mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-23 20:47:25 -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="VerticalAlignment" Value="Stretch"/>
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<ControlTemplate>
|
<ControlTemplate>
|
||||||
<Grid ColumnDefinitions="Auto,*">
|
<Grid ColumnDefinitions="Auto,*" Background="Transparent">
|
||||||
<Path Grid.Column="0"
|
<Path Grid.Column="0"
|
||||||
x:Name="PART_IndicatorIcon"
|
x:Name="PART_IndicatorIcon"
|
||||||
Width="10"
|
Width="10"
|
||||||
|
@ -1072,6 +1072,7 @@
|
||||||
<Setter Property="Margin" Value="0" />
|
<Setter Property="Margin" Value="0" />
|
||||||
<Setter Property="Width" Value="8" />
|
<Setter Property="Width" Value="8" />
|
||||||
<Setter Property="Height" Value="8" />
|
<Setter Property="Height" Value="8" />
|
||||||
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<ControlTemplate>
|
<ControlTemplate>
|
||||||
<Border Background="Transparent"
|
<Border Background="Transparent"
|
||||||
|
@ -1224,8 +1225,7 @@
|
||||||
Classes="tree_expander"
|
Classes="tree_expander"
|
||||||
Focusable="False"
|
Focusable="False"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}"
|
IsChecked="{TemplateBinding IsExpanded, Mode=TwoWay}"/>
|
||||||
IsHitTestVisible="False" />
|
|
||||||
</Panel>
|
</Panel>
|
||||||
<ContentPresenter Name="PART_HeaderPresenter"
|
<ContentPresenter Name="PART_HeaderPresenter"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
|
|
|
@ -53,51 +53,55 @@
|
||||||
<DataTemplate x:DataType="vm:BranchTreeNode">
|
<DataTemplate x:DataType="vm:BranchTreeNode">
|
||||||
<Grid Height="24"
|
<Grid Height="24"
|
||||||
Margin="{Binding Depth, Converter={x:Static c:IntConverters.ToTreeMargin}}"
|
Margin="{Binding Depth, Converter={x:Static c:IntConverters.ToTreeMargin}}"
|
||||||
ColumnDefinitions="16,20,*,Auto,Auto"
|
ColumnDefinitions="16,*"
|
||||||
Background="Transparent"
|
|
||||||
DoubleTapped="OnDoubleTappedBranchNode"
|
|
||||||
ToolTip.Tip="{Binding Tooltip}">
|
ToolTip.Tip="{Binding Tooltip}">
|
||||||
|
|
||||||
<!-- Tree Expander -->
|
<!-- Tree Expander -->
|
||||||
<ToggleButton Grid.Column="0"
|
<v:BranchTreeNodeToggleButton Grid.Column="0"
|
||||||
Classes="tree_expander"
|
Classes="tree_expander"
|
||||||
Focusable="False"
|
Focusable="False"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
IsChecked="{Binding IsExpanded}"
|
IsChecked="{Binding IsExpanded, Mode=OneWay}"
|
||||||
IsHitTestVisible="False"
|
IsVisible="{Binding !IsBranch}"/>
|
||||||
IsVisible="{Binding !IsBranch}"/>
|
|
||||||
|
|
||||||
<!-- Icon -->
|
<!-- Content Area (allows double-click) -->
|
||||||
<v:BranchTreeNodeIcon Grid.Column="1"
|
<Grid Grid.Column="1"
|
||||||
Node="{Binding}"
|
Background="Transparent"
|
||||||
IsExpanded="{Binding IsExpanded}"/>
|
ColumnDefinitions="20,*,Auto,Auto"
|
||||||
|
DoubleTapped="OnDoubleTappedBranchNode">
|
||||||
|
|
||||||
|
<!-- Icon -->
|
||||||
|
<v:BranchTreeNodeIcon Grid.Column="0"
|
||||||
|
Node="{Binding}"
|
||||||
|
IsExpanded="{Binding IsExpanded}"/>
|
||||||
|
|
||||||
<!-- Name -->
|
<!-- Name -->
|
||||||
<TextBlock Grid.Column="2"
|
<TextBlock Grid.Column="1"
|
||||||
Text="{Binding Name}"
|
Text="{Binding Name}"
|
||||||
Classes="monospace"
|
Classes="monospace"
|
||||||
FontWeight="{Binding NameFontWeight}"/>
|
FontWeight="{Binding NameFontWeight}"/>
|
||||||
|
|
||||||
<!-- Tracking status -->
|
<!-- Tracking status -->
|
||||||
<Border Grid.Column="3"
|
<Border Grid.Column="2"
|
||||||
Margin="8,0"
|
Margin="8,0"
|
||||||
Height="18"
|
Height="18"
|
||||||
CornerRadius="9"
|
CornerRadius="9"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Background="{DynamicResource Brush.Badge}"
|
Background="{DynamicResource Brush.Badge}"
|
||||||
IsVisible="{Binding IsUpstreamTrackStatusVisible}">
|
IsVisible="{Binding IsUpstreamTrackStatusVisible}">
|
||||||
<TextBlock Classes="monospace" FontSize="10" HorizontalAlignment="Center" Margin="9,0" Text="{Binding UpstreamTrackStatus}" Foreground="{DynamicResource Brush.BadgeFG}"/>
|
<TextBlock Classes="monospace" FontSize="10" HorizontalAlignment="Center" Margin="9,0" Text="{Binding UpstreamTrackStatus}" Foreground="{DynamicResource Brush.BadgeFG}"/>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- Filter Toggle Button -->
|
<!-- Filter Toggle Button -->
|
||||||
<ToggleButton Grid.Column="4"
|
<ToggleButton Grid.Column="3"
|
||||||
Classes="filter"
|
Classes="filter"
|
||||||
Margin="0,0,8,0"
|
Margin="0,0,8,0"
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
IsCheckedChanged="OnToggleFilter"
|
IsCheckedChanged="OnToggleFilter"
|
||||||
IsVisible="{Binding IsBranch}"
|
IsVisible="{Binding IsBranch}"
|
||||||
IsChecked="{Binding IsFiltered}"
|
IsChecked="{Binding IsFiltered}"
|
||||||
ToolTip.Tip="{DynamicResource Text.Filter}"/>
|
ToolTip.Tip="{DynamicResource Text.Filter}"/>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
</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 partial class BranchTree : UserControl
|
||||||
{
|
{
|
||||||
public static readonly StyledProperty<List<ViewModels.BranchTreeNode>> NodesProperty =
|
public static readonly StyledProperty<List<ViewModels.BranchTreeNode>> NodesProperty =
|
||||||
|
@ -132,6 +149,42 @@ namespace SourceGit.Views
|
||||||
BranchesPresenter.SelectedItem = null;
|
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)
|
protected override void OnSizeChanged(SizeChangedEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnSizeChanged(e);
|
base.OnSizeChanged(e);
|
||||||
|
@ -165,6 +218,9 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
private void OnNodesSelectionChanged(object _, SelectionChangedEventArgs e)
|
private void OnNodesSelectionChanged(object _, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
|
if (_disableSelectionChangingEvent)
|
||||||
|
return;
|
||||||
|
|
||||||
var repo = DataContext as ViewModels.Repository;
|
var repo = DataContext as ViewModels.Repository;
|
||||||
if (repo?.Settings == null)
|
if (repo?.Settings == null)
|
||||||
return;
|
return;
|
||||||
|
@ -273,35 +329,7 @@ namespace SourceGit.Views
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
node.IsExpanded = !node.IsExpanded;
|
ToggleNodeIsExpanded(node);
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -342,6 +370,8 @@ namespace SourceGit.Views
|
||||||
foreach (var sub in node.Children)
|
foreach (var sub in node.Children)
|
||||||
CollectBranchesInNode(outs, sub);
|
CollectBranchesInNode(outs, sub);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool _disableSelectionChangingEvent = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue