Skip to content

Commit 4dd2847

Browse files
committed
feature: use custom BranchSelector instead of ComboBox to select remote branches with searching enabled (#2217)
Signed-off-by: leo <longshuang@msn.cn>
1 parent 1f1cd2f commit 4dd2847

File tree

5 files changed

+380
-51
lines changed

5 files changed

+380
-51
lines changed

src/ViewModels/AddWorktree.cs

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,6 @@ public List<string> LocalBranches
3737
private set;
3838
}
3939

40-
public List<string> RemoteBranches
41-
{
42-
get;
43-
private set;
44-
}
45-
4640
public string SelectedBranch
4741
{
4842
get => _selectedBranch;
@@ -59,24 +53,30 @@ public bool SetTrackingBranch
5953
}
6054
}
6155

62-
public string SelectedTrackingBranch
56+
public List<Models.Branch> RemoteBranches
6357
{
6458
get;
65-
set;
59+
private set;
60+
}
61+
62+
public Models.Branch SelectedTrackingBranch
63+
{
64+
get => _selectedTrackingBranch;
65+
set => SetProperty(ref _selectedTrackingBranch, value);
6666
}
6767

6868
public AddWorktree(Repository repo)
6969
{
7070
_repo = repo;
7171

7272
LocalBranches = new List<string>();
73-
RemoteBranches = new List<string>();
73+
RemoteBranches = new List<Models.Branch>();
7474
foreach (var branch in repo.Branches)
7575
{
7676
if (branch.IsLocal)
7777
LocalBranches.Add(branch.Name);
7878
else
79-
RemoteBranches.Add(branch.FriendlyName);
79+
RemoteBranches.Add(branch);
8080
}
8181
}
8282

@@ -110,7 +110,7 @@ public override async Task<bool> Sure()
110110
ProgressDescription = "Adding worktree ...";
111111

112112
var branchName = _selectedBranch;
113-
var tracking = _setTrackingBranch ? SelectedTrackingBranch : string.Empty;
113+
var tracking = (_setTrackingBranch && _selectedTrackingBranch != null) ? _selectedTrackingBranch.FriendlyName : string.Empty;
114114
var log = _repo.CreateLog("Add Worktree");
115115

116116
Use(log);
@@ -129,21 +129,18 @@ private void AutoSelectTrackingBranch()
129129
return;
130130

131131
var name = string.IsNullOrEmpty(_selectedBranch) ? System.IO.Path.GetFileName(_path.TrimEnd('/', '\\')) : _selectedBranch;
132-
var remoteBranch = RemoteBranches.Find(b => b.EndsWith(name, StringComparison.Ordinal));
133-
if (string.IsNullOrEmpty(remoteBranch))
132+
var remoteBranch = RemoteBranches.Find(b => b.Name.EndsWith(name, StringComparison.Ordinal));
133+
if (remoteBranch == null)
134134
remoteBranch = RemoteBranches[0];
135135

136-
if (!remoteBranch.Equals(SelectedTrackingBranch, StringComparison.Ordinal))
137-
{
138-
SelectedTrackingBranch = remoteBranch;
139-
OnPropertyChanged(nameof(SelectedTrackingBranch));
140-
}
136+
SelectedTrackingBranch = remoteBranch;
141137
}
142138

143139
private Repository _repo = null;
144140
private string _path = string.Empty;
145141
private bool _createNewBranch = true;
146142
private string _selectedBranch = string.Empty;
147143
private bool _setTrackingBranch = false;
144+
private Models.Branch _selectedTrackingBranch = null;
148145
}
149146
}

src/Views/AddWorktree.axaml

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
44
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
55
xmlns:vm="using:SourceGit.ViewModels"
6+
xmlns:v="using:SourceGit.Views"
67
xmlns:c="using:SourceGit.Converters"
78
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
89
x:Class="SourceGit.Views.AddWorktree"
@@ -84,22 +85,12 @@
8485
Margin="0,0,8,0"
8586
Text="{DynamicResource Text.AddWorktree.Tracking}"/>
8687
</Border>
87-
<ComboBox Grid.Row="3" Grid.Column="1"
88-
Height="28" Padding="8,0"
89-
VerticalAlignment="Center" HorizontalAlignment="Stretch"
90-
ItemsSource="{Binding RemoteBranches}"
91-
IsTextSearchEnabled="True"
92-
SelectedItem="{Binding SelectedTrackingBranch, Mode=TwoWay}"
93-
IsVisible="{Binding SetTrackingBranch, Mode=OneWay}">
94-
<ComboBox.ItemTemplate>
95-
<DataTemplate>
96-
<StackPanel Orientation="Horizontal" Height="20" VerticalAlignment="Center">
97-
<Path Margin="0,0,8,0" Width="14" Height="14" Fill="{DynamicResource Brush.FG1}" Data="{StaticResource Icons.Branch}"/>
98-
<TextBlock Text="{Binding}"/>
99-
</StackPanel>
100-
</DataTemplate>
101-
</ComboBox.ItemTemplate>
102-
</ComboBox>
88+
<v:BranchSelector Grid.Row="3" Grid.Column="1"
89+
Height="28"
90+
VerticalAlignment="Center" HorizontalAlignment="Stretch"
91+
Branches="{Binding RemoteBranches}"
92+
SelectedBranch="{Binding SelectedTrackingBranch, Mode=TwoWay}"
93+
IsVisible="{Binding SetTrackingBranch, Mode=OneWay}"/>
10394

10495
<CheckBox Grid.Row="4" Grid.Column="1"
10596
Height="32"

src/Views/BranchSelector.axaml

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
<UserControl xmlns="https://github.com/avaloniaui"
2+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+
xmlns:m="using:SourceGit.Models"
6+
xmlns:v="using:SourceGit.Views"
7+
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
8+
x:Class="SourceGit.Views.BranchSelector">
9+
<UserControl.Styles>
10+
<Style Selector="v|BranchSelector">
11+
<Setter Property="FocusAdorner">
12+
<FocusAdornerTemplate>
13+
<Border/>
14+
</FocusAdornerTemplate>
15+
</Setter>
16+
17+
<Setter Property="Template">
18+
<ControlTemplate>
19+
<Grid Background="Transparent">
20+
<Border x:Name="PART_Background"
21+
Background="{DynamicResource Brush.Contents}"
22+
BorderThickness="1"
23+
BorderBrush="{DynamicResource Brush.Border1}"
24+
CornerRadius="3"/>
25+
26+
<Grid x:Name="PART_Selected"
27+
Background="Transparent"
28+
ColumnDefinitions="Auto,*,32"
29+
PointerPressed="OnToggleDropDown">
30+
<Path Grid.Column="0"
31+
Margin="8,0,0,0"
32+
Width="14" Height="14"
33+
Data="{StaticResource Icons.Branch}"
34+
IsHitTestVisible="False"/>
35+
36+
<ContentControl Grid.Column="1"
37+
Margin="8,0,0,0"
38+
Content="{TemplateBinding SelectedBranch, Mode=OneWay}">
39+
<ContentControl.DataTemplates>
40+
<DataTemplate DataType="m:Branch">
41+
<Grid>
42+
<TextBlock Text="{Binding FriendlyName, Mode=OneWay}"/>
43+
</Grid>
44+
</DataTemplate>
45+
</ContentControl.DataTemplates>
46+
</ContentControl>
47+
48+
<Path Grid.Column="2"
49+
Width="12" Height="12"
50+
Margin="0,0,10,0"
51+
HorizontalAlignment="Right" VerticalAlignment="Center"
52+
Data="M0 0 M1939 486L2029 576L1024 1581L19 576L109 486L1024 1401L1939 486Z"
53+
IsHitTestVisible="False"/>
54+
</Grid>
55+
56+
<Popup x:Name="PART_Popup"
57+
WindowManagerAddShadowHint="False"
58+
IsOpen="{TemplateBinding IsDropDownOpened, Mode=TwoWay}"
59+
Width="{Binding Bounds.Width, ElementName=PART_Background}"
60+
MaxHeight="600"
61+
PlacementTarget="PART_Background"
62+
Placement="BottomEdgeAlignedLeft"
63+
VerticalOffset="2"
64+
IsLightDismissEnabled="True"
65+
InheritsTransform="True">
66+
<Border Background="{DynamicResource Brush.Contents}"
67+
BorderThickness="1"
68+
BorderBrush="{DynamicResource Brush.Border1}"
69+
CornerRadius="4"
70+
Padding="4"
71+
HorizontalAlignment="Stretch">
72+
<Grid RowDefinitions="36,Auto">
73+
<TextBox Grid.Row="0"
74+
x:Name="PART_TextFilter"
75+
Height="24"
76+
Margin="6,0"
77+
BorderThickness="1"
78+
CornerRadius="12"
79+
Text="{TemplateBinding SearchFilter, Mode=TwoWay}"
80+
BorderBrush="{DynamicResource Brush.Border2}"
81+
VerticalContentAlignment="Center"
82+
KeyDown="OnSearchBoxKeyDown">
83+
<TextBox.InnerLeftContent>
84+
<Path Width="14" Height="14"
85+
Margin="6,0,0,0"
86+
Fill="{DynamicResource Brush.FG2}"
87+
Data="{StaticResource Icons.Search}"/>
88+
</TextBox.InnerLeftContent>
89+
90+
<TextBox.InnerRightContent>
91+
<Button Classes="icon_button"
92+
Width="16"
93+
Margin="0,0,6,0"
94+
Click="OnClearSearchFilter"
95+
IsVisible="{Binding ElementName=PART_TextFilter, Path=Text, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
96+
HorizontalAlignment="Right">
97+
<Path Width="14" Height="14"
98+
Margin="0,1,0,0"
99+
Fill="{DynamicResource Brush.FG1}"
100+
Data="{StaticResource Icons.Clear}"/>
101+
</Button>
102+
</TextBox.InnerRightContent>
103+
</TextBox>
104+
105+
<ListBox Grid.Row="1"
106+
Focusable="True"
107+
Margin="0,4"
108+
MaxHeight="360"
109+
BorderThickness="0"
110+
Background="Transparent"
111+
ItemsSource="{TemplateBinding VisibleBranches, Mode=OneWay}"
112+
SelectedItem="{TemplateBinding SelectedBranch, Mode=TwoWay}"
113+
KeyDown="OnDropDownListKeyDown">
114+
<ListBox.ItemsPanel>
115+
<ItemsPanelTemplate>
116+
<VirtualizingStackPanel Orientation="Vertical"/>
117+
</ItemsPanelTemplate>
118+
</ListBox.ItemsPanel>
119+
120+
<ListBox.Styles>
121+
<Style Selector="ListBoxItem">
122+
<Setter Property="Height" Value="28"/>
123+
<Setter Property="CornerRadius" Value="3"/>
124+
</Style>
125+
</ListBox.Styles>
126+
127+
<ListBox.ItemTemplate>
128+
<DataTemplate DataType="m:Branch">
129+
<StackPanel Orientation="Horizontal" Background="Transparent" Height="28" PointerPressed="OnDropDownItemPointerPressed">
130+
<Path Width="14" Height="14" Fill="{DynamicResource Brush.FG1}" Data="{StaticResource Icons.Branch}"/>
131+
<TextBlock Margin="8,0,0,0" Text="{Binding FriendlyName, Mode=OneWay}" VerticalAlignment="Center"/>
132+
</StackPanel>
133+
</DataTemplate>
134+
</ListBox.ItemTemplate>
135+
</ListBox>
136+
</Grid>
137+
</Border>
138+
</Popup>
139+
</Grid>
140+
</ControlTemplate>
141+
</Setter>
142+
143+
<Style Selector="^:pointerover /template/ Border#PART_Background">
144+
<Setter Property="BorderBrush" Value="{DynamicResource Brush.Accent}" />
145+
</Style>
146+
147+
<Style Selector="^:focus-visible">
148+
<Style Selector="^ /template/ Border#PART_Background">
149+
<Setter Property="Background" Value="{DynamicResource ComboBoxBackgroundUnfocused}" />
150+
</Style>
151+
</Style>
152+
</Style>
153+
</UserControl.Styles>
154+
</UserControl>

0 commit comments

Comments
 (0)