Go to NEXT/PREV differences in DiffViewer

This commit is contained in:
leo 2020-07-20 11:13:47 +08:00
parent e9c9a98384
commit 2138ee9c33
2 changed files with 175 additions and 70 deletions

View file

@ -13,18 +13,36 @@
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Border Grid.Row="0" BorderBrush="{StaticResource Brush.Border2}" BorderThickness="0,0,0,1"> <Border Grid.Row="0" BorderBrush="{StaticResource Brush.Border2}" BorderThickness="0,0,0,1">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,4"> <Grid Margin="8,4">
<StackPanel x:Name="orgFileNamePanel" Orientation="Horizontal"> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" x:Name="orgFileNamePanel" Orientation="Horizontal">
<Path Width="10" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.File}"/> <Path Width="10" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.File}"/>
<TextBlock x:Name="orgFileName" Margin="4,0,0,0" VerticalAlignment="Center" Foreground="{StaticResource Brush.FG}"/> <TextBlock x:Name="orgFileName" Margin="4,0,0,0" VerticalAlignment="Center" Foreground="{StaticResource Brush.FG}"/>
<TextBlock Margin="8,0" VerticalAlignment="Center" Text="→" Foreground="{StaticResource Brush.FG}"/> <TextBlock Margin="8,0" VerticalAlignment="Center" Text="→" Foreground="{StaticResource Brush.FG}"/>
</StackPanel> </StackPanel>
<Path Width="10" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.File}"/>
<TextBlock x:Name="fileName" Margin="4,0" VerticalAlignment="Center" Foreground="{StaticResource Brush.FG}"/>
</StackPanel>
</Border>
<Path x:Name="loading" Grid.Row="0" HorizontalAlignment="Left" Width="10" Height="10" Margin="8,0" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Loading}" Visibility="Collapsed"/> <StackPanel Grid.Column="1" Orientation="Horizontal">
<Path Width="10" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.File}"/>
<TextBlock x:Name="fileName" Margin="4,0" VerticalAlignment="Center" Foreground="{StaticResource Brush.FG}"/>
<Path x:Name="loading" Width="10" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Loading}"/>
</StackPanel>
<StackPanel Grid.Column="2" x:Name="diffNavigation" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Width="26" Click="Go2Next" ToolTip="Next Difference" Background="Transparent">
<Path Width="10" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.MoveDown}"/>
</Button>
<Button Click="Go2Prev" ToolTip="Previous Difference" Background="Transparent">
<Path Width="10" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.MoveUp}"/>
</Button>
</StackPanel>
</Grid>
</Border>
<Grid x:Name="textChange" Grid.Row="1" ClipToBounds="True"> <Grid x:Name="textChange" Grid.Row="1" ClipToBounds="True">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@ -41,40 +59,41 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBox <TextBox
x:Name="leftLineNumber" x:Name="leftLineNumber"
Grid.Column="0" Grid.Column="0"
AcceptsReturn="True" AcceptsReturn="True"
AcceptsTab="True" AcceptsTab="True"
BorderThickness="0" BorderThickness="0"
Background="Transparent" Background="Transparent"
IsReadOnly="True" IsReadOnly="True"
Margin="4,0,4,0" Padding="2,0"
FontSize="13" Margin="0"
HorizontalContentAlignment="Right" FontSize="13"
VerticalAlignment="Stretch"/> HorizontalContentAlignment="Right"
VerticalAlignment="Stretch"/>
<Rectangle Grid.Column="1" Width="1" Fill="{StaticResource Brush.Border2}"/> <Rectangle Grid.Column="1" Width="1" Fill="{StaticResource Brush.Border2}"/>
<RichTextBox <RichTextBox
x:Name="leftText" x:Name="leftText"
Grid.Column="2" Grid.Column="2"
AcceptsReturn="True" AcceptsReturn="True"
AcceptsTab="True" AcceptsTab="True"
IsReadOnly="True" IsReadOnly="True"
BorderThickness="0" BorderThickness="0"
Background="Transparent" Background="Transparent"
Foreground="{StaticResource Brush.FG}" Foreground="{StaticResource Brush.FG}"
Height="Auto" Height="Auto"
FontSize="13" FontSize="13"
HorizontalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
RenderOptions.ClearTypeHint="Enabled" RenderOptions.ClearTypeHint="Enabled"
ScrollViewer.ScrollChanged="OnViewerScroll" ScrollViewer.ScrollChanged="OnViewerScroll"
PreviewMouseWheel="OnViewerMouseWheel" PreviewMouseWheel="OnViewerMouseWheel"
SizeChanged="LeftSizeChanged" SizeChanged="LeftSizeChanged"
SelectionChanged="OnViewerSelectionChanged" SelectionChanged="OnViewerSelectionChanged"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"> VerticalAlignment="Stretch">
<RichTextBox.Document> <RichTextBox.Document>
<FlowDocument PageWidth="0"/> <FlowDocument PageWidth="0"/>
</RichTextBox.Document> </RichTextBox.Document>
@ -96,40 +115,41 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBox <TextBox
x:Name="rightLineNumber" x:Name="rightLineNumber"
Grid.Column="0" Grid.Column="0"
AcceptsReturn="True" AcceptsReturn="True"
AcceptsTab="True" AcceptsTab="True"
IsReadOnly="True" IsReadOnly="True"
BorderThickness="0" BorderThickness="0"
Background="Transparent" Background="Transparent"
Margin="4,0,4,0" Padding="2,0"
FontSize="13" Margin="0"
HorizontalContentAlignment="Right" FontSize="13"
VerticalAlignment="Stretch"/> HorizontalContentAlignment="Right"
VerticalAlignment="Stretch"/>
<Rectangle Grid.Column="1" Width="1" Fill="{StaticResource Brush.Border2}"/> <Rectangle Grid.Column="1" Width="1" Fill="{StaticResource Brush.Border2}"/>
<RichTextBox <RichTextBox
x:Name="rightText" x:Name="rightText"
Grid.Column="2" Grid.Column="2"
AcceptsReturn="True" AcceptsReturn="True"
AcceptsTab="True" AcceptsTab="True"
IsReadOnly="True" IsReadOnly="True"
BorderThickness="0" BorderThickness="0"
Background="Transparent" Background="Transparent"
Foreground="{StaticResource Brush.FG}" Foreground="{StaticResource Brush.FG}"
Height="Auto" Height="Auto"
FontSize="13" FontSize="13"
HorizontalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
RenderOptions.ClearTypeHint="Enabled" RenderOptions.ClearTypeHint="Enabled"
ScrollViewer.ScrollChanged="OnViewerScroll" ScrollViewer.ScrollChanged="OnViewerScroll"
PreviewMouseWheel="OnViewerMouseWheel" PreviewMouseWheel="OnViewerMouseWheel"
SizeChanged="RightSizeChanged" SizeChanged="RightSizeChanged"
SelectionChanged="OnViewerSelectionChanged" SelectionChanged="OnViewerSelectionChanged"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"> VerticalAlignment="Stretch">
<RichTextBox.Document> <RichTextBox.Document>
<FlowDocument PageWidth="0"/> <FlowDocument PageWidth="0"/>
</RichTextBox.Document> </RichTextBox.Document>

View file

@ -96,18 +96,20 @@ namespace SourceGit.UI {
Dispatcher.Invoke(() => { Dispatcher.Invoke(() => {
loading.Visibility = Visibility.Collapsed; loading.Visibility = Visibility.Collapsed;
sizeChange.Visibility = Visibility.Visible; sizeChange.Visibility = Visibility.Visible;
diffNavigation.Visibility = Visibility.Collapsed;
txtNewSize.Content = $"{bc.Size} Bytes"; txtNewSize.Content = $"{bc.Size} Bytes";
txtOldSize.Content = $"{bc.PreSize} Bytes"; txtOldSize.Content = $"{bc.PreSize} Bytes";
}); });
} }
/// <summary> /// <summary>
/// Show no changes or only eol changes. /// Show no changes or only EOL changes.
/// </summary> /// </summary>
private void SetSame() { private void SetSame() {
Dispatcher.Invoke(() => { Dispatcher.Invoke(() => {
loading.Visibility = Visibility.Collapsed; loading.Visibility = Visibility.Collapsed;
noChange.Visibility = Visibility.Visible; noChange.Visibility = Visibility.Visible;
diffNavigation.Visibility = Visibility.Collapsed;
}); });
} }
@ -119,6 +121,7 @@ namespace SourceGit.UI {
Dispatcher.Invoke(() => { Dispatcher.Invoke(() => {
loading.Visibility = Visibility.Collapsed; loading.Visibility = Visibility.Collapsed;
textChange.Visibility = Visibility.Visible; textChange.Visibility = Visibility.Visible;
diffNavigation.Visibility = Visibility.Visible;
minWidth = Math.Max(leftText.ActualWidth, rightText.ActualWidth) - 16; minWidth = Math.Max(leftText.ActualWidth, rightText.ActualWidth) - 16;
@ -149,6 +152,7 @@ namespace SourceGit.UI {
p.Background = Brushes.Transparent; p.Background = Brushes.Transparent;
p.Foreground = FindResource("Brush.FG") as SolidColorBrush; p.Foreground = FindResource("Brush.FG") as SolidColorBrush;
p.FontStyle = FontStyles.Normal; p.FontStyle = FontStyles.Normal;
p.DataContext = b;
switch (b.Mode) { switch (b.Mode) {
case Git.Diff.LineMode.Normal: case Git.Diff.LineMode.Normal:
@ -205,6 +209,7 @@ namespace SourceGit.UI {
cp.Background = p.Background; cp.Background = p.Background;
cp.Foreground = p.Foreground; cp.Foreground = p.Foreground;
cp.FontStyle = p.FontStyle; cp.FontStyle = p.FontStyle;
cp.DataContext = b;
rightText.Document.Blocks.Add(cp); rightText.Document.Blocks.Add(cp);
for (int i = 0; i < b.Count; i++) { for (int i = 0; i < b.Count; i++) {
@ -237,8 +242,8 @@ namespace SourceGit.UI {
rightText.ScrollToVerticalOffset(e.VerticalOffset); rightText.ScrollToVerticalOffset(e.VerticalOffset);
} }
leftLineNumber.Margin = new Thickness(4, -e.VerticalOffset, 4, 0); leftLineNumber.Margin = new Thickness(0, -e.VerticalOffset, 0, 0);
rightLineNumber.Margin = new Thickness(4, -e.VerticalOffset, 4, 0); rightLineNumber.Margin = new Thickness(0, -e.VerticalOffset, 0, 0);
} else { } else {
if (leftText.HorizontalOffset != e.HorizontalOffset) { if (leftText.HorizontalOffset != e.HorizontalOffset) {
leftText.ScrollToHorizontalOffset(e.HorizontalOffset); leftText.ScrollToHorizontalOffset(e.HorizontalOffset);
@ -315,6 +320,86 @@ namespace SourceGit.UI {
} }
} }
} }
/// <summary>
/// Go to next difference.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Go2Next(object sender, RoutedEventArgs e) {
Paragraph next = null;
double minTop = 0;
foreach (var p in leftText.Document.Blocks) {
var rect = p.ContentStart.GetCharacterRect(LogicalDirection.Forward);
var block = p.DataContext as Git.Diff.Block;
if (rect.Top > 0 && block.IsLeftDelete) {
next = p as Paragraph;
minTop = rect.Top;
break;
}
}
foreach (var p in rightText.Document.Blocks) {
var rect = p.ContentStart.GetCharacterRect(LogicalDirection.Forward);
var block = p.DataContext as Git.Diff.Block;
if (rect.Top > 0 && block.IsRightAdded) {
if (next == null || minTop > rect.Top) {
next = p as Paragraph;
minTop = rect.Top;
}
break;
}
}
if (next != null) {
rightText.ScrollToVerticalOffset(rightText.VerticalOffset + minTop);
}
}
/// <summary>
/// Go to previous difference.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Go2Prev(object sender, RoutedEventArgs e) {
Paragraph next = null;
double maxTop = 0;
var p = leftText.Document.Blocks.LastBlock as Paragraph;
do {
var rect = p.ContentStart.GetCharacterRect(LogicalDirection.Forward);
var block = p.DataContext as Git.Diff.Block;
if (rect.Top < 0 && block.IsLeftDelete) {
next = p;
maxTop = rect.Top;
break;
}
p = p.PreviousBlock as Paragraph;
} while (p != null);
p = rightText.Document.Blocks.LastBlock as Paragraph;
do {
var rect = p.ContentStart.GetCharacterRect(LogicalDirection.Forward);
var block = p.DataContext as Git.Diff.Block;
if (rect.Top < 0 && block.IsRightAdded) {
if (next == null || maxTop < rect.Top) {
next = p;
maxTop = rect.Top;
}
break;
}
p = p.PreviousBlock as Paragraph;
} while (p != null);
if (next != null) {
rightText.ScrollToVerticalOffset(rightText.VerticalOffset + maxTop);
}
}
#endregion #endregion
} }
} }