ux: tree toggle button

This commit is contained in:
leo 2024-07-12 11:01:02 +08:00
parent 67d0167278
commit 3c770e2525
No known key found for this signature in database
3 changed files with 104 additions and 70 deletions

View file

@ -1002,7 +1002,7 @@
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="Template">
<ControlTemplate>
<Grid ColumnDefinitions="Auto,*">
<Grid ColumnDefinitions="Auto,*" Background="Transparent">
<Path Grid.Column="0"
x:Name="PART_IndicatorIcon"
Width="10"
@ -1072,6 +1072,7 @@
<Setter Property="Margin" Value="0" />
<Setter Property="Width" Value="8" />
<Setter Property="Height" Value="8" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<ControlTemplate>
<Border Background="Transparent"
@ -1224,8 +1225,7 @@
Classes="tree_expander"
Focusable="False"
HorizontalAlignment="Center"
IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}"
IsHitTestVisible="False" />
IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}"/>
</Panel>
<ContentPresenter Name="PART_HeaderPresenter"
Grid.Column="1"

View file

@ -53,33 +53,36 @@
<DataTemplate x:DataType="vm:BranchTreeNode">
<Grid Height="24"
Margin="{Binding Depth, Converter={x:Static c:IntConverters.ToTreeMargin}}"
ColumnDefinitions="16,20,*,Auto,Auto"
Background="Transparent"
DoubleTapped="OnDoubleTappedBranchNode"
ColumnDefinitions="16,*"
ToolTip.Tip="{Binding Tooltip}">
<!-- Tree Expander -->
<ToggleButton Grid.Column="0"
<v:BranchTreeNodeToggleButton Grid.Column="0"
Classes="tree_expander"
Focusable="False"
HorizontalAlignment="Center"
IsChecked="{Binding IsExpanded}"
IsHitTestVisible="False"
IsChecked="{Binding IsExpanded, Mode=OneWay}"
IsVisible="{Binding !IsBranch}"/>
<!-- Content Area (allows double-click) -->
<Grid Grid.Column="1"
Background="Transparent"
ColumnDefinitions="20,*,Auto,Auto"
DoubleTapped="OnDoubleTappedBranchNode">
<!-- Icon -->
<v:BranchTreeNodeIcon Grid.Column="1"
<v:BranchTreeNodeIcon Grid.Column="0"
Node="{Binding}"
IsExpanded="{Binding IsExpanded}"/>
<!-- Name -->
<TextBlock Grid.Column="2"
<TextBlock Grid.Column="1"
Text="{Binding Name}"
Classes="monospace"
FontWeight="{Binding NameFontWeight}"/>
<!-- Tracking status -->
<Border Grid.Column="3"
<Border Grid.Column="2"
Margin="8,0"
Height="18"
CornerRadius="9"
@ -90,7 +93,7 @@
</Border>
<!-- Filter Toggle Button -->
<ToggleButton Grid.Column="4"
<ToggleButton Grid.Column="3"
Classes="filter"
Margin="0,0,8,0"
Background="Transparent"
@ -99,6 +102,7 @@
IsChecked="{Binding IsFiltered}"
ToolTip.Tip="{DynamicResource Text.Filter}"/>
</Grid>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

View file

@ -87,6 +87,23 @@ namespace SourceGit.Views
}
}
public class BranchTreeNodeToggleButton : ToggleButton
{
protected override Type StyleKeyOverride => typeof(ToggleButton);
protected override void OnPointerPressed(PointerPressedEventArgs e)
{
if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed &&
DataContext is ViewModels.BranchTreeNode { IsBranch: false } node)
{
var tree = this.FindAncestorOfType<BranchTree>();
tree.ToggleNodeIsExpanded(node);
}
e.Handled = true;
}
}
public partial class BranchTree : UserControl
{
public static readonly StyledProperty<List<ViewModels.BranchTreeNode>> NodesProperty =
@ -132,6 +149,42 @@ namespace SourceGit.Views
BranchesPresenter.SelectedItem = null;
}
public void ToggleNodeIsExpanded(ViewModels.BranchTreeNode node)
{
_disableSelectionChangingEvent = true;
node.IsExpanded = !node.IsExpanded;
var rows = Rows;
var depth = node.Depth;
var idx = rows.IndexOf(node);
if (idx == -1)
return;
if (node.IsExpanded)
{
var subtree = new List<ViewModels.BranchTreeNode>();
MakeRows(subtree, node.Children, depth + 1);
rows.InsertRange(idx + 1, subtree);
}
else
{
var removeCount = 0;
for (int i = idx + 1; i < rows.Count; i++)
{
var row = rows[i];
if (row.Depth <= depth)
break;
row.IsSelected = false;
removeCount++;
}
rows.RemoveRange(idx + 1, removeCount);
}
RaiseEvent(new RoutedEventArgs(RowsChangedEvent));
_disableSelectionChangingEvent = false;
}
protected override void OnSizeChanged(SizeChangedEventArgs e)
{
base.OnSizeChanged(e);
@ -165,6 +218,9 @@ namespace SourceGit.Views
private void OnNodesSelectionChanged(object _, SelectionChangedEventArgs e)
{
if (_disableSelectionChangingEvent)
return;
var repo = DataContext as ViewModels.Repository;
if (repo?.Settings == null)
return;
@ -273,35 +329,7 @@ namespace SourceGit.Views
}
else
{
node.IsExpanded = !node.IsExpanded;
var rows = Rows;
var depth = node.Depth;
var idx = rows.IndexOf(node);
if (idx == -1)
return;
if (node.IsExpanded)
{
var subtree = new List<ViewModels.BranchTreeNode>();
MakeRows(subtree, node.Children, depth + 1);
rows.InsertRange(idx + 1, subtree);
}
else
{
var removeCount = 0;
for (int i = idx + 1; i < rows.Count; i++)
{
var row = rows[i];
if (row.Depth <= depth)
break;
removeCount++;
}
rows.RemoveRange(idx + 1, removeCount);
}
RaiseEvent(new RoutedEventArgs(RowsChangedEvent));
ToggleNodeIsExpanded(node);
}
}
}
@ -342,6 +370,8 @@ namespace SourceGit.Views
foreach (var sub in node.Children)
CollectBranchesInNode(outs, sub);
}
private bool _disableSelectionChangingEvent = false;
}
}