126 lines
4.3 KiB
C#
126 lines
4.3 KiB
C#
|
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 == '}');
|
||
|
}
|
||
|
}
|