diff --git a/src/UniGetUI.Avalonia/Assets/Styles/Styles.Common.axaml b/src/UniGetUI.Avalonia/Assets/Styles/Styles.Common.axaml index 00e7acbae2..b001dc1cc8 100644 --- a/src/UniGetUI.Avalonia/Assets/Styles/Styles.Common.axaml +++ b/src/UniGetUI.Avalonia/Assets/Styles/Styles.Common.axaml @@ -495,6 +495,39 @@ + + + + + - - - diff --git a/src/UniGetUI.Avalonia/Views/SoftwarePages/SoftwareCatalogPage.axaml b/src/UniGetUI.Avalonia/Views/SoftwarePages/SoftwareCatalogPage.axaml index 73579cf2e3..4187f29c79 100644 --- a/src/UniGetUI.Avalonia/Views/SoftwarePages/SoftwareCatalogPage.axaml +++ b/src/UniGetUI.Avalonia/Views/SoftwarePages/SoftwareCatalogPage.axaml @@ -25,16 +25,61 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + - - + + + + + + - + @@ -93,19 +162,22 @@ - - - - - - - - - - + + + + + + + - + - + - - - - - - + + + + + @@ -338,11 +423,16 @@ + - - - + diff --git a/src/UniGetUI.Avalonia/Views/SoftwarePages/SoftwareCatalogPage.axaml.cs b/src/UniGetUI.Avalonia/Views/SoftwarePages/SoftwareCatalogPage.axaml.cs index 3b26bef9f8..c5049ad177 100644 --- a/src/UniGetUI.Avalonia/Views/SoftwarePages/SoftwareCatalogPage.axaml.cs +++ b/src/UniGetUI.Avalonia/Views/SoftwarePages/SoftwareCatalogPage.axaml.cs @@ -1,6 +1,10 @@ +using System.ComponentModel; +using Avalonia; using Avalonia.Controls; using Avalonia.Threading; +using UniGetUI.Avalonia.Extensions; using UniGetUI.Avalonia.ViewModels.Pages; +using UniGetUI.Core.SettingsEngine; using UniGetUI.Core.Tools; using UniGetUI.PackageEngine.PackageLoader; @@ -8,9 +12,12 @@ namespace UniGetUI.Avalonia.Views.Pages; public partial class SoftwareCatalogPage : UserControl, IEnterLeaveListener, ISearchBoxPage { + private const string FilterPaneWidthKey = "SoftwareCatalog"; + private const double DefaultFilterPaneWidth = 220; private readonly SoftwareCatalogViewModel _viewModel = new(); private readonly DispatcherTimer _stateTimer = new() { Interval = TimeSpan.FromSeconds(2) }; private InstalledPackagesLoader? _loader; + private double _savedFilterPaneWidth = DefaultFilterPaneWidth; public string QueryBackup { @@ -27,6 +34,47 @@ public SoftwareCatalogPage() InitializeComponent(); DataContext = _viewModel; _stateTimer.Tick += (_, _) => _viewModel.UpdateStates(); + + // Restore the per-page filter pane width from settings. + var savedWidth = Settings.GetDictionaryItem(Settings.K.SidepanelWidths, FilterPaneWidthKey); + if (savedWidth >= 100) _savedFilterPaneWidth = savedWidth; + _viewModel.TrackedFilterPaneWidth = _savedFilterPaneWidth; + + // Persist the dragged width and snap the pane closed when it is dragged below the minimum. + FilteringPanel.ColumnDefinitions[0] + .GetObservable(ColumnDefinition.WidthProperty) + .SubscribeValue(width => + { + if (!_viewModel.IsFilterPaneOpen) return; + if (width.IsAbsolute && width.Value >= 100) + { + _savedFilterPaneWidth = width.Value; + _viewModel.TrackedFilterPaneWidth = width.Value; + Settings.SetDictionaryItem(Settings.K.SidepanelWidths, FilterPaneWidthKey, (int)width.Value); + } + else if (width.IsAbsolute && width.Value < 100) + { + _savedFilterPaneWidth = DefaultFilterPaneWidth; + _viewModel.TrackedFilterPaneWidth = DefaultFilterPaneWidth; + _viewModel.IsFilterPaneOpen = false; + } + }); + + _viewModel.PropertyChanged += OnViewModelPropertyChanged; + UpdateFilterPaneColumn(_viewModel.IsFilterPaneOpen); + } + + private void OnViewModelPropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == nameof(SoftwareCatalogViewModel.IsFilterPaneOpen)) + UpdateFilterPaneColumn(_viewModel.IsFilterPaneOpen); + } + + private void UpdateFilterPaneColumn(bool open) + { + if (FilteringPanel.ColumnDefinitions.Count < 2) return; + FilteringPanel.ColumnDefinitions[0].Width = open ? new GridLength(_savedFilterPaneWidth) : new GridLength(0); + FilteringPanel.ColumnDefinitions[1].Width = open ? new GridLength(12) : new GridLength(0); } public void OnEnter()