optimize<DiffViewer>: change theme will not redo diff

This commit is contained in:
leo 2021-08-04 17:09:42 +08:00
parent 164501db01
commit 7ab2c1017a
2 changed files with 64 additions and 103 deletions

View file

@ -9,11 +9,36 @@ namespace SourceGit.Views.Controls {
/// 支持部分高亮的文本组件 /// 支持部分高亮的文本组件
/// </summary> /// </summary>
public class HighlightableTextBlock : TextBlock { public class HighlightableTextBlock : TextBlock {
private static readonly Brush BG_EMPTY = new SolidColorBrush(Color.FromArgb(60, 0, 0, 0));
private static readonly Brush BG_ADDED = new SolidColorBrush(Color.FromArgb(60, 0, 255, 0));
private static readonly Brush BG_DELETED = new SolidColorBrush(Color.FromArgb(60, 255, 0, 0));
private static readonly Brush HL_ADDED = new SolidColorBrush(Color.FromArgb(128, 0, 255, 0));
private static readonly Brush HL_DELETED = new SolidColorBrush(Color.FromArgb(128, 255, 0, 0));
public class Data { public class Data {
public Models.TextChanges.LineMode Mode { get; set; } = Models.TextChanges.LineMode.None;
public string Text { get; set; } = ""; public string Text { get; set; } = "";
public List<Models.TextChanges.HighlightRange> Highlights { get; set; } = new List<Models.TextChanges.HighlightRange>(); public List<Models.TextChanges.HighlightRange> Highlights { get; set; } = new List<Models.TextChanges.HighlightRange>();
public Brush HighlightBrush { get; set; } = Brushes.Transparent;
public bool IsContent {
get {
return Mode == Models.TextChanges.LineMode.Added
|| Mode == Models.TextChanges.LineMode.Deleted
|| Mode == Models.TextChanges.LineMode.Normal;
}
}
public bool IsDifference {
get {
return Mode == Models.TextChanges.LineMode.Added
|| Mode == Models.TextChanges.LineMode.Deleted
|| Mode == Models.TextChanges.LineMode.None;
}
}
public string FG {
get { return Mode == Models.TextChanges.LineMode.Indicator ? "Brush.FG2" : "Brush.FG1"; }
}
} }
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register( public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
@ -33,8 +58,33 @@ namespace SourceGit.Views.Controls {
txt.Inlines.Clear(); txt.Inlines.Clear();
txt.Text = null; txt.Text = null;
txt.Background = Brushes.Transparent;
txt.FontStyle = FontStyles.Normal;
if (txt.Content == null) return; if (txt.Content == null) return;
Brush highlightBrush = Brushes.Transparent;
switch (txt.Content.Mode) {
case Models.TextChanges.LineMode.None:
txt.Background = BG_EMPTY;
break;
case Models.TextChanges.LineMode.Indicator:
txt.FontStyle = FontStyles.Italic;
break;
case Models.TextChanges.LineMode.Added:
txt.Background = BG_ADDED;
highlightBrush = HL_ADDED;
break;
case Models.TextChanges.LineMode.Deleted:
txt.Background = BG_DELETED;
highlightBrush = HL_DELETED;
break;
default:
break;
}
txt.SetResourceReference(ForegroundProperty, txt.Content.FG);
if (txt.Content.Highlights == null || txt.Content.Highlights.Count == 0) { if (txt.Content.Highlights == null || txt.Content.Highlights.Count == 0) {
txt.Text = txt.Content.Text; txt.Text = txt.Content.Text;
return; return;
@ -47,7 +97,7 @@ namespace SourceGit.Views.Controls {
} }
txt.Inlines.Add(new TextBlock() { txt.Inlines.Add(new TextBlock() {
Background = txt.Content.HighlightBrush, Background = highlightBrush,
LineHeight = txt.LineHeight, LineHeight = txt.LineHeight,
Text = txt.Content.Text.Substring(highlight.Start, highlight.Count), Text = txt.Content.Text.Substring(highlight.Start, highlight.Count),
}); });

View file

@ -15,13 +15,6 @@ namespace SourceGit.Views.Widgets {
/// 变更对比视图 /// 变更对比视图
/// </summary> /// </summary>
public partial class DiffViewer : UserControl { public partial class DiffViewer : UserControl {
private static readonly Brush BG_EMPTY = new SolidColorBrush(Color.FromArgb(40, 0, 0, 0));
private static readonly Brush BG_ADDED = new SolidColorBrush(Color.FromArgb(60, 0, 255, 0));
private static readonly Brush BG_DELETED = new SolidColorBrush(Color.FromArgb(60, 255, 0, 0));
private static readonly Brush BG_NORMAL = Brushes.Transparent;
private static readonly Brush HL_ADDED = new SolidColorBrush(Color.FromArgb(128, 0, 255, 0));
private static readonly Brush HL_DELETED = new SolidColorBrush(Color.FromArgb(128, 255, 0, 0));
private static readonly Brush HL_NORMAL = Brushes.Transparent;
public class Option { public class Option {
public string[] RevisionRange = new string[] { }; public string[] RevisionRange = new string[] { };
@ -32,29 +25,9 @@ namespace SourceGit.Views.Widgets {
} }
public class Block { public class Block {
public Models.TextChanges.LineMode Mode { get; set; } public string OldLine { get; set; } = "";
public Brush BG { get; set; } public string NewLine { get; set; } = "";
public Brush FG { get; set; }
public FontStyle Style { get; set; }
public string OldLine { get; set; }
public string NewLine { get; set; }
public Controls.HighlightableTextBlock.Data Data { get; set; } = new Controls.HighlightableTextBlock.Data(); public Controls.HighlightableTextBlock.Data Data { get; set; } = new Controls.HighlightableTextBlock.Data();
public bool IsContent {
get {
return Mode == Models.TextChanges.LineMode.Added
|| Mode == Models.TextChanges.LineMode.Deleted
|| Mode == Models.TextChanges.LineMode.Normal;
}
}
public bool IsDifference {
get {
return Mode == Models.TextChanges.LineMode.Added
|| Mode == Models.TextChanges.LineMode.Deleted
|| Mode == Models.TextChanges.LineMode.None;
}
}
} }
private ulong seq = 0; private ulong seq = 0;
@ -65,7 +38,6 @@ namespace SourceGit.Views.Widgets {
private List<Rectangle> splitters = new List<Rectangle>(); private List<Rectangle> splitters = new List<Rectangle>();
public DiffViewer() { public DiffViewer() {
Models.Theme.AddListener(this, Reload);
InitializeComponent(); InitializeComponent();
Reset(); Reset();
} }
@ -211,22 +183,16 @@ namespace SourceGit.Views.Widgets {
} }
private void MakeCombinedViewer(ulong dummy) { private void MakeCombinedViewer(ulong dummy) {
var fgCommon = FindResource("Brush.FG1") as Brush;
var fgIndicator = FindResource("Brush.FG2") as Brush;
var lastOldLine = ""; var lastOldLine = "";
var lastNewLine = ""; var lastNewLine = "";
var blocks = new List<Block>(); var blocks = new List<Block>();
foreach (var line in cachedTextChanges) { foreach (var line in cachedTextChanges) {
var block = new Block(); var block = new Block();
block.Mode = line.Mode;
block.BG = GetLineBackground(line);
block.FG = block.IsContent ? fgCommon : fgIndicator;
block.Style = block.IsContent ? FontStyles.Normal : FontStyles.Italic;
block.OldLine = line.OldLine; block.OldLine = line.OldLine;
block.NewLine = line.NewLine; block.NewLine = line.NewLine;
block.Data.Mode = line.Mode;
block.Data.Text = line.Content; block.Data.Text = line.Content;
block.Data.HighlightBrush = GetLineHighlight(line);
block.Data.Highlights.AddRange(line.Highlights); block.Data.Highlights.AddRange(line.Highlights);
if (line.OldLine.Length > 0) lastOldLine = line.OldLine; if (line.OldLine.Length > 0) lastOldLine = line.OldLine;
@ -273,8 +239,6 @@ namespace SourceGit.Views.Widgets {
} }
private void MakeSideBySideViewer(ulong dummy) { private void MakeSideBySideViewer(ulong dummy) {
var fgCommon = FindResource("Brush.FG1") as Brush;
var fgIndicator = FindResource("Brush.FG2") as Brush;
var lastOldLine = ""; var lastOldLine = "";
var lastNewLine = ""; var lastNewLine = "";
var oldSideBlocks = new List<Block>(); var oldSideBlocks = new List<Block>();
@ -282,14 +246,10 @@ namespace SourceGit.Views.Widgets {
foreach (var line in cachedTextChanges) { foreach (var line in cachedTextChanges) {
var block = new Block(); var block = new Block();
block.Mode = line.Mode;
block.BG = GetLineBackground(line);
block.FG = block.IsContent ? fgCommon : fgIndicator;
block.Style = block.IsContent ? FontStyles.Normal : FontStyles.Italic;
block.OldLine = line.OldLine; block.OldLine = line.OldLine;
block.NewLine = line.NewLine; block.NewLine = line.NewLine;
block.Data.Mode = line.Mode;
block.Data.Text = line.Content; block.Data.Text = line.Content;
block.Data.HighlightBrush = GetLineHighlight(line);
block.Data.Highlights.AddRange(line.Highlights); block.Data.Highlights.AddRange(line.Highlights);
if (line.OldLine.Length > 0) lastOldLine = line.OldLine; if (line.OldLine.Length > 0) lastOldLine = line.OldLine;
@ -364,55 +324,13 @@ namespace SourceGit.Views.Widgets {
}); });
} }
private Brush GetLineBackground(Models.TextChanges.Line line) {
switch (line.Mode) {
case Models.TextChanges.LineMode.Added:
return BG_ADDED;
case Models.TextChanges.LineMode.Deleted:
return BG_DELETED;
default:
return BG_NORMAL;
}
}
private Brush GetLineHighlight(Models.TextChanges.Line line) {
switch (line.Mode) {
case Models.TextChanges.LineMode.Added:
return HL_ADDED;
case Models.TextChanges.LineMode.Deleted:
return HL_DELETED;
default:
return HL_NORMAL;
}
}
private void FillEmptyLines(List<Block> old, List<Block> cur) { private void FillEmptyLines(List<Block> old, List<Block> cur) {
if (old.Count < cur.Count) { if (old.Count < cur.Count) {
int diff = cur.Count - old.Count; int diff = cur.Count - old.Count;
for (int i = 0; i < diff; i++) old.Add(new Block());
for (int i = 0; i < diff; i++) {
var empty = new Block();
empty.Mode = Models.TextChanges.LineMode.None;
empty.BG = BG_EMPTY;
empty.FG = Brushes.Transparent;
empty.Style = FontStyles.Normal;
empty.OldLine = "";
empty.NewLine = "";
old.Add(empty);
}
} else if (old.Count > cur.Count) { } else if (old.Count > cur.Count) {
int diff = old.Count - cur.Count; int diff = old.Count - cur.Count;
for (int i = 0; i < diff; i++) cur.Add(new Block());
for (int i = 0; i < diff; i++) {
var empty = new Block();
empty.Mode = Models.TextChanges.LineMode.None;
empty.BG = BG_EMPTY;
empty.FG = Brushes.Transparent;
empty.Style = FontStyles.Normal;
empty.OldLine = "";
empty.NewLine = "";
cur.Add(empty);
}
} }
} }
@ -445,7 +363,7 @@ namespace SourceGit.Views.Widgets {
foreach (var item in items) { foreach (var item in items) {
var block = item as Block; var block = item as Block;
if (block == null) continue; if (block == null) continue;
if (!block.IsContent) continue; if (!block.Data.IsContent) continue;
builder.Append(block.Data.Text); builder.Append(block.Data.Text);
builder.AppendLine(); builder.AppendLine();
@ -464,17 +382,11 @@ namespace SourceGit.Views.Widgets {
var line = new FrameworkElementFactory(typeof(Controls.HighlightableTextBlock)); var line = new FrameworkElementFactory(typeof(Controls.HighlightableTextBlock));
line.SetBinding(Controls.HighlightableTextBlock.ContentProperty, new Binding("Data")); line.SetBinding(Controls.HighlightableTextBlock.ContentProperty, new Binding("Data"));
line.SetBinding(TextBlock.BackgroundProperty, new Binding("BG"));
line.SetBinding(TextBlock.ForegroundProperty, new Binding("FG"));
line.SetBinding(TextBlock.FontStyleProperty, new Binding("Style"));
line.SetValue(TextBlock.FontFamilyProperty, new FontFamily("Consolas,Microsoft YaHei UI")); line.SetValue(TextBlock.FontFamilyProperty, new FontFamily("Consolas,Microsoft YaHei UI"));
line.SetValue(TextBlock.FontSizeProperty, 13.0); line.SetValue(TextBlock.FontSizeProperty, 13.0);
line.SetValue(TextBlock.MarginProperty, new Thickness(0)); line.SetValue(TextBlock.MarginProperty, new Thickness(0));
line.SetValue(TextBlock.PaddingProperty, new Thickness(4, 0, 0, 0)); line.SetValue(TextBlock.PaddingProperty, new Thickness(4, 0, 0, 0));
line.SetValue(TextBlock.LineHeightProperty, 16.0); line.SetValue(TextBlock.LineHeightProperty, 16.0);
line.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
line.SetValue(TextOptions.TextRenderingModeProperty, TextRenderingMode.ClearType);
line.SetValue(RenderOptions.ClearTypeHintProperty, ClearTypeHint.Enabled);
var colContent = new DataGridTemplateColumn(); var colContent = new DataGridTemplateColumn();
colContent.CellTemplate = new DataTemplate(); colContent.CellTemplate = new DataTemplate();
@ -576,7 +488,7 @@ namespace SourceGit.Views.Widgets {
foreach (var item in items) { foreach (var item in items) {
var block = item as Block; var block = item as Block;
if (block == null) continue; if (block == null) continue;
if (!block.IsContent) continue; if (!block.Data.IsContent) continue;
builder.Append(block.Data.Text); builder.Append(block.Data.Text);
builder.AppendLine(); builder.AppendLine();
@ -619,7 +531,6 @@ namespace SourceGit.Views.Widgets {
} }
} }
private void OnTextDiffSyncSelected(object sender, SelectionChangedEventArgs e) { private void OnTextDiffSyncSelected(object sender, SelectionChangedEventArgs e) {
DataGrid dG = sender as DataGrid; DataGrid dG = sender as DataGrid;
int Index = dG.SelectedIndex; int Index = dG.SelectedIndex;
@ -649,8 +560,8 @@ namespace SourceGit.Views.Widgets {
var first = grid.Items[firstVisible] as Block; var first = grid.Items[firstVisible] as Block;
for (int i = firstVisible - 1; i >= 0; i--) { for (int i = firstVisible - 1; i >= 0; i--) {
var next = grid.Items[i] as Block; var next = grid.Items[i] as Block;
if (next.IsDifference) { if (next.Data.IsDifference) {
if (firstModeEnded || next.Mode != first.Mode) { if (firstModeEnded || next.Data.Mode != first.Data.Mode) {
scroller.ScrollToVerticalOffset(i); scroller.ScrollToVerticalOffset(i);
grid.SelectedIndex = i; grid.SelectedIndex = i;
break; break;
@ -673,8 +584,8 @@ namespace SourceGit.Views.Widgets {
var first = grid.Items[firstVisible] as Block; var first = grid.Items[firstVisible] as Block;
for (int i = firstVisible + 1; i < grid.Items.Count; i++) { for (int i = firstVisible + 1; i < grid.Items.Count; i++) {
var next = grid.Items[i] as Block; var next = grid.Items[i] as Block;
if (next.IsDifference) { if (next.Data.IsDifference) {
if (firstModeEnded || next.Mode != first.Mode) { if (firstModeEnded || next.Data.Mode != first.Data.Mode) {
scroller.ScrollToVerticalOffset(i); scroller.ScrollToVerticalOffset(i);
grid.SelectedIndex = i; grid.SelectedIndex = i;
break; break;