diff --git a/YMouseButtonControl.Core.Tests/ViewModels/ProfilesListViewModelTests.cs b/YMouseButtonControl.Core.Tests/ViewModels/ProfilesListViewModelTests.cs index 9199815..b0754dc 100644 --- a/YMouseButtonControl.Core.Tests/ViewModels/ProfilesListViewModelTests.cs +++ b/YMouseButtonControl.Core.Tests/ViewModels/ProfilesListViewModelTests.cs @@ -14,6 +14,7 @@ using YMouseButtonControl.Core.ViewModels.Implementations.Dialogs; using YMouseButtonControl.Core.ViewModels.Interfaces; using YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; +using YMouseButtonControl.Core.ViewModels.ProfilesList; using YMouseButtonControl.Core.ViewModels.ProfilesList.Features.Add; using YMouseButtonControl.DataAccess.LiteDb; diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/Setting.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/Setting.cs index 4ee3aa3..d4ed463 100644 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/Setting.cs +++ b/YMouseButtonControl.Core/DataAccess/Models/Implementations/Setting.cs @@ -1,12 +1,20 @@ using System; +using ReactiveUI; namespace YMouseButtonControl.Core.DataAccess.Models.Implementations; -public class Setting : IEquatable +public class Setting : ReactiveObject, IEquatable { + private string? _value; + public int Id { get; set; } public required string Name { get; set; } - public string? Value { get; set; } + + public string? Value + { + get => _value; + set => this.RaiseAndSetIfChanged(ref _value, value); + } public bool Equals(Setting? other) { diff --git a/YMouseButtonControl.Core/DataAccess/Repositories/IRepository.cs b/YMouseButtonControl.Core/DataAccess/Repositories/IRepository.cs index e26e947..5622e9e 100644 --- a/YMouseButtonControl.Core/DataAccess/Repositories/IRepository.cs +++ b/YMouseButtonControl.Core/DataAccess/Repositories/IRepository.cs @@ -5,6 +5,7 @@ namespace YMouseButtonControl.Core.DataAccess.Repositories; public interface IRepository { T GetById(string id); + T GetById(int id); IEnumerable GetAll(); void Add(T entity); void Update(string id, T entity); diff --git a/YMouseButtonControl.Core/Profiles/Implementations/SettingsService.cs b/YMouseButtonControl.Core/Profiles/Implementations/SettingsService.cs index 5ebf79d..59fab38 100644 --- a/YMouseButtonControl.Core/Profiles/Implementations/SettingsService.cs +++ b/YMouseButtonControl.Core/Profiles/Implementations/SettingsService.cs @@ -1,9 +1,11 @@ using System; using System.Linq; +using System.Xml.Linq; using DynamicData; using ReactiveUI; using YMouseButtonControl.Core.DataAccess.Models.Implementations; using YMouseButtonControl.Core.DataAccess.UnitOfWork; +using YMouseButtonControl.Core.Profiles.Interfaces; namespace YMouseButtonControl.Core.Profiles.Implementations; @@ -33,7 +35,19 @@ public bool IsUnsavedChanges() public Setting? GetSetting(string name) { - return _settings.Items.FirstOrDefault(x => x.Name == name); + using var unitOfWork = _unitOfWorkFactory.Create(); + var repository = unitOfWork.GetRepository(); + return repository.GetAll().ToList().FirstOrDefault(x => x.Name == name); + } + + public Setting UpdateSetting(int id, string value) + { + using var unitOfWork = _unitOfWorkFactory.Create(); + var repository = unitOfWork.GetRepository(); + var dbSetting = repository.GetById(id); + dbSetting.Value = value; + repository.ApplyAction([dbSetting]); + return dbSetting; } private void LoadSettingsFromDb() diff --git a/YMouseButtonControl.Core/Profiles/Interfaces/ISettingsService.cs b/YMouseButtonControl.Core/Profiles/Interfaces/ISettingsService.cs index f037438..29024c8 100644 --- a/YMouseButtonControl.Core/Profiles/Interfaces/ISettingsService.cs +++ b/YMouseButtonControl.Core/Profiles/Interfaces/ISettingsService.cs @@ -2,11 +2,12 @@ using DynamicData; using YMouseButtonControl.Core.DataAccess.Models.Implementations; -namespace YMouseButtonControl.Core.Profiles.Implementations; +namespace YMouseButtonControl.Core.Profiles.Interfaces; public interface ISettingsService { IObservable> Connect(); bool IsUnsavedChanges(); Setting? GetSetting(string name); + Setting UpdateSetting(int id, string value); } diff --git a/YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/GlobalSettingsDialogViewModel.cs b/YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/GlobalSettingsDialogViewModel.cs index 405598f..02caeec 100644 --- a/YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/GlobalSettingsDialogViewModel.cs +++ b/YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/GlobalSettingsDialogViewModel.cs @@ -1,22 +1,48 @@ using System; +using System.Reactive; +using System.Reactive.Linq; using ReactiveUI; using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.Profiles.Implementations; +using YMouseButtonControl.Core.Profiles.Interfaces; +using YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; namespace YMouseButtonControl.Core.ViewModels.Implementations.Dialogs; public class GlobalSettingsDialogViewModel : DialogBase, IGlobalSettingsDialogViewModel { - private readonly ISettingsService _settingsService; private Setting _startMinimized; + private readonly ObservableAsPropertyHelper? _applyIsExec; public GlobalSettingsDialogViewModel(ISettingsService settingsService) { - _settingsService = settingsService; - _startMinimized = - _settingsService.GetSetting("StartMinimized") + settingsService.GetSetting("StartMinimized") ?? throw new Exception($"Error retrieving StartMinimized setting"); + + var startMinimizedChanged = this.WhenAnyValue( + x => x.StartMinimized.Value, + selector: val => + { + var curVal = settingsService.GetSetting("StartMinimized"); + if (curVal is null) + { + return true; + } + + return curVal.Value != val; + } + ); + + var applyIsExecObs = this.WhenAnyValue(x => x.AppIsExec); + var canSave = startMinimizedChanged.Merge(applyIsExecObs); + ApplyCommand = ReactiveCommand.Create( + () => + { + settingsService.UpdateSetting(StartMinimized.Id, StartMinimized.Value!); + }, + canSave + ); + _applyIsExec = ApplyCommand.IsExecuting.ToProperty(this, x => x.AppIsExec); } public Setting StartMinimized @@ -24,4 +50,8 @@ public Setting StartMinimized get => _startMinimized; set => this.RaiseAndSetIfChanged(ref _startMinimized, value); } + + public ReactiveCommand ApplyCommand { get; init; } + + public bool AppIsExec => _applyIsExec?.Value ?? false; } diff --git a/YMouseButtonControl.Core/ViewModels/Interfaces/Dialogs/IGlobalSettingsDialogViewModel.cs b/YMouseButtonControl.Core/ViewModels/Interfaces/Dialogs/IGlobalSettingsDialogViewModel.cs index ef49456..f0b0294 100644 --- a/YMouseButtonControl.Core/ViewModels/Interfaces/Dialogs/IGlobalSettingsDialogViewModel.cs +++ b/YMouseButtonControl.Core/ViewModels/Interfaces/Dialogs/IGlobalSettingsDialogViewModel.cs @@ -1,6 +1,6 @@ using YMouseButtonControl.Core.DataAccess.Models.Implementations; -namespace YMouseButtonControl.Core.ViewModels.Implementations.Dialogs; +namespace YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; public interface IGlobalSettingsDialogViewModel { diff --git a/YMouseButtonControl.Core/ViewModels/MainWindow/IMainWindowViewModel.cs b/YMouseButtonControl.Core/ViewModels/MainWindow/IMainWindowViewModel.cs index be99603..5e1d129 100644 --- a/YMouseButtonControl.Core/ViewModels/MainWindow/IMainWindowViewModel.cs +++ b/YMouseButtonControl.Core/ViewModels/MainWindow/IMainWindowViewModel.cs @@ -1,6 +1,8 @@ using System.Reactive; using ReactiveUI; +using YMouseButtonControl.Core.ViewModels.Implementations.Dialogs; using YMouseButtonControl.Core.ViewModels.Interfaces; +using YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; namespace YMouseButtonControl.Core.ViewModels.MainWindow; @@ -12,6 +14,6 @@ public interface IMainWindowViewModel ReactiveCommand ApplyCommand { get; } ReactiveCommand CloseCommand { get; } ReactiveCommand SettingsCommand { get; } - Interaction ShowSettingsDialogInteraction { get; } + Interaction ShowSettingsDialogInteraction { get; } string? ProfileName { get; set; } } diff --git a/YMouseButtonControl.Core/ViewModels/MainWindow/MainWindowViewModel.cs b/YMouseButtonControl.Core/ViewModels/MainWindow/MainWindowViewModel.cs index bab5088..2310bdf 100644 --- a/YMouseButtonControl.Core/ViewModels/MainWindow/MainWindowViewModel.cs +++ b/YMouseButtonControl.Core/ViewModels/MainWindow/MainWindowViewModel.cs @@ -9,7 +9,9 @@ using YMouseButtonControl.Core.DataAccess.Models.Implementations; using YMouseButtonControl.Core.Profiles.Interfaces; using YMouseButtonControl.Core.ViewModels.Implementations; +using YMouseButtonControl.Core.ViewModels.Implementations.Dialogs; using YMouseButtonControl.Core.ViewModels.Interfaces; +using YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; using YMouseButtonControl.Core.ViewModels.MainWindow.Features.Apply; namespace YMouseButtonControl.Core.ViewModels.MainWindow; @@ -20,6 +22,7 @@ public class MainWindowViewModel : ViewModelBase, IMainWindowViewModel private readonly IProfilesService _ps; private readonly IProfilesListViewModel _profilesListViewModel; + private readonly IGlobalSettingsDialogViewModel _globalSettingsDialogViewModel; private string? _profileName; #endregion @@ -31,15 +34,17 @@ public MainWindowViewModel( ILayerViewModel layerViewModel, IProfilesListViewModel profilesListViewModel, IProfilesInformationViewModel profilesInformationViewModel, + IGlobalSettingsDialogViewModel globalSettingsDialogViewModel, IApply apply ) { _profilesListViewModel = profilesListViewModel; + _globalSettingsDialogViewModel = globalSettingsDialogViewModel; _ps = ps; LayerViewModel = layerViewModel; ProfilesInformationViewModel = profilesInformationViewModel; SettingsCommand = ReactiveCommand.CreateFromTask(ShowSettingsDialogAsync); - ShowSettingsDialogInteraction = new Interaction(); + ShowSettingsDialogInteraction = new Interaction(); CloseCommand = ReactiveCommand.Create(() => { if ( @@ -75,7 +80,7 @@ is IClassicDesktopStyleApplicationLifetime lifetime public ReactiveCommand CloseCommand { get; } public ReactiveCommand SettingsCommand { get; } - public Interaction ShowSettingsDialogInteraction { get; } + public Interaction ShowSettingsDialogInteraction { get; } public string? ProfileName { @@ -87,7 +92,7 @@ public string? ProfileName private async Task ShowSettingsDialogAsync() { - await ShowSettingsDialogInteraction.Handle(Unit.Default); + await ShowSettingsDialogInteraction.Handle(_globalSettingsDialogViewModel); } private void OnProfileChanged(Profile profile) => ProfileName = profile.Name; diff --git a/YMouseButtonControl.Core/ViewModels/ProfilesList/ProfilesListViewModel.cs b/YMouseButtonControl.Core/ViewModels/ProfilesList/ProfilesListViewModel.cs index 253e5d9..0dd917c 100644 --- a/YMouseButtonControl.Core/ViewModels/ProfilesList/ProfilesListViewModel.cs +++ b/YMouseButtonControl.Core/ViewModels/ProfilesList/ProfilesListViewModel.cs @@ -7,11 +7,12 @@ using ReactiveUI; using YMouseButtonControl.Core.DataAccess.Models.Implementations; using YMouseButtonControl.Core.Profiles.Interfaces; +using YMouseButtonControl.Core.ViewModels.Implementations; using YMouseButtonControl.Core.ViewModels.Interfaces; using YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; using YMouseButtonControl.Core.ViewModels.ProfilesList.Features.Add; -namespace YMouseButtonControl.Core.ViewModels.Implementations; +namespace YMouseButtonControl.Core.ViewModels.ProfilesList; public class ProfilesListViewModel : ViewModelBase, IProfilesListViewModel { diff --git a/YMouseButtonControl.DataAccess.LiteDb/Repository.cs b/YMouseButtonControl.DataAccess.LiteDb/Repository.cs index 2b250f0..0e2512d 100644 --- a/YMouseButtonControl.DataAccess.LiteDb/Repository.cs +++ b/YMouseButtonControl.DataAccess.LiteDb/Repository.cs @@ -9,6 +9,8 @@ public class Repository(ILiteCollection collection) : IRepository { public T GetById(string id) => collection.FindById(id); + public T GetById(int id) => collection.FindById(id); + public IEnumerable GetAll() => collection.FindAll(); public void Add(T entity) => collection.Insert(entity); diff --git a/YMouseButtonControl/App.axaml.cs b/YMouseButtonControl/App.axaml.cs index 33e8ecd..3c63f06 100644 --- a/YMouseButtonControl/App.axaml.cs +++ b/YMouseButtonControl/App.axaml.cs @@ -12,6 +12,7 @@ using YMouseButtonControl.Configuration; using YMouseButtonControl.Core; using YMouseButtonControl.Core.Profiles.Implementations; +using YMouseButtonControl.Core.Profiles.Interfaces; using YMouseButtonControl.Core.Services.BackgroundTasks; using YMouseButtonControl.Core.ViewModels.Interfaces; using YMouseButtonControl.Core.ViewModels.MainWindow; diff --git a/YMouseButtonControl/Converters/SettingValueConverter.cs b/YMouseButtonControl/Converters/SettingValueConverter.cs new file mode 100644 index 0000000..086bea7 --- /dev/null +++ b/YMouseButtonControl/Converters/SettingValueConverter.cs @@ -0,0 +1,32 @@ +using System; +using System.Globalization; +using Avalonia.Data.Converters; + +namespace YMouseButtonControl.Converters; + +public class SettingValueConverter : IValueConverter +{ + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + if (value is not string) + { + return null; + } + + if (value is not string valStr) + { + return null; + } + return bool.Parse(valStr); + } + + public object? ConvertBack( + object? value, + Type targetType, + object? parameter, + CultureInfo culture + ) + { + return value?.ToString(); + } +} diff --git a/YMouseButtonControl/DependencyInjection/ViewModelsBootstrapper.cs b/YMouseButtonControl/DependencyInjection/ViewModelsBootstrapper.cs index a9af509..65c436c 100644 --- a/YMouseButtonControl/DependencyInjection/ViewModelsBootstrapper.cs +++ b/YMouseButtonControl/DependencyInjection/ViewModelsBootstrapper.cs @@ -4,6 +4,7 @@ using YMouseButtonControl.Core.ViewModels.Interfaces; using YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; using YMouseButtonControl.Core.ViewModels.MainWindow; +using YMouseButtonControl.Core.ViewModels.ProfilesList; using YMouseButtonControl.Core.ViewModels.Services; namespace YMouseButtonControl.DependencyInjection; diff --git a/YMouseButtonControl/Views/Dialogs/GlobalSettingsDialog.axaml b/YMouseButtonControl/Views/Dialogs/GlobalSettingsDialog.axaml index 242ccd1..f8e893c 100644 --- a/YMouseButtonControl/Views/Dialogs/GlobalSettingsDialog.axaml +++ b/YMouseButtonControl/Views/Dialogs/GlobalSettingsDialog.axaml @@ -3,14 +3,25 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:dialogs="clr-namespace:YMouseButtonControl.Core.ViewModels.Implementations.Dialogs;assembly=YMouseButtonControl.Core" + xmlns:converters="clr-namespace:YMouseButtonControl.Converters" WindowStartupLocation="CenterOwner" Width="800" Height="600" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="YMouseButtonControl.Views.Dialogs.GlobalSettingsDialog" Title="Global Settings"> - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/YMouseButtonControl/Views/Dialogs/GlobalSettingsDialog.axaml.cs b/YMouseButtonControl/Views/Dialogs/GlobalSettingsDialog.axaml.cs index 0312fa0..58ee608 100644 --- a/YMouseButtonControl/Views/Dialogs/GlobalSettingsDialog.axaml.cs +++ b/YMouseButtonControl/Views/Dialogs/GlobalSettingsDialog.axaml.cs @@ -1,5 +1,6 @@ using Avalonia; using Avalonia.Controls; +using Avalonia.Interactivity; using Avalonia.Markup.Xaml; namespace YMouseButtonControl.Views.Dialogs; @@ -10,4 +11,9 @@ public GlobalSettingsDialog() { InitializeComponent(); } + + private void Cancel_OnClick(object? sender, RoutedEventArgs e) + { + Close(); + } } diff --git a/YMouseButtonControl/Views/MainWindow.axaml.cs b/YMouseButtonControl/Views/MainWindow.axaml.cs index 1447320..601b817 100644 --- a/YMouseButtonControl/Views/MainWindow.axaml.cs +++ b/YMouseButtonControl/Views/MainWindow.axaml.cs @@ -4,6 +4,7 @@ using Avalonia.ReactiveUI; using ReactiveUI; using YMouseButtonControl.Core.ViewModels.Implementations.Dialogs; +using YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; using YMouseButtonControl.Core.ViewModels.MainWindow; using YMouseButtonControl.Core.Views; using YMouseButtonControl.Views.Dialogs; @@ -33,7 +34,9 @@ public MainWindow() #endif } - private async Task ShowGlobalSettingsDialog(IInteractionContext context) + private async Task ShowGlobalSettingsDialog( + IInteractionContext context + ) { var dialog = new GlobalSettingsDialog { DataContext = context.Input }; await dialog.ShowDialog( diff --git a/YMouseButtonControl/Views/ProfilesListView.axaml b/YMouseButtonControl/Views/ProfilesListView.axaml index c91e9e6..77b5f7f 100644 --- a/YMouseButtonControl/Views/ProfilesListView.axaml +++ b/YMouseButtonControl/Views/ProfilesListView.axaml @@ -4,6 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:implementations="clr-namespace:YMouseButtonControl.Core.ViewModels.Implementations;assembly=YMouseButtonControl.Core" xmlns:models="clr-namespace:YMouseButtonControl.Core.DataAccess.Models.Implementations;assembly=YMouseButtonControl.Core" + xmlns:profilesList="clr-namespace:YMouseButtonControl.Core.ViewModels.ProfilesList;assembly=YMouseButtonControl.Core" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" @@ -12,7 +13,7 @@ x:Class="YMouseButtonControl.Views.ProfilesListView"> - + diff --git a/YMouseButtonControl/Views/ProfilesListView.axaml.cs b/YMouseButtonControl/Views/ProfilesListView.axaml.cs index f5df0dc..9f21a3e 100644 --- a/YMouseButtonControl/Views/ProfilesListView.axaml.cs +++ b/YMouseButtonControl/Views/ProfilesListView.axaml.cs @@ -9,6 +9,7 @@ using YMouseButtonControl.Core.DataAccess.Models.Implementations; using YMouseButtonControl.Core.ViewModels.Implementations; using YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; +using YMouseButtonControl.Core.ViewModels.ProfilesList; using YMouseButtonControl.Views.Dialogs; namespace YMouseButtonControl.Views;