diff --git a/Source/LibationWinForms/AvaloniaUI/Controls/DirectorySelectControl.axaml b/Source/LibationWinForms/AvaloniaUI/Controls/DirectorySelectControl.axaml new file mode 100644 index 00000000..cc93bafa --- /dev/null +++ b/Source/LibationWinForms/AvaloniaUI/Controls/DirectorySelectControl.axaml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/LibationWinForms/AvaloniaUI/Controls/DirectorySelectControl.axaml.cs b/Source/LibationWinForms/AvaloniaUI/Controls/DirectorySelectControl.axaml.cs new file mode 100644 index 00000000..ded5f227 --- /dev/null +++ b/Source/LibationWinForms/AvaloniaUI/Controls/DirectorySelectControl.axaml.cs @@ -0,0 +1,146 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; +using Dinah.Core; +using LibationFileManager; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using ReactiveUI; +using Avalonia.Controls.Primitives; +using System.Collections; +using Avalonia.Data.Converters; +using System; +using System.Globalization; +using Avalonia.Data; + +namespace LibationWinForms.AvaloniaUI.Controls +{ + public class TextCaseConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is Configuration.KnownDirectories dir) + { + + } + return new BindingNotification(new InvalidCastException(), BindingErrorType.Error); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } + public partial class DirectorySelectControl : TemplatedControl + { + private static readonly List defaultList = new List() + { + Configuration.KnownDirectories.WinTemp, + Configuration.KnownDirectories.UserProfile, + Configuration.KnownDirectories.AppDir, + Configuration.KnownDirectories.MyDocs, + Configuration.KnownDirectories.LibationFiles + }; + public static readonly StyledProperty SelectedirectoryProperty = + AvaloniaProperty.Register(nameof(Selectedirectory), defaultList[0]); + + public static readonly StyledProperty> KnownDirectoriesProperty = + AvaloniaProperty.Register>(nameof(KnownDirectories), defaultList); + + public static readonly StyledProperty SubdirectoryProperty = + AvaloniaProperty.Register(nameof(Subdirectory), "subdir"); + + DirectorySelectViewModel DirectorySelect { get; } = new(); + public DirectorySelectControl() + { + InitializeComponent(); + } + + protected override void OnInitialized() + { + DirectorySelect.Directories.Clear(); + + int insertIndex = 0; + foreach (var kd in KnownDirectories.Distinct()) + DirectorySelect.Directories.Insert(insertIndex++, new(this, kd)); + + DataContext = DirectorySelect; + base.OnInitialized(); + } + + public List KnownDirectories + { + get { return GetValue(KnownDirectoriesProperty); } + set + { + SetValue(KnownDirectoriesProperty, value); + //SetDirectoryItems(KnownDirectories); + } + } + + + public Configuration.KnownDirectories? Selectedirectory + { + get { return GetValue(SelectedirectoryProperty); } + set + { + SetValue(SelectedirectoryProperty, value); + + if (value is null or Configuration.KnownDirectories.None) + return; + + // set default + var item = DirectorySelect.Directories.SingleOrDefault(item => item.Value == value.Value); + if (item is null) + return; + + DirectorySelect.SelectedDirectory = item; + } + } + + + public string? Subdirectory + { + get { return GetValue(SubdirectoryProperty); } + set + { + SetValue(SubdirectoryProperty, value); + } + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + } + + public class DirectorySelectViewModel : ViewModels.ViewModelBase + { + public class DirectoryComboBoxItem + { + private readonly DirectorySelectControl _parentControl; + public string Description { get; } + public Configuration.KnownDirectories Value { get; } + + public string FullPath => AddSubDirectoryToPath(Configuration.GetKnownDirectoryPath(Value)); + + /// Displaying relative paths is confusing. UI should display absolute equivalent + public string UiDisplayPath => Value == Configuration.KnownDirectories.AppDir ? AddSubDirectoryToPath(Configuration.AppDir_Absolute) : FullPath; + + public DirectoryComboBoxItem(DirectorySelectControl parentControl, Configuration.KnownDirectories knownDirectory) + { + _parentControl = parentControl; + Value = knownDirectory; + Description = Value.GetDescription(); + } + + internal string AddSubDirectoryToPath(string path) => string.IsNullOrWhiteSpace(_parentControl.Subdirectory) ? path : System.IO.Path.Combine(path, _parentControl.Subdirectory); + + public override string ToString() => Description; + } + public ObservableCollection Directories { get; } = new(new()); + private DirectoryComboBoxItem _selectedDirectory; + public DirectoryComboBoxItem SelectedDirectory { get => _selectedDirectory; set => this.RaiseAndSetIfChanged(ref _selectedDirectory, value); } + } +} diff --git a/Source/LibationWinForms/AvaloniaUI/ViewModels/ProductsDisplayViewModel.cs b/Source/LibationWinForms/AvaloniaUI/ViewModels/ProductsDisplayViewModel.cs index d27209d5..f8b9fafd 100644 --- a/Source/LibationWinForms/AvaloniaUI/ViewModels/ProductsDisplayViewModel.cs +++ b/Source/LibationWinForms/AvaloniaUI/ViewModels/ProductsDisplayViewModel.cs @@ -86,10 +86,8 @@ namespace LibationWinForms.AvaloniaUI.ViewModels GridEntries = new GridEntryCollection(CreateGridEntries(dbBooks)); GridEntries.CollapseAll(); - int bookEntryCount = GridEntries.BookEntries().Count(); - InitialLoaded?.Invoke(this, EventArgs.Empty); - VisibleCountChanged?.Invoke(this, bookEntryCount); + VisibleCountChanged?.Invoke(this, GridEntries.BookEntries().Count()); RegisterCollectionChanged(); } @@ -112,7 +110,12 @@ namespace LibationWinForms.AvaloniaUI.ViewModels var existingSeriesEntries = GridEntries.AllItems().SeriesEntries().ToList(); - await Dispatcher.UIThread.InvokeAsync(() => GridEntries.ReplaceList(newEntries)); + await Dispatcher.UIThread.InvokeAsync(() => + { + GridEntries.ReplaceList(newEntries); + GridEntries.Filter = existingFilter; + ReSort(); + }); //We're replacing the list, so preserve usere's existing collapse/expand //state. When resetting a list, default state is open. @@ -122,11 +125,8 @@ namespace LibationWinForms.AvaloniaUI.ViewModels if (sEntry is SeriesEntry se && !series.Liberate.Expanded) await Dispatcher.UIThread.InvokeAsync(() => GridEntries.CollapseItem(se)); } - await Dispatcher.UIThread.InvokeAsync(() => - { - GridEntries.Filter = existingFilter; - ReSort(); - }); + + await Dispatcher.UIThread.InvokeAsync(() => VisibleCountChanged?.Invoke(this, GridEntries.BookEntries().Count())); } catch (Exception ex) { diff --git a/Source/LibationWinForms/AvaloniaUI/Views/Dialogs/AccountsDialog.axaml b/Source/LibationWinForms/AvaloniaUI/Views/Dialogs/AccountsDialog.axaml index 70e8ff87..0942c6f6 100644 --- a/Source/LibationWinForms/AvaloniaUI/Views/Dialogs/AccountsDialog.axaml +++ b/Source/LibationWinForms/AvaloniaUI/Views/Dialogs/AccountsDialog.axaml @@ -36,6 +36,7 @@ Width="60" Height="30" Content="X" + IsEnabled="{Binding !IsDefault}" Click="DeleteButton_Clicked" /> @@ -50,6 +51,7 @@ Width="60" Height="30" Content="Export" + IsEnabled="{Binding !IsDefault}" ToolTip.Tip="Export account authorization to audible-cli" Click="ExportButton_Clicked" /> @@ -71,13 +73,13 @@ - @@ -101,25 +103,11 @@ Margin="10" ColumnDefinitions="*,Auto" > - - -