Initial commit to new repository

This commit is contained in:
2026-04-03 18:22:19 +09:00
commit 4458bb0f52
7672 changed files with 452440 additions and 0 deletions

View File

@@ -0,0 +1,210 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using AxCopilot.Services;
namespace AxCopilot.Views;
/// <summary>
/// 에이전트 파일 수정 시 변경 전/후 diff를 보여주는 패널.
/// DiffService의 결과를 색상 하이라이트로 렌더링하고
/// Accept/Reject 버튼으로 변경 승인/취소를 지원합니다.
/// </summary>
public class DiffViewerPanel : Border
{
private readonly string _filePath;
private readonly string _oldContent;
private readonly string _newContent;
private readonly List<DiffService.DiffLine> _diffLines;
/// <summary>사용자가 Accept를 눌렀을 때 발생합니다.</summary>
public event EventHandler? Accepted;
/// <summary>사용자가 Reject를 눌렀을 때 발생합니다.</summary>
public event EventHandler? Rejected;
public DiffViewerPanel(string filePath, string oldContent, string newContent)
{
_filePath = filePath;
_oldContent = oldContent;
_newContent = newContent;
_diffLines = DiffService.ComputeDiff(oldContent, newContent);
CornerRadius = new CornerRadius(10);
Background = new SolidColorBrush(Color.FromRgb(0xFA, 0xFA, 0xFF));
BorderBrush = new SolidColorBrush(Color.FromRgb(0xE0, 0xE0, 0xEC));
BorderThickness = new Thickness(1);
Padding = new Thickness(0);
Margin = new Thickness(0, 8, 0, 8);
Child = BuildContent();
}
private UIElement BuildContent()
{
var mainStack = new StackPanel();
// 헤더
var header = new Border
{
Background = new SolidColorBrush(Color.FromRgb(0xF0, 0xF2, 0xFF)),
CornerRadius = new CornerRadius(10, 10, 0, 0),
Padding = new Thickness(14, 10, 14, 10),
};
var headerGrid = new Grid();
headerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
headerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
var summary = DiffService.GetSummary(_diffLines);
var titlePanel = new StackPanel { Orientation = Orientation.Horizontal };
titlePanel.Children.Add(new TextBlock
{
Text = "\uE89A",
FontFamily = new FontFamily("Segoe MDL2 Assets"),
FontSize = 13, Foreground = new SolidColorBrush(Color.FromRgb(0x4B, 0x5E, 0xFC)),
VerticalAlignment = VerticalAlignment.Center,
Margin = new Thickness(0, 0, 8, 0),
});
titlePanel.Children.Add(new TextBlock
{
Text = System.IO.Path.GetFileName(_filePath),
FontSize = 13, FontWeight = FontWeights.SemiBold,
Foreground = new SolidColorBrush(Color.FromRgb(0x1A, 0x1B, 0x2E)),
VerticalAlignment = VerticalAlignment.Center,
});
titlePanel.Children.Add(new TextBlock
{
Text = $" · {summary}",
FontSize = 11,
Foreground = new SolidColorBrush(Color.FromRgb(0x88, 0x88, 0xAA)),
VerticalAlignment = VerticalAlignment.Center,
});
Grid.SetColumn(titlePanel, 0);
headerGrid.Children.Add(titlePanel);
// Accept / Reject 버튼
var btnPanel = new StackPanel { Orientation = Orientation.Horizontal };
var acceptBtn = CreateButton("적용", Color.FromRgb(0x10, 0x7C, 0x10), Colors.White);
acceptBtn.Click += (_, _) => Accepted?.Invoke(this, EventArgs.Empty);
btnPanel.Children.Add(acceptBtn);
var rejectBtn = CreateButton("취소", Colors.Transparent, Color.FromRgb(0xC5, 0x0F, 0x1F));
rejectBtn.Click += (_, _) => Rejected?.Invoke(this, EventArgs.Empty);
btnPanel.Children.Add(rejectBtn);
Grid.SetColumn(btnPanel, 1);
headerGrid.Children.Add(btnPanel);
header.Child = headerGrid;
mainStack.Children.Add(header);
// Diff 내용
var scrollViewer = new ScrollViewer
{
MaxHeight = 300,
VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
};
var diffStack = new StackPanel { Margin = new Thickness(0) };
foreach (var line in _diffLines)
{
var (bg, fg, prefix) = line.Type switch
{
DiffService.DiffType.Added => (
Color.FromRgb(0xE6, 0xFF, 0xED),
Color.FromRgb(0x16, 0x6C, 0x34),
"+"),
DiffService.DiffType.Removed => (
Color.FromRgb(0xFF, 0xEB, 0xE9),
Color.FromRgb(0xCF, 0x22, 0x2E),
"-"),
_ => (
Color.FromRgb(0xFF, 0xFF, 0xFF),
Color.FromRgb(0x66, 0x66, 0x88),
" ")
};
var lineNo = line.OldLineNo?.ToString() ?? "";
var newLineNo = line.NewLineNo?.ToString() ?? "";
var linePanel = new Border
{
Background = new SolidColorBrush(bg),
Padding = new Thickness(8, 1, 8, 1),
};
var lineGrid = new Grid();
lineGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(36) }); // old line
lineGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(36) }); // new line
lineGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(16) }); // prefix
lineGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); // content
var oldLineText = new TextBlock
{
Text = lineNo, FontSize = 10, FontFamily = new FontFamily("Consolas"),
Foreground = new SolidColorBrush(Color.FromRgb(0xAA, 0xAA, 0xCC)),
HorizontalAlignment = HorizontalAlignment.Right, Margin = new Thickness(0, 0, 4, 0),
};
Grid.SetColumn(oldLineText, 0);
lineGrid.Children.Add(oldLineText);
var newLineText = new TextBlock
{
Text = newLineNo, FontSize = 10, FontFamily = new FontFamily("Consolas"),
Foreground = new SolidColorBrush(Color.FromRgb(0xAA, 0xAA, 0xCC)),
HorizontalAlignment = HorizontalAlignment.Right, Margin = new Thickness(0, 0, 4, 0),
};
Grid.SetColumn(newLineText, 1);
lineGrid.Children.Add(newLineText);
var prefixText = new TextBlock
{
Text = prefix, FontSize = 11, FontFamily = new FontFamily("Consolas"),
Foreground = new SolidColorBrush(fg), FontWeight = FontWeights.Bold,
};
Grid.SetColumn(prefixText, 2);
lineGrid.Children.Add(prefixText);
var contentText = new TextBlock
{
Text = line.Content, FontSize = 11, FontFamily = new FontFamily("Consolas"),
Foreground = new SolidColorBrush(fg),
TextWrapping = TextWrapping.NoWrap,
};
Grid.SetColumn(contentText, 3);
lineGrid.Children.Add(contentText);
linePanel.Child = lineGrid;
diffStack.Children.Add(linePanel);
}
scrollViewer.Content = diffStack;
mainStack.Children.Add(scrollViewer);
return mainStack;
}
private static Button CreateButton(string text, Color bg, Color fg)
{
var btn = new Button { Cursor = System.Windows.Input.Cursors.Hand, Margin = new Thickness(4, 0, 0, 0) };
var template = new ControlTemplate(typeof(Button));
var bdFactory = new FrameworkElementFactory(typeof(Border));
bdFactory.SetValue(Border.BackgroundProperty, new SolidColorBrush(bg));
bdFactory.SetValue(Border.CornerRadiusProperty, new CornerRadius(6));
bdFactory.SetValue(Border.PaddingProperty, new Thickness(12, 5, 12, 5));
if (bg == Colors.Transparent)
{
bdFactory.SetValue(Border.BorderBrushProperty, new SolidColorBrush(fg));
bdFactory.SetValue(Border.BorderThicknessProperty, new Thickness(1));
}
var cpFactory = new FrameworkElementFactory(typeof(ContentPresenter));
cpFactory.SetValue(ContentPresenter.HorizontalAlignmentProperty, HorizontalAlignment.Center);
bdFactory.AppendChild(cpFactory);
template.VisualTree = bdFactory;
btn.Template = template;
btn.Content = new TextBlock { Text = text, FontSize = 11, Foreground = new SolidColorBrush(fg), FontWeight = FontWeights.SemiBold };
return btn;
}
}