Improve EditQuickFilters dialog reordering behavior

This commit is contained in:
MBucari 2025-07-25 14:23:14 -06:00
parent c98c7c095a
commit accedeb1b1
2 changed files with 73 additions and 41 deletions

View File

@ -24,9 +24,8 @@
CanUserSortColumns="False"
AutoGenerateColumns="False"
IsReadOnly="False"
ItemsSource="{Binding Filters}"
ItemsSource="{CompiledBinding Filters}"
GridLinesVisibility="All">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Delete">
@ -38,7 +37,7 @@
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
IsEnabled="{Binding !IsDefault}"
IsEnabled="{CompiledBinding !IsDefault}"
Click="DeleteButton_Clicked" />
</DataTemplate>
@ -48,14 +47,13 @@
<DataGridTextColumn
Width="*"
IsReadOnly="False"
Binding="{Binding Name, Mode=TwoWay}"
Binding="{CompiledBinding Name, Mode=TwoWay}"
Header="Name"/>
<DataGridTextColumn
Width="*"
IsReadOnly="False"
Binding="{Binding FilterString, Mode=TwoWay}"
Binding="{CompiledBinding FilterString, Mode=TwoWay}"
Header="Filter"/>
<DataGridTemplateColumn Header="Move&#xa;Up">
@ -67,16 +65,19 @@
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
IsEnabled="{Binding !IsDefault}"
ToolTip.Tip="Export account authorization to audible-cli"
Click="MoveUpButton_Clicked" />
Click="MoveUpButton_Clicked">
<Button.IsEnabled>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<CompiledBinding Path="!IsTop" />
<CompiledBinding Path="!IsDefault" />
</MultiBinding>
</Button.IsEnabled>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Move&#xa;Down">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
@ -86,15 +87,18 @@
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
IsEnabled="{Binding !IsDefault}"
ToolTip.Tip="Export account authorization to audible-cli"
Click="MoveDownButton_Clicked" />
Click="MoveDownButton_Clicked">
<Button.IsEnabled>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<CompiledBinding Path="!IsBottom" />
<CompiledBinding Path="!IsDefault" />
</MultiBinding>
</Button.IsEnabled>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<Grid

View File

@ -1,15 +1,15 @@
using AudibleUtilities;
using Avalonia.Collections;
using Avalonia.Controls;
using LibationFileManager;
using ReactiveUI;
using System.Collections.ObjectModel;
using System.Linq;
namespace LibationAvalonia.Dialogs
{
public partial class EditQuickFilters : DialogWindow
{
public ObservableCollection<Filter> Filters { get; } = new();
public AvaloniaList<Filter> Filters { get; } = new();
public class Filter : ViewModels.ViewModelBase
{
@ -17,10 +17,7 @@ namespace LibationAvalonia.Dialogs
public string Name
{
get => _name;
set
{
this.RaiseAndSetIfChanged(ref _name, value);
}
set => this.RaiseAndSetIfChanged(ref _name, value);
}
private string _filterString;
@ -35,6 +32,10 @@ namespace LibationAvalonia.Dialogs
}
}
public bool IsDefault { get; private set; } = true;
private bool _isTop;
private bool _isBottom;
public bool IsTop { get => _isTop; set => this.RaiseAndSetIfChanged(ref _isTop, value); }
public bool IsBottom { get => _isBottom; set => this.RaiseAndSetIfChanged(ref _isBottom, value); }
public QuickFilters.NamedFilter AsNamedFilter() => new(FilterString, Name);
@ -44,12 +45,12 @@ namespace LibationAvalonia.Dialogs
InitializeComponent();
if (Design.IsDesignMode)
{
Filters = new ObservableCollection<Filter>([
new Filter { Name = "Filter 1", FilterString = "[filter1 string]" },
Filters = [
new Filter { Name = "Filter 1", FilterString = "[filter1 string]", IsTop = true },
new Filter { Name = "Filter 2", FilterString = "[filter2 string]" },
new Filter { Name = "Filter 3", FilterString = "[filter3 string]" },
new Filter { Name = "Filter 4", FilterString = "[filter4 string]" }
]);
new Filter { Name = "Filter 4", FilterString = "[filter4 string]", IsBottom = true },
new Filter()];
DataContext = this;
return;
}
@ -65,6 +66,8 @@ namespace LibationAvalonia.Dialogs
ControlToFocusOnShow = this.FindControl<Button>(nameof(saveBtn));
var allFilters = QuickFilters.Filters.Select(f => new Filter { FilterString = f.Filter, Name = f.Name }).ToList();
allFilters[0].IsTop = true;
allFilters[^1].IsBottom = true;
allFilters.Add(new Filter());
foreach (var f in allFilters)
@ -81,6 +84,7 @@ namespace LibationAvalonia.Dialogs
var newBlank = new Filter();
newBlank.PropertyChanged += Filter_PropertyChanged;
Filters.Insert(Filters.Count, newBlank);
ReIndexFilters();
}
protected override void SaveAndClose()
@ -98,30 +102,54 @@ namespace LibationAvalonia.Dialogs
filter.PropertyChanged -= Filter_PropertyChanged;
Filters.Remove(filter);
ReIndexFilters();
}
}
public void MoveUpButton_Clicked(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{
if (e.Source is Button btn && btn.DataContext is Filter filter)
{
var index = Filters.IndexOf(filter);
if (index < 1) return;
if (e.Source is not Button btn || btn.DataContext is not Filter filter || filter.IsDefault)
return;
Filters.Remove(filter);
Filters.Insert(index - 1, filter);
}
var oldIndex = Filters.IndexOf(filter);
if (oldIndex < 1) return;
var filterCount = Filters.Count(f => !f.IsDefault);
MoveFilter(oldIndex, oldIndex - 1, filterCount);
}
public void MoveDownButton_Clicked(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{
if (e.Source is Button btn && btn.DataContext is Filter filter)
{
var index = Filters.IndexOf(filter);
if (index >= Filters.Count - 2) return;
if (e.Source is not Button btn || btn.DataContext is not Filter filter || filter.IsDefault)
return;
Filters.Remove(filter);
Filters.Insert(index + 1, filter);
var filterCount = Filters.Count(f => !f.IsDefault);
var oldIndex = Filters.IndexOf(filter);
if (oldIndex >= filterCount - 1) return;
MoveFilter(oldIndex, oldIndex + 1, filterCount);
}
private void MoveFilter(int oldIndex, int newIndex, int filterCount)
{
var filter = Filters[oldIndex];
Filters.RemoveAt(oldIndex);
Filters.Insert(newIndex, filter);
Filters[oldIndex].IsTop = oldIndex == 0;
Filters[newIndex].IsTop = newIndex == 0;
Filters[newIndex].IsBottom = newIndex == filterCount - 1;
Filters[oldIndex].IsBottom = oldIndex == filterCount - 1;
}
private void ReIndexFilters()
{
var filterCount = Filters.Count(f => !f.IsDefault);
for (int i = filterCount - 1; i >= 0; i--)
{
Filters[i].IsTop = i == 0;
Filters[i].IsBottom = i == filterCount - 1;
}
}
}