refactor: more efficient way to update the visibility of tab splitters

This commit is contained in:
leo 2024-06-06 18:09:35 +08:00
parent b0c14ab3e4
commit 5514c56a29
No known key found for this signature in database
GPG key ID: B528468E49CD0E58
4 changed files with 29 additions and 83 deletions

View file

@ -1,43 +0,0 @@
using System.Collections.Generic;
using Avalonia.Collections;
using Avalonia.Data.Converters;
namespace SourceGit.Converters
{
public static class LauncherPageConverters
{
public static readonly FuncMultiValueConverter<object, bool> ToTabSeperatorVisible =
new FuncMultiValueConverter<object, bool>(v =>
{
if (v == null)
return false;
var array = new List<object>();
array.AddRange(v);
if (array.Count != 3)
return false;
var self = array[0] as ViewModels.LauncherPage;
if (self == null)
return false;
var selected = array[1] as ViewModels.LauncherPage;
if (selected == null)
return true;
var collections = array[2] as AvaloniaList<ViewModels.LauncherPage>;
if (collections == null)
return true;
if (self == selected)
return false;
var selfIdx = collections.IndexOf(self);
if (selfIdx == collections.Count - 1)
return true;
return collections[selfIdx + 1] != selected;
});
}
}

View file

@ -23,6 +23,7 @@ namespace SourceGit.ViewModels
if (SetProperty(ref _activePage, value)) if (SetProperty(ref _activePage, value))
{ {
PopupHost.Active = value; PopupHost.Active = value;
UpdateTabSplitterVisible();
} }
} }
} }
@ -157,13 +158,12 @@ namespace SourceGit.ViewModels
ActivePage = Pages[removeIdx == Pages.Count - 1 ? removeIdx - 1 : removeIdx + 1]; ActivePage = Pages[removeIdx == Pages.Count - 1 ? removeIdx - 1 : removeIdx + 1];
CloseRepositoryInTab(page); CloseRepositoryInTab(page);
Pages.RemoveAt(removeIdx); Pages.RemoveAt(removeIdx);
OnPropertyChanged(nameof(Pages));
} }
else if (removeIdx + 1 == activeIdx) else if (removeIdx + 1 == activeIdx)
{ {
CloseRepositoryInTab(page); CloseRepositoryInTab(page);
Pages.RemoveAt(removeIdx); Pages.RemoveAt(removeIdx);
OnPropertyChanged(nameof(Pages)); UpdateTabSplitterVisible();
} }
else else
{ {
@ -174,42 +174,25 @@ namespace SourceGit.ViewModels
GC.Collect(); GC.Collect();
} }
public void CloseOtherTabs(object param) public void CloseOtherTabs()
{ {
if (Pages.Count == 1) if (Pages.Count == 1)
return; return;
var page = param as LauncherPage; var id = ActivePage.Node.Id;
if (page == null)
page = _activePage;
ActivePage = page;
foreach (var one in Pages) foreach (var one in Pages)
{ {
if (one.Node.Id != page.Node.Id) if (one.Node.Id != id)
CloseRepositoryInTab(one); CloseRepositoryInTab(one);
} }
Pages = new AvaloniaList<LauncherPage> { page }; Pages = new AvaloniaList<LauncherPage> { ActivePage };
OnPropertyChanged(nameof(Pages));
GC.Collect(); GC.Collect();
} }
public void CloseRightTabs(object param) public void CloseRightTabs()
{ {
LauncherPage page = param as LauncherPage; var endIdx = Pages.IndexOf(ActivePage);
if (page == null)
page = _activePage;
var endIdx = Pages.IndexOf(page);
var activeIdx = Pages.IndexOf(_activePage);
if (endIdx < activeIdx)
{
ActivePage = page;
}
for (var i = Pages.Count - 1; i > endIdx; i--) for (var i = Pages.Count - 1; i > endIdx; i--)
{ {
CloseRepositoryInTab(Pages[i]); CloseRepositoryInTab(Pages[i]);
@ -275,6 +258,13 @@ namespace SourceGit.ViewModels
page.Data = null; page.Data = null;
} }
private void UpdateTabSplitterVisible()
{
var activePageIdx = ActivePage == null ? -1 : Pages.IndexOf(ActivePage);
for (int i = 0; i < Pages.Count; i++)
Pages[i].IsTabSplitterVisible = (activePageIdx != i && activePageIdx != i + 1);
}
private LauncherPage _activePage = null; private LauncherPage _activePage = null;
} }
} }

View file

@ -18,6 +18,12 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _data, value); set => SetProperty(ref _data, value);
} }
public bool IsTabSplitterVisible
{
get => _isTabSplitterVisible;
set => SetProperty(ref _isTabSplitterVisible, value);
}
public AvaloniaList<Models.Notification> Notifications public AvaloniaList<Models.Notification> Notifications
{ {
get; get;
@ -50,12 +56,11 @@ namespace SourceGit.ViewModels
public void DismissNotification(object param) public void DismissNotification(object param)
{ {
if (param is Models.Notification notice) if (param is Models.Notification notice)
{
Notifications.Remove(notice); Notifications.Remove(notice);
}
} }
private RepositoryNode _node = null; private RepositoryNode _node = null;
private object _data = null; private object _data = null;
private bool _isTabSplitterVisible = true;
} }
} }

View file

@ -125,11 +125,9 @@
CommandParameter="{Binding}" CommandParameter="{Binding}"
InputGesture="{OnPlatform Ctrl+W, macOS=⌘+W}"/> InputGesture="{OnPlatform Ctrl+W, macOS=⌘+W}"/>
<MenuItem Header="{DynamicResource Text.PageTabBar.Tab.CloseOther}" <MenuItem Header="{DynamicResource Text.PageTabBar.Tab.CloseOther}"
Command="{Binding #me.((vm:Launcher)DataContext).CloseOtherTabs}" Command="{Binding #me.((vm:Launcher)DataContext).CloseOtherTabs}"/>
CommandParameter="{Binding}"/>
<MenuItem Header="{DynamicResource Text.PageTabBar.Tab.CloseRight}" <MenuItem Header="{DynamicResource Text.PageTabBar.Tab.CloseRight}"
Command="{Binding #me.((vm:Launcher)DataContext).CloseRightTabs}" Command="{Binding #me.((vm:Launcher)DataContext).CloseRightTabs}"/>
CommandParameter="{Binding}"/>
<MenuItem Header="-" IsVisible="{Binding Node.IsRepository}"/> <MenuItem Header="-" IsVisible="{Binding Node.IsRepository}"/>
<MenuItem IsVisible="{Binding Node.IsRepository}"> <MenuItem IsVisible="{Binding Node.IsRepository}">
<MenuItem.Header> <MenuItem.Header>
@ -210,15 +208,11 @@
</ToolTip.Tip> </ToolTip.Tip>
<Path Width="8" Height="8" Data="{StaticResource Icons.Window.Close}"/> <Path Width="8" Height="8" Data="{StaticResource Icons.Window.Close}"/>
</Button> </Button>
<Rectangle Grid.Column="2" Width=".5" Height="20" HorizontalAlignment="Right" VerticalAlignment="Center" Fill="{DynamicResource Brush.FG2}"> <Rectangle Grid.Column="2"
<Rectangle.IsVisible> Width=".5" Height="20"
<MultiBinding Converter="{x:Static c:LauncherPageConverters.ToTabSeperatorVisible}"> HorizontalAlignment="Right" VerticalAlignment="Center"
<Binding/> Fill="{DynamicResource Brush.FG2}"
<Binding Path="$parent[ListBox].SelectedItem"/> IsVisible="{Binding IsTabSplitterVisible}"/>
<Binding Path="#me.((vm:Launcher)DataContext).Pages"/>
</MultiBinding>
</Rectangle.IsVisible>
</Rectangle>
</Grid> </Grid>
</Border> </Border>
</DataTemplate> </DataTemplate>