Files
sourcegit/src/Views/BranchTree.axaml
2025-08-29 17:32:22 +08:00

171 lines
8.7 KiB
XML

<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:c="using:SourceGit.Converters"
xmlns:v="using:SourceGit.Views"
xmlns:vm="using:SourceGit.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.BranchTree"
x:Name="ThisControl">
<ListBox x:Name="BranchesPresenter"
Classes="repo_left_content_list"
ItemsSource="{Binding #ThisControl.Rows}"
SelectionMode="Multiple"
SelectionChanged="OnNodesSelectionChanged"
KeyDown="OnTreeKeyDown"
ContextRequested="OnTreeContextRequested">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Styles>
<Style Selector="ListBoxItem" x:DataType="vm:BranchTreeNode">
<Setter Property="CornerRadius" Value="{Binding CornerRadius}"/>
</Style>
<Style Selector="ListBoxItem:pointerover v|FilterModeSwitchButton">
<Setter Property="IsNoneVisible" Value="True"/>
</Style>
</ListBox.Styles>
<ListBox.ItemTemplate>
<DataTemplate DataType="vm:BranchTreeNode">
<Border Background="Transparent"
PointerPressed="OnNodePointerPressed"
ToolTip.Tip="{Binding Backend}"
ToolTip.Placement="Right">
<Border.DataTemplates>
<DataTemplate DataType="m:Branch">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Path Width="12" Height="12" Data="{StaticResource Icons.Branch}"/>
<TextBlock FontWeight="Bold" VerticalAlignment="Center" Margin="4,0,0,0" Text="{Binding FriendlyName}"/>
<Border Background="Green" Margin="4,0,0,0" CornerRadius="4" VerticalAlignment="Center" IsVisible="{Binding !IsLocal}">
<TextBlock Text="{DynamicResource Text.BranchTree.Remote}" FontSize="12" Classes="primary" Margin="4,0" Foreground="White" VerticalAlignment="Center"/>
</Border>
</StackPanel>
<Grid RowDefinitions="Auto,Auto,Auto" ColumnDefinitions="Auto,Auto" Margin="0,8,0,0" IsVisible="{Binding IsLocal, Mode=OneWay}">
<TextBlock Grid.Row="0" Grid.Column="0"
Classes="info_label"
HorizontalAlignment="Left" VerticalAlignment="Center"
Text="{DynamicResource Text.BranchTree.Tracking}"/>
<StackPanel Grid.Row="0" Grid.Column="1"
Margin="8,0,0,0"
Orientation="Horizontal">
<TextBlock Text="{Binding Upstream, Mode=OneWay, Converter={x:Static c:StringConverters.ToFriendlyUpstream}}"
IsVisible="{Binding Upstream, Mode=OneWay, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
<TextBlock IsVisible="{Binding Upstream, Mode=OneWay, Converter={x:Static StringConverters.IsNullOrEmpty}}">
<Run Text="---"/>
<Run Text="(none)" Foreground="{DynamicResource Brush.FG2}"/>
</TextBlock>
<Border Background="OrangeRed" Margin="4,0,0,0" CornerRadius="4" VerticalAlignment="Center" IsVisible="{Binding IsUpstreamGone}">
<TextBlock Text="{DynamicResource Text.BranchTree.InvalidUpstream}" FontSize="12" Classes="primary" Margin="4,1" Foreground="White" VerticalAlignment="Center"/>
</Border>
</StackPanel>
<TextBlock Grid.Row="1" Grid.Column="0"
Classes="info_label"
Margin="0,4,0,0"
HorizontalAlignment="Left" VerticalAlignment="Center"
Text="{DynamicResource Text.BranchTree.Status}"
IsVisible="{Binding IsTrackStatusVisible, Mode=OneWay}"/>
<v:BranchTreeNodeTrackStatusTooltip Grid.Row="1" Grid.Column="1"
Margin="8,4,0,0"/>
<TextBlock Grid.Row="2" Grid.Column="0"
Classes="info_label"
Margin="0,4,0,0"
HorizontalAlignment="Left" VerticalAlignment="Center"
Text="{DynamicResource Text.BranchTree.Worktree}"
IsVisible="{Binding HasWorktree}"/>
<TextBlock Grid.Row="2" Grid.Column="1"
Margin="8,4,0,0"
Text="{Binding WorktreePath, Mode=OneWay}"
IsVisible="{Binding HasWorktree}"/>
</Grid>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="m:Remote">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Path Width="12" Height="12" Data="{StaticResource Icons.Remote}"/>
<TextBlock FontWeight="Bold" VerticalAlignment="Center" Text="{Binding Name}" Margin="8,0,0,0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
<TextBlock Classes="info_label"
HorizontalAlignment="Left" VerticalAlignment="Center"
Text="{DynamicResource Text.BranchTree.URL}"/>
<TextBlock Margin="6,0,0,0" Foreground="{DynamicResource Brush.Link}" Text="{Binding URL, Mode=OneWay}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</Border.DataTemplates>
<Grid Height="24"
Margin="{Binding Depth, Converter={x:Static c:IntConverters.ToTreeMargin}}"
ColumnDefinitions="16,*">
<!-- Tree Expander -->
<v:BranchTreeNodeToggleButton Grid.Column="0"
Classes="tree_expander"
Focusable="False"
HorizontalAlignment="Center"
IsChecked="{Binding IsExpanded, Mode=OneWay}"
IsVisible="{Binding !IsBranch}"/>
<!-- Content Area (allows double-clicking) -->
<Grid Grid.Column="1"
Background="Transparent"
ColumnDefinitions="18,*,Auto,Auto"
DoubleTapped="OnDoubleTappedBranchNode">
<!-- Icon -->
<v:BranchTreeNodeIcon Grid.Column="0" IsExpanded="{Binding IsExpanded}"/>
<!-- Name -->
<TextBlock Grid.Column="1"
Classes="primary"
FontWeight="{Binding IsCurrent, Converter={x:Static c:BoolConverters.IsBoldToFontWeight}}"
TextTrimming="CharacterEllipsis">
<Run Text="{Binding Name}"/>
<Run Text="{Binding BranchesCount}" Foreground="{DynamicResource Brush.FG2}"/>
</TextBlock>
<!-- Upstream invalid tip -->
<Border Grid.Column="2"
Width="12" Height="12"
Margin="8,0"
Background="Transparent"
IsVisible="{Binding ShowUpstreamGoneTip}">
<Path Data="{StaticResource Icons.Error}" Fill="DarkOrange"/>
</Border>
<!-- Tracking status -->
<v:BranchTreeNodeTrackStatusPresenter Grid.Column="2"
VerticalAlignment="Center"
FontFamily="{DynamicResource Fonts.Monospace}"
FontSize="10"
Foreground="{DynamicResource Brush.BadgeFG}"
Background="{DynamicResource Brush.Badge}"/>
<!-- Filter Mode Switcher -->
<v:FilterModeSwitchButton Grid.Column="3"
Margin="0,0,12,0"
Mode="{Binding FilterMode}"/>
</Grid>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</UserControl>