mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-22 20:37:19 -08:00
ux: tree toggle button
This commit is contained in:
parent
67d0167278
commit
3c770e2525
3 changed files with 104 additions and 70 deletions
|
@ -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"
|
||||
|
|
|
@ -53,51 +53,55 @@
|
|||
<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"
|
||||
Classes="tree_expander"
|
||||
Focusable="False"
|
||||
HorizontalAlignment="Center"
|
||||
IsChecked="{Binding IsExpanded}"
|
||||
IsHitTestVisible="False"
|
||||
IsVisible="{Binding !IsBranch}"/>
|
||||
<v:BranchTreeNodeToggleButton Grid.Column="0"
|
||||
Classes="tree_expander"
|
||||
Focusable="False"
|
||||
HorizontalAlignment="Center"
|
||||
IsChecked="{Binding IsExpanded, Mode=OneWay}"
|
||||
IsVisible="{Binding !IsBranch}"/>
|
||||
|
||||
<!-- Icon -->
|
||||
<v:BranchTreeNodeIcon Grid.Column="1"
|
||||
Node="{Binding}"
|
||||
IsExpanded="{Binding IsExpanded}"/>
|
||||
<!-- Content Area (allows double-click) -->
|
||||
<Grid Grid.Column="1"
|
||||
Background="Transparent"
|
||||
ColumnDefinitions="20,*,Auto,Auto"
|
||||
DoubleTapped="OnDoubleTappedBranchNode">
|
||||
|
||||
<!-- Icon -->
|
||||
<v:BranchTreeNodeIcon Grid.Column="0"
|
||||
Node="{Binding}"
|
||||
IsExpanded="{Binding IsExpanded}"/>
|
||||
|
||||
<!-- Name -->
|
||||
<TextBlock Grid.Column="2"
|
||||
Text="{Binding Name}"
|
||||
Classes="monospace"
|
||||
FontWeight="{Binding NameFontWeight}"/>
|
||||
<!-- Name -->
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{Binding Name}"
|
||||
Classes="monospace"
|
||||
FontWeight="{Binding NameFontWeight}"/>
|
||||
|
||||
<!-- Tracking status -->
|
||||
<Border Grid.Column="3"
|
||||
Margin="8,0"
|
||||
Height="18"
|
||||
CornerRadius="9"
|
||||
VerticalAlignment="Center"
|
||||
Background="{DynamicResource Brush.Badge}"
|
||||
IsVisible="{Binding IsUpstreamTrackStatusVisible}">
|
||||
<TextBlock Classes="monospace" FontSize="10" HorizontalAlignment="Center" Margin="9,0" Text="{Binding UpstreamTrackStatus}" Foreground="{DynamicResource Brush.BadgeFG}"/>
|
||||
</Border>
|
||||
<!-- Tracking status -->
|
||||
<Border Grid.Column="2"
|
||||
Margin="8,0"
|
||||
Height="18"
|
||||
CornerRadius="9"
|
||||
VerticalAlignment="Center"
|
||||
Background="{DynamicResource Brush.Badge}"
|
||||
IsVisible="{Binding IsUpstreamTrackStatusVisible}">
|
||||
<TextBlock Classes="monospace" FontSize="10" HorizontalAlignment="Center" Margin="9,0" Text="{Binding UpstreamTrackStatus}" Foreground="{DynamicResource Brush.BadgeFG}"/>
|
||||
</Border>
|
||||
|
||||
<!-- Filter Toggle Button -->
|
||||
<ToggleButton Grid.Column="4"
|
||||
Classes="filter"
|
||||
Margin="0,0,8,0"
|
||||
Background="Transparent"
|
||||
IsCheckedChanged="OnToggleFilter"
|
||||
IsVisible="{Binding IsBranch}"
|
||||
IsChecked="{Binding IsFiltered}"
|
||||
ToolTip.Tip="{DynamicResource Text.Filter}"/>
|
||||
<!-- Filter Toggle Button -->
|
||||
<ToggleButton Grid.Column="3"
|
||||
Classes="filter"
|
||||
Margin="0,0,8,0"
|
||||
Background="Transparent"
|
||||
IsCheckedChanged="OnToggleFilter"
|
||||
IsVisible="{Binding IsBranch}"
|
||||
IsChecked="{Binding IsFiltered}"
|
||||
ToolTip.Tip="{DynamicResource Text.Filter}"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue