Skip to content

Commit 237d4bc

Browse files
committed
feature: support compact folders display mode in changes tree view (#1674) (#1729)
Signed-off-by: leo <[email protected]>
1 parent ce23e8c commit 237d4bc

13 files changed

+82
-19
lines changed

src/Resources/Locales/en_US.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@
526526
<x:String x:Key="Text.Preferences.Appearance" xml:space="preserve">APPEARANCE</x:String>
527527
<x:String x:Key="Text.Preferences.Appearance.DefaultFont" xml:space="preserve">Default Font</x:String>
528528
<x:String x:Key="Text.Preferences.Appearance.EditorTabWidth" xml:space="preserve">Editor Tab Width</x:String>
529+
<x:String x:Key="Text.Preferences.Appearance.EnableCompactFolders" xml:space="preserve">Enable compact folders in changes tree</x:String>
529530
<x:String x:Key="Text.Preferences.Appearance.FontSize" xml:space="preserve">Font Size</x:String>
530531
<x:String x:Key="Text.Preferences.Appearance.FontSize.Default" xml:space="preserve">Default</x:String>
531532
<x:String x:Key="Text.Preferences.Appearance.FontSize.Editor" xml:space="preserve">Editor</x:String>

src/Resources/Locales/zh_CN.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@
530530
<x:String x:Key="Text.Preferences.Appearance" xml:space="preserve">外观配置</x:String>
531531
<x:String x:Key="Text.Preferences.Appearance.DefaultFont" xml:space="preserve">缺省字体</x:String>
532532
<x:String x:Key="Text.Preferences.Appearance.EditorTabWidth" xml:space="preserve">编辑器制表符宽度</x:String>
533+
<x:String x:Key="Text.Preferences.Appearance.EnableCompactFolders" xml:space="preserve">在变更列表树中启用紧凑文件夹模式</x:String>
533534
<x:String x:Key="Text.Preferences.Appearance.FontSize" xml:space="preserve">字体大小</x:String>
534535
<x:String x:Key="Text.Preferences.Appearance.FontSize.Default" xml:space="preserve">默认</x:String>
535536
<x:String x:Key="Text.Preferences.Appearance.FontSize.Editor" xml:space="preserve">代码编辑器</x:String>

src/Resources/Locales/zh_TW.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@
530530
<x:String x:Key="Text.Preferences.Appearance" xml:space="preserve">外觀設定</x:String>
531531
<x:String x:Key="Text.Preferences.Appearance.DefaultFont" xml:space="preserve">預設字型</x:String>
532532
<x:String x:Key="Text.Preferences.Appearance.EditorTabWidth" xml:space="preserve">編輯器 Tab 寬度</x:String>
533+
<x:String x:Key="Text.Preferences.Appearance.EnableCompactFolders" xml:space="preserve">在變更樹中啟用精簡文件夾顯示模式</x:String>
533534
<x:String x:Key="Text.Preferences.Appearance.FontSize" xml:space="preserve">字型大小</x:String>
534535
<x:String x:Key="Text.Preferences.Appearance.FontSize.Default" xml:space="preserve">預設</x:String>
535536
<x:String x:Key="Text.Preferences.Appearance.FontSize.Editor" xml:space="preserve">程式碼</x:String>

src/ViewModels/ChangeTreeNode.cs

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
using System.Collections.Generic;
2-
2+
using System.IO;
33
using CommunityToolkit.Mvvm.ComponentModel;
44

55
namespace SourceGit.ViewModels
66
{
77
public class ChangeTreeNode : ObservableObject
88
{
99
public string FullPath { get; set; }
10+
public string DisplayName { get; set; }
1011
public int Depth { get; private set; } = 0;
1112
public Models.Change Change { get; set; } = null;
1213
public List<ChangeTreeNode> Children { get; set; } = new List<ChangeTreeNode>();
@@ -32,22 +33,22 @@ public bool IsExpanded
3233
set => SetProperty(ref _isExpanded, value);
3334
}
3435

35-
public ChangeTreeNode(Models.Change c, int depth)
36+
public ChangeTreeNode(Models.Change c)
3637
{
3738
FullPath = c.Path;
38-
Depth = depth;
39+
DisplayName = Path.GetFileName(c.Path);
3940
Change = c;
4041
IsExpanded = false;
4142
}
4243

43-
public ChangeTreeNode(string path, bool isExpanded, int depth)
44+
public ChangeTreeNode(string path, bool isExpanded)
4445
{
4546
FullPath = path;
46-
Depth = depth;
47+
DisplayName = Path.GetFileName(path);
4748
IsExpanded = isExpanded;
4849
}
4950

50-
public static List<ChangeTreeNode> Build(IList<Models.Change> changes, HashSet<string> folded)
51+
public static List<ChangeTreeNode> Build(IList<Models.Change> changes, HashSet<string> folded, bool compactFolders)
5152
{
5253
var nodes = new List<ChangeTreeNode>();
5354
var folders = new Dictionary<string, ChangeTreeNode>();
@@ -57,12 +58,11 @@ public static List<ChangeTreeNode> Build(IList<Models.Change> changes, HashSet<s
5758
var sepIdx = c.Path.IndexOf('/');
5859
if (sepIdx == -1)
5960
{
60-
nodes.Add(new ChangeTreeNode(c, 0));
61+
nodes.Add(new ChangeTreeNode(c));
6162
}
6263
else
6364
{
6465
ChangeTreeNode lastFolder = null;
65-
int depth = 0;
6666

6767
while (sepIdx != -1)
6868
{
@@ -73,27 +73,32 @@ public static List<ChangeTreeNode> Build(IList<Models.Change> changes, HashSet<s
7373
}
7474
else if (lastFolder == null)
7575
{
76-
lastFolder = new ChangeTreeNode(folder, !folded.Contains(folder), depth);
76+
lastFolder = new ChangeTreeNode(folder, !folded.Contains(folder));
7777
folders.Add(folder, lastFolder);
7878
InsertFolder(nodes, lastFolder);
7979
}
8080
else
8181
{
82-
var cur = new ChangeTreeNode(folder, !folded.Contains(folder), depth);
82+
var cur = new ChangeTreeNode(folder, !folded.Contains(folder));
8383
folders.Add(folder, cur);
8484
InsertFolder(lastFolder.Children, cur);
8585
lastFolder = cur;
8686
}
8787

88-
depth++;
8988
sepIdx = c.Path.IndexOf('/', sepIdx + 1);
9089
}
9190

92-
lastFolder?.Children.Add(new ChangeTreeNode(c, depth));
91+
lastFolder?.Children.Add(new ChangeTreeNode(c));
9392
}
9493
}
9594

96-
Sort(nodes);
95+
if (compactFolders)
96+
{
97+
foreach (var node in nodes)
98+
Compact(node);
99+
}
100+
101+
SortAndSetDepth(nodes, 0);
97102

98103
folders.Clear();
99104
return nodes;
@@ -113,12 +118,37 @@ private static void InsertFolder(List<ChangeTreeNode> collection, ChangeTreeNode
113118
collection.Add(subFolder);
114119
}
115120

116-
private static void Sort(List<ChangeTreeNode> nodes)
121+
private static void Compact(ChangeTreeNode node)
122+
{
123+
var childrenCount = node.Children.Count;
124+
if (childrenCount == 0)
125+
return;
126+
127+
if (childrenCount > 1)
128+
{
129+
foreach (var c in node.Children)
130+
Compact(c);
131+
return;
132+
}
133+
134+
var child = node.Children[0];
135+
if (child.Change != null)
136+
return;
137+
138+
node.FullPath = $"{node.FullPath}/{child.DisplayName}";
139+
node.DisplayName = $"{node.DisplayName} / {child.DisplayName}";
140+
node.IsExpanded = child.IsExpanded;
141+
node.Children = child.Children;
142+
Compact(node);
143+
}
144+
145+
private static void SortAndSetDepth(List<ChangeTreeNode> nodes, int depth)
117146
{
118147
foreach (var node in nodes)
119148
{
149+
node.Depth = depth;
120150
if (node.IsFolder)
121-
Sort(node.Children);
151+
SortAndSetDepth(node.Children, depth + 1);
122152
}
123153

124154
nodes.Sort((l, r) =>

src/ViewModels/Preferences.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,12 @@ public int LFSImageActiveIdx
267267
set => SetProperty(ref _lfsImageActiveIdx, value);
268268
}
269269

270+
public bool EnableCompactFoldersInChangesTree
271+
{
272+
get => _enableCompactFoldersInChangesTree;
273+
set => SetProperty(ref _enableCompactFoldersInChangesTree, value);
274+
}
275+
270276
public Models.ChangeViewMode UnstagedChangeViewMode
271277
{
272278
get => _unstagedChangeViewMode;
@@ -718,6 +724,7 @@ private bool RemoveInvalidRepositoriesRecursive(List<RepositoryNode> collection)
718724
private bool _useFullTextDiff = false;
719725
private bool _useBlockNavigationInDiffView = false;
720726
private int _lfsImageActiveIdx = 0;
727+
private bool _enableCompactFoldersInChangesTree = false;
721728

722729
private Models.ChangeViewMode _unstagedChangeViewMode = Models.ChangeViewMode.List;
723730
private Models.ChangeViewMode _stagedChangeViewMode = Models.ChangeViewMode.List;

src/Views/BranchCompare.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
<!-- Changes -->
126126
<Border Grid.Row="1" Margin="0,4,0,0" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1" Background="{DynamicResource Brush.Contents}">
127127
<v:ChangeCollectionView ViewMode="{Binding Source={x:Static vm:Preferences.Instance}, Path=CommitChangeViewMode}"
128+
EnableCompactFolders="{Binding Source={x:Static vm:Preferences.Instance}, Path=EnableCompactFoldersInChangesTree}"
128129
Changes="{Binding VisibleChanges}"
129130
SelectedChanges="{Binding SelectedChanges, Mode=TwoWay}"
130131
ContextRequested="OnChangeContextRequested"/>

src/Views/ChangeCollectionView.axaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@
6565
IsVisible="{Binding !IsFolder}"/>
6666

6767
<StackPanel Grid.Column="2" Orientation="Horizontal" Margin="4,0,0,0">
68-
<TextBlock Classes="primary" Text="{Binding ConflictMarker}" Foreground="DarkOrange" FontWeight="Bold" Margin="0,0,4,0" IsVisible="{Binding ShowConflictMarker}"/>
69-
<TextBlock Classes="primary" Text="{Binding FullPath, Converter={x:Static c:PathConverters.PureFileName}}"/>
68+
<TextBlock Classes="primary" Text="{Binding ConflictMarker, Mode=OneWay}" Foreground="DarkOrange" FontWeight="Bold" Margin="0,0,4,0" IsVisible="{Binding ShowConflictMarker}"/>
69+
<TextBlock Classes="primary" Text="{Binding DisplayName, Mode=OneWay}"/>
7070
</StackPanel>
7171
</Grid>
7272
</DataTemplate>

src/Views/ChangeCollectionView.axaml.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ public Models.ChangeViewMode ViewMode
109109
set => SetValue(ViewModeProperty, value);
110110
}
111111

112+
public static readonly StyledProperty<bool> EnableCompactFoldersProperty =
113+
AvaloniaProperty.Register<ChangeCollectionView, bool>(nameof(EnableCompactFolders), false);
114+
115+
public bool EnableCompactFolders
116+
{
117+
get => GetValue(EnableCompactFoldersProperty);
118+
set => SetValue(EnableCompactFoldersProperty, value);
119+
}
120+
112121
public static readonly StyledProperty<List<Models.Change>> ChangesProperty =
113122
AvaloniaProperty.Register<ChangeCollectionView, List<Models.Change>>(nameof(Changes));
114123

@@ -254,6 +263,9 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang
254263
UpdateDataSource(false);
255264
else if (change.Property == SelectedChangesProperty)
256265
UpdateSelection();
266+
267+
if (change.Property == EnableCompactFoldersProperty && ViewMode == Models.ChangeViewMode.Tree)
268+
UpdateDataSource(true);
257269
}
258270

259271
private void OnRowDataContextChanged(object sender, EventArgs e)
@@ -384,7 +396,7 @@ private void UpdateDataSource(bool onlyViewModeChange)
384396
}
385397

386398
var tree = new ViewModels.ChangeCollectionAsTree();
387-
tree.Tree = ViewModels.ChangeTreeNode.Build(changes, oldFolded);
399+
tree.Tree = ViewModels.ChangeTreeNode.Build(changes, oldFolded, EnableCompactFolders);
388400

389401
var rows = new List<ViewModels.ChangeTreeNode>();
390402
MakeTreeRows(rows, tree.Tree);

src/Views/CommitChanges.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
<Border Grid.Row="1" Margin="0,4,0,0" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1" Background="{DynamicResource Brush.Contents}">
4949
<v:ChangeCollectionView SelectionMode="Single"
5050
ViewMode="{Binding Source={x:Static vm:Preferences.Instance}, Path=CommitChangeViewMode}"
51+
EnableCompactFolders="{Binding Source={x:Static vm:Preferences.Instance}, Path=EnableCompactFoldersInChangesTree}"
5152
Changes="{Binding VisibleChanges}"
5253
SelectedChanges="{Binding SelectedChanges, Mode=TwoWay}"
5354
ContextRequested="OnChangeContextRequested"/>

src/Views/Preferences.axaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@
159159
<TabItem.Header>
160160
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preferences.Appearance}"/>
161161
</TabItem.Header>
162-
<Grid Margin="8" RowDefinitions="32,32,32,32,32,32,32,32,Auto" ColumnDefinitions="Auto,*">
162+
<Grid Margin="8" RowDefinitions="32,32,32,32,32,32,32,32,32,Auto" ColumnDefinitions="Auto,*">
163163
<TextBlock Grid.Row="0" Grid.Column="0"
164164
Text="{DynamicResource Text.Preferences.Appearance.Theme}"
165165
HorizontalAlignment="Right"
@@ -266,6 +266,11 @@
266266
IsChecked="{Binding UseFixedTabWidth, Mode=TwoWay}"/>
267267

268268
<CheckBox Grid.Row="8" Grid.Column="1"
269+
Height="32"
270+
Content="{DynamicResource Text.Preferences.Appearance.EnableCompactFolders}"
271+
IsChecked="{Binding EnableCompactFoldersInChangesTree, Mode=TwoWay}"/>
272+
273+
<CheckBox Grid.Row="9" Grid.Column="1"
269274
Height="32"
270275
Content="{DynamicResource Text.Preferences.Appearance.UseNativeWindowFrame}"
271276
IsChecked="{Binding UseSystemWindowFrame, Mode=OneTime}"

0 commit comments

Comments
 (0)