CodeMerger/ChangesHighlightingColorize...

126 lines
4.3 KiB
C#
Raw Normal View History

2025-02-23 07:10:00 -03:00
using ICSharpCode.AvalonEdit.Rendering;
using System.Windows.Media;
using System;
using System.Windows;
using ICSharpCode.AvalonEdit.Document;
namespace CodeMerger;
public class ChangesHighlightingColorizer : IBackgroundRenderer
{
private static readonly Brush AddedLineBrush = new SolidColorBrush(Color.FromArgb(40, 50, 205, 50)); // Verde más visible
private static readonly Brush ModifiedLineBrush = new SolidColorBrush(Color.FromArgb(40, 255, 215, 0)); // Amarillo más visible
private TextView _textView;
public KnownLayer Layer => KnownLayer.Background;
public void SetTextView(TextView textView)
{
if (_textView != null)
_textView.VisualLinesChanged -= TextView_VisualLinesChanged;
_textView = textView;
_textView.VisualLinesChanged += TextView_VisualLinesChanged;
}
private void TextView_VisualLinesChanged(object sender, EventArgs e)
{
_textView?.InvalidateLayer(Layer);
}
public void Draw(TextView textView, DrawingContext drawingContext)
{
if (textView?.Document == null) return;
bool isInAddedSection = false;
bool isInModifiedSection = false;
int sectionStartDepth = 0;
int currentDepth = 0;
int currentLine = 1;
int totalLines = textView.Document.LineCount;
while (currentLine <= totalLines)
{
var documentLine = textView.Document.GetLineByNumber(currentLine);
var lineText = textView.Document.GetText(documentLine);
var trimmedText = lineText.Trim();
// Actualizar el nivel de anidación
currentDepth += CountOpenBraces(trimmedText) - CountCloseBraces(trimmedText);
// Detectar inicio de secciones
if (trimmedText.Contains("// Added:") || trimmedText.Contains("// New:"))
{
isInAddedSection = true;
isInModifiedSection = false;
sectionStartDepth = currentDepth;
}
else if (trimmedText.Contains("// Modified:") || trimmedText.Contains("// Changed:"))
{
isInAddedSection = false;
isInModifiedSection = true;
sectionStartDepth = currentDepth;
}
// Obtener la línea visual
var visualLine = textView.GetOrConstructVisualLine(documentLine);
if (visualLine != null)
{
// Determinar el color basado en el estado actual
Brush brush = null;
if (isInAddedSection)
{
brush = AddedLineBrush;
}
else if (isInModifiedSection)
{
brush = ModifiedLineBrush;
}
// Si tenemos un color asignado y no es una línea de separador
if (brush != null && !trimmedText.Contains("// ----------------------------------------"))
{
var rect = BackgroundGeometryBuilder.GetRectsFromVisualSegment(textView, visualLine, 0, 1000)
.First();
// Dibujar el fondo de la línea completa
drawingContext.DrawRectangle(
brush,
null,
new Rect(0, rect.Top, textView.ActualWidth, rect.Height)
);
}
}
// Detectar fin de secciones
// Si volvemos al mismo nivel de anidación donde empezó la sección y encontramos una llave de cierre
if ((isInAddedSection || isInModifiedSection) &&
currentDepth <= sectionStartDepth &&
trimmedText.Contains("}"))
{
isInAddedSection = false;
isInModifiedSection = false;
}
// También terminar sección si encontramos un nuevo marcador
if (trimmedText.Contains("// ----------------------------------------"))
{
isInAddedSection = false;
isInModifiedSection = false;
}
currentLine++;
}
}
private int CountOpenBraces(string text)
{
return text.Count(c => c == '{');
}
private int CountCloseBraces(string text)
{
return text.Count(c => c == '}');
}
}