diff --git a/.csharpierignore b/.csharpierignore new file mode 100644 index 0000000..7cd70ab --- /dev/null +++ b/.csharpierignore @@ -0,0 +1 @@ +**/Migrations/* \ No newline at end of file diff --git a/.gitignore b/.gitignore index 0059da0..e20f1a7 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs +*.db # Mono auto generated files mono_crash.* diff --git a/YMouseButtonControl.Core.Tests/BaseTest.cs b/YMouseButtonControl.Core.Tests/BaseTest.cs deleted file mode 100644 index f418a8e..0000000 --- a/YMouseButtonControl.Core.Tests/BaseTest.cs +++ /dev/null @@ -1,77 +0,0 @@ -using AutoFixture; -using AutoFixture.Kernel; -using YMouseButtonControl.Core.DataAccess.Configuration; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes; -using YMouseButtonControl.Core.Profiles.Implementations; -using YMouseButtonControl.DataAccess.LiteDb; - -namespace YMouseButtonControl.Core.Tests; - -public abstract class BaseTest -{ - private const string ConnStr = "tmp.db"; - - [SetUp] - public void Setup() - { - if (File.Exists(ConnStr)) - { - File.Delete(ConnStr); - } - } - - [TearDown] - public virtual void TearDown() - { - if (File.Exists(ConnStr)) - { - File.Delete(ConnStr); - } - } - - protected static ProfilesService GetProfilesService() - { - return GetProfilesService(Array.Empty()); - } - - /// - /// This method adds seed data to the database before it is read - /// - /// - /// - protected static ProfilesService GetProfilesService(IEnumerable? seedData) - { - var dbConfig = new DatabaseConfiguration { ConnectionString = $"Filename={ConnStr}" }; - var uowF = new LiteDbUnitOfWorkFactory(dbConfig); - - if (seedData is null) - return new ProfilesService(uowF); - - var uow = uowF.Create(); - var repo = uow.GetRepository(); - repo.ApplyAction(seedData); - uow.Dispose(); - return new ProfilesService(uowF); - } - - protected static List GetSeedData(int count = 10) - { - var fixture = new Fixture(); - fixture.Customize(c => c.With(p => p.IsDefault, false)); - fixture.Customizations.Add( - new TypeRelay( - typeof(DataAccess.Models.Interfaces.ISimulatedKeystrokesType), - typeof(StickyHoldActionType) - ) - ); - fixture.Customizations.Add( - new TypeRelay( - typeof(DataAccess.Models.Interfaces.IButtonMapping), - typeof(NothingMapping) - ) - ); - return fixture.CreateMany(count).ToList() - ?? throw new Exception("Error creating test profiles"); - } -} diff --git a/YMouseButtonControl.Core.Tests/KeyboardAndMouse/KeyboardSimulatorWorkerTests.cs b/YMouseButtonControl.Core.Tests/KeyboardAndMouse/KeyboardSimulatorWorkerTests.cs deleted file mode 100644 index f212fa9..0000000 --- a/YMouseButtonControl.Core.Tests/KeyboardAndMouse/KeyboardSimulatorWorkerTests.cs +++ /dev/null @@ -1,295 +0,0 @@ -using NSubstitute; -using SharpHook; -using SharpHook.Native; -using SharpHook.Reactive; -using SharpHook.Testing; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes; -using YMouseButtonControl.Core.KeyboardAndMouse; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; -using YMouseButtonControl.Core.Processes; -using YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations; -using YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations.SimulatedKeystrokesTypes; -using YMouseButtonControl.Services.Windows; -using RightClick = YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations.SimulatedMousePressTypes.RightClick; - -namespace YMouseButtonControl.Core.Tests.KeyboardAndMouse; - -[Platform("Win")] -public class KeyboardSimulatorWorkerTests : BaseTest -{ - [Test] - public void DefaultProfileSendsKeys() - { - var pf = GetProfilesService(GetSeedData()); - pf.CurrentProfile!.MouseButton3 = new SimulatedKeystrokes - { - SimulatedKeystrokesType = new MouseButtonPressedActionType(), - BlockOriginalMouseInput = true, - Keys = "wee", - }; - var testProvider = new TestProvider(); - using var hook = new SimpleReactiveGlobalHook(globalHookProvider: testProvider); - var curWinSvc = Substitute.For(); - var mouseListener = new MouseListener(hook, pf, curWinSvc); - var skipProfileSvc = Substitute.For(); - var eventSimulatorMock = Substitute.For(); - var eventSimulatorSvc = new EventSimulatorService(eventSimulatorMock); - var sut = new KeyboardSimulatorWorker( - pf, - mouseListener, - skipProfileSvc, - new AsMouseButtonPressedService(eventSimulatorSvc), - new AsMouseButtonReleasedService(eventSimulatorSvc), - new DuringMousePressAndReleaseService(eventSimulatorSvc), - new RepeatedWhileButtonDownService(eventSimulatorSvc), - new StickyRepeatService(eventSimulatorSvc), - new StickyHoldService(eventSimulatorSvc), - new RightClick(eventSimulatorSvc) - ); - - var evtDn = new UioHookEvent - { - Type = EventType.MousePressed, - Mouse = new MouseEventData { Button = MouseButton.Button3 }, - }; - // var evtUp = new UioHookEvent - // { - // Type = EventType.MouseReleased, - // Mouse = new MouseEventData { Button = MouseButton.Button3, } - // }; - RunHookAndWaitForStart(hook, testProvider); - - sut.Run(); - testProvider.PostEvent(ref evtDn); - // testProvider.PostEvent(ref evtUp); - - eventSimulatorMock.Received(1).SimulateKeyPress(Arg.Is(KeyCode.VcW)); - eventSimulatorMock.Received(2).SimulateKeyPress(Arg.Is(KeyCode.VcE)); - eventSimulatorMock.Received(2).SimulateKeyRelease(Arg.Is(KeyCode.VcE)); - eventSimulatorMock.Received(1).SimulateKeyRelease(Arg.Is(KeyCode.VcW)); - } - - [Test] - public void NonDefaultProfileSendsKeys() - { - var pf = GetProfilesService(GetSeedData()); - pf.Profiles.First(x => !x.IsDefault).MouseButton3 = new SimulatedKeystrokes - { - SimulatedKeystrokesType = new MouseButtonPressedActionType(), - BlockOriginalMouseInput = true, - Keys = "wee", - }; - var testProvider = new TestProvider(); - using var hook = new SimpleReactiveGlobalHook(globalHookProvider: testProvider); - var curWinSvc = Substitute.For(); - var mouseListener = new MouseListener(hook, pf, curWinSvc); - var skipProfileSvc = Substitute.For(); - var eventSimulatorMock = Substitute.For(); - var eventSimulatorSvc = new EventSimulatorService(eventSimulatorMock); - var sut = new KeyboardSimulatorWorker( - pf, - mouseListener, - skipProfileSvc, - new AsMouseButtonPressedService(eventSimulatorSvc), - new AsMouseButtonReleasedService(eventSimulatorSvc), - new DuringMousePressAndReleaseService(eventSimulatorSvc), - new RepeatedWhileButtonDownService(eventSimulatorSvc), - new StickyRepeatService(eventSimulatorSvc), - new StickyHoldService(eventSimulatorSvc), - new RightClick(eventSimulatorSvc) - ); - - var evtDn = new UioHookEvent - { - Type = EventType.MousePressed, - Mouse = new MouseEventData { Button = MouseButton.Button3 }, - }; - // var evtUp = new UioHookEvent - // { - // Type = EventType.MouseReleased, - // Mouse = new MouseEventData { Button = MouseButton.Button3, } - // }; - RunHookAndWaitForStart(hook, testProvider); - - sut.Run(); - testProvider.PostEvent(ref evtDn); - // testProvider.PostEvent(ref evtUp); - - eventSimulatorMock.Received(1).SimulateKeyPress(Arg.Is(KeyCode.VcW)); - eventSimulatorMock.Received(2).SimulateKeyPress(Arg.Is(KeyCode.VcE)); - eventSimulatorMock.Received(2).SimulateKeyRelease(Arg.Is(KeyCode.VcE)); - eventSimulatorMock.Received(1).SimulateKeyRelease(Arg.Is(KeyCode.VcW)); - } - - [Test] - public void NonDefaultProfileNotSendKeys() - { - var pf = GetProfilesService(GetSeedData()); - pf.Profiles.First(x => !x.IsDefault).MouseButton3 = new SimulatedKeystrokes - { - SimulatedKeystrokesType = new MouseButtonPressedActionType(), - BlockOriginalMouseInput = true, - Keys = "wee", - }; - var testProvider = new TestProvider(); - using var hook = new SimpleReactiveGlobalHook(globalHookProvider: testProvider); - var curWinSvc = Substitute.For(); - curWinSvc.ForegroundWindow.Returns("U can't touch this"); - var mouseListener = new MouseListener(hook, pf, curWinSvc); - var skipProfileService = GetSkipProfileService(); - var eventSimulatorMock = Substitute.For(); - var eventSimulatorSvc = new EventSimulatorService(eventSimulatorMock); - var sut = new KeyboardSimulatorWorker( - pf, - mouseListener, - skipProfileService, - new AsMouseButtonPressedService(eventSimulatorSvc), - new AsMouseButtonReleasedService(eventSimulatorSvc), - new DuringMousePressAndReleaseService(eventSimulatorSvc), - new RepeatedWhileButtonDownService(eventSimulatorSvc), - new StickyRepeatService(eventSimulatorSvc), - new StickyHoldService(eventSimulatorSvc), - new RightClick(eventSimulatorSvc) - ); - - var evtDn = new UioHookEvent - { - Type = EventType.MousePressed, - Mouse = new MouseEventData { Button = MouseButton.Button3 }, - }; - // var evtUp = new UioHookEvent - // { - // Type = EventType.MouseReleased, - // Mouse = new MouseEventData { Button = MouseButton.Button3, } - // }; - RunHookAndWaitForStart(hook, testProvider); - - sut.Run(); - testProvider.PostEvent(ref evtDn); - // testProvider.PostEvent(ref evtUp); - - eventSimulatorMock.DidNotReceive().SimulateKeyPress(Arg.Any()); - eventSimulatorMock.DidNotReceive().SimulateKeyRelease(Arg.Any()); - } - - [Test] - public void DefaultProfileSendsKeysReleased() - { - var pf = GetProfilesService(GetSeedData()); - pf.CurrentProfile!.MouseButton3 = new SimulatedKeystrokes - { - SimulatedKeystrokesType = new MouseButtonReleasedActionType(), - BlockOriginalMouseInput = true, - Keys = "wee", - }; - var testProvider = new TestProvider(); - using var hook = new SimpleReactiveGlobalHook(globalHookProvider: testProvider); - var curWinSvc = Substitute.For(); - var mouseListener = new MouseListener(hook, pf, curWinSvc); - var skipProfileSvc = Substitute.For(); - var eventSimulatorMock = Substitute.For(); - var eventSimulatorSvc = new EventSimulatorService(eventSimulatorMock); - var sut = new KeyboardSimulatorWorker( - pf, - mouseListener, - skipProfileSvc, - new AsMouseButtonPressedService(eventSimulatorSvc), - new AsMouseButtonReleasedService(eventSimulatorSvc), - new DuringMousePressAndReleaseService(eventSimulatorSvc), - new RepeatedWhileButtonDownService(eventSimulatorSvc), - new StickyRepeatService(eventSimulatorSvc), - new StickyHoldService(eventSimulatorSvc), - new RightClick(eventSimulatorSvc) - ); - - var evtUp = new UioHookEvent - { - Type = EventType.MouseReleased, - Mouse = new MouseEventData { Button = MouseButton.Button3 }, - }; - RunHookAndWaitForStart(hook, testProvider); - - sut.Run(); - testProvider.PostEvent(ref evtUp); - - eventSimulatorMock.Received(1).SimulateKeyPress(Arg.Is(KeyCode.VcW)); - eventSimulatorMock.Received(2).SimulateKeyPress(Arg.Is(KeyCode.VcE)); - eventSimulatorMock.Received(2).SimulateKeyRelease(Arg.Is(KeyCode.VcE)); - eventSimulatorMock.Received(1).SimulateKeyRelease(Arg.Is(KeyCode.VcW)); - } - - // [Test] - // public void DefaultProfileSendsKeysReleased() - // { - // var pf = GetProfilesService(GetSeedData()); - // pf.CurrentProfile!.MouseButton3 = new SimulatedKeystrokes - // { - // // SimulatedKeystrokesType = new(), - // BlockOriginalMouseInput = true, - // Keys = "wee" - // }; - // var testProvider = new TestProvider(); - // using var hook = new SimpleReactiveGlobalHook(globalHookProvider: testProvider); - // var curWinSvc = Substitute.For(); - // var mouseListener = new MouseListener(hook, pf, curWinSvc); - // var skipProfileSvc = Substitute.For(); - // var eventSimulatorMock = Substitute.For(); - // var eventSimulatorSvc = new EventSimulatorService(eventSimulatorMock); - // var sut = new KeyboardSimulatorWorker( - // pf, - // mouseListener, - // skipProfileSvc, - // new AsMouseButtonPressedService(eventSimulatorSvc), - // new AsMouseButtonReleasedService(eventSimulatorSvc), - // new DuringMousePressAndReleaseService(eventSimulatorSvc), - // new RepeatedWhileButtonDownService(eventSimulatorSvc), - // new StickyRepeatService(eventSimulatorSvc), - // new StickyHoldService(eventSimulatorSvc), - // new RightClick(eventSimulatorSvc) - // ); - // - // var evtUp = new UioHookEvent - // { - // Type = EventType.MouseReleased, - // Mouse = new MouseEventData { Button = MouseButton.Button3, } - // }; - // RunHookAndWaitForStart(hook, testProvider); - // - // sut.Run(); - // testProvider.PostEvent(ref evtUp); - // - // eventSimulatorMock.Received(1).SimulateKeyPress(Arg.Is(KeyCode.VcW)); - // eventSimulatorMock.Received(2).SimulateKeyPress(Arg.Is(KeyCode.VcE)); - // eventSimulatorMock.Received(2).SimulateKeyRelease(Arg.Is(KeyCode.VcE)); - // eventSimulatorMock.Received(1).SimulateKeyRelease(Arg.Is(KeyCode.VcW)); - // } - - private static ISkipProfileService GetSkipProfileService() - { - if (OperatingSystem.IsWindowsVersionAtLeast(5, 1, 2600)) - { - return new SkipProfileService(); - } - else if (OperatingSystem.IsMacOS()) - { - // return new YMouseButtonControl.Services.MacOS.SkipProfileService(); - } - else - { - // return new YMouseButtonControl.Services.Linux.SkipProfileService(); - } - - throw new Exception("Bad state"); - } - - private static void RunHookAndWaitForStart(IReactiveGlobalHook hook, TestProvider provider) - { - hook.RunAsync(); - - while (!provider.IsRunning) - { - Thread.Yield(); - } - } -} diff --git a/YMouseButtonControl.Core.Tests/Profiles/ProfilesServiceTests.cs b/YMouseButtonControl.Core.Tests/Profiles/ProfilesServiceTests.cs deleted file mode 100644 index 18e916b..0000000 --- a/YMouseButtonControl.Core.Tests/Profiles/ProfilesServiceTests.cs +++ /dev/null @@ -1,208 +0,0 @@ -using FluentAssertions; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.Profiles.Exceptions; -using YMouseButtonControl.Core.Profiles.Interfaces; - -namespace YMouseButtonControl.Core.Tests.Profiles; - -public class ProfilesServiceTests : BaseTest -{ - [Test] - public void TestCtor() - { - var sut = GetProfilesService(); - - Assert.That(sut, Is.InstanceOf()); - } - - [Test] - public void HasDefaultDatabase() - { - var sut = GetProfilesService(); - - Assert.Multiple(() => - { - Assert.That(sut.Profiles, Has.Count.EqualTo(1)); - Assert.That(sut.CurrentProfile, Is.Not.Null); - Assert.That(sut.CurrentProfile!.IsDefault, Is.True); - Assert.That(sut.UnsavedChanges, Is.False); - }); - } - - [Test] - public void AddProfile() - { - var newProfile = new Profile { Name = "NEW" }; - var sut = GetProfilesService(); - var defaultProfile = sut.Profiles.First(x => x.IsDefault); - - sut.AddProfile(newProfile); - - Assert.Multiple(() => - { - Assert.That(newProfile.DisplayPriority, Is.GreaterThan(defaultProfile.DisplayPriority)); - Assert.That(sut.Profiles, Has.Count.EqualTo(2)); - Assert.That(sut.UnsavedChanges); - sut.CurrentProfile.Should().BeEquivalentTo(newProfile); - }); - } - - [Test] - public void RemoveProfile() - { - var sut = GetProfilesService(GetSeedData()); - var profileToRemove = sut.Profiles[5]; - - sut.RemoveProfile(profileToRemove); - - sut.Profiles.Should().NotContainEquivalentOf(profileToRemove); - } - - [Test] - public void RemoveDefaultProfile_ThrowsException() - { - var sut = GetProfilesService(); - sut.CurrentProfile = sut.Profiles.First(x => x.Name == "Default"); - - Assert.Throws(() => sut.RemoveProfile(sut.CurrentProfile)); - } - - [Test] - public void MoveDefaultProfile_ThrowsException() - { - var sut = GetProfilesService(); - sut.CurrentProfile = sut.Profiles.First(x => x.Name == "Default"); - - Assert.Throws(() => sut.MoveProfileDown(sut.CurrentProfile)); - Assert.Throws(() => sut.MoveProfileUp(sut.CurrentProfile)); - } - - [Test] - public void MoveProfileAboveDefault_ThrowsException() - { - var sut = GetProfilesService(GetSeedData()); - var defaultProfile = sut.Profiles.First(x => x.Name == "Default"); - var profToMove = sut - .Profiles.Where(x => x.DisplayPriority > defaultProfile.DisplayPriority) - .MinBy(x => x.DisplayPriority); - - Assert.Throws(() => sut.MoveProfileUp(profToMove)); - } - - [Test] - public void MoveProfileDown() - { - var sut = GetProfilesService(GetSeedData()); - var profileToMoveDown = sut.Profiles[5]; - var initialPriority = profileToMoveDown.DisplayPriority; - - sut.MoveProfileDown(profileToMoveDown); - - var newPriority = profileToMoveDown.DisplayPriority; - Assert.That(initialPriority, Is.LessThan(newPriority)); - } - - [Test] - public void MoveProfileUp() - { - var sut = GetProfilesService(GetSeedData()); - var profile = sut.Profiles[5]; - var initialPriority = profile.DisplayPriority; - sut.MoveProfileUp(profile); - - var newPriority = profile.DisplayPriority; - - Assert.That(initialPriority, Is.GreaterThan(newPriority)); - } - - [Test] - public void CopyProfile() - { - var sut = GetProfilesService(GetSeedData()); - var profile = sut.Profiles[1]; - - var profileCopy = sut.CopyProfile(profile); - - profileCopy.Should().BeEquivalentTo(profile); - } - - [Test] - public void WriteProfileToPath() - { - const string output = "tmp.json"; - var sut = GetProfilesService(GetSeedData()); - var profile = sut.Profiles[1]; - - sut.WriteProfileToFile(profile, output); - - Assert.That(File.Exists(output)); - - if (File.Exists(output)) - { - File.Delete(output); - } - } - - [Test] - public void ImportProfileFromPath() - { - const string json = - "{\"Checked\":true,\"Name\":\"Name7c8fd081-5cc2-41ac-8daa-34fdb59024eb\",\"MouseButton1\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription7815a17c-db7b-44f1-8d37-4f4abe1a140a\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseButton2\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription6c5331ad-732e-4a2b-b566-7dc446b35f0d\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseButton3\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescriptionaabc8b2b-49ae-48dd-adcf-2fc2ef068d09\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseButton4\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription89e8664b-29c9-4d0b-a4f8-e86805ed0485\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseButton5\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription7b3d0fd6-3dc6-400a-bc99-fa46ca932095\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseWheelUp\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription888080de-7fd7-4b9d-828d-584ce0bfdd8e\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseWheelDown\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription4975e8aa-c9a2-49f7-a34d-47932cbbac5c\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseWheelLeft\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription57cbfaf3-19a0-4d4f-976c-36dad6e95c6c\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseWheelRight\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription8d04cfce-5361-4027-a790-fa996eccab2a\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"Description\":\"Descriptionb0ba4f6e-4929-433e-8cb1-a8aa256ef7f3\",\"WindowCaption\":\"WindowCaption41783e0a-bbd3-4c80-8053-c1662788849d\",\"Process\":\"Process9952adfe-db98-4cfc-90a7-a0e20f58aebc\",\"WindowClass\":\"WindowClass31f013da-d1bc-4c83-a67d-ee4175db575e\",\"ParentClass\":\"ParentClassb6be68c5-5be1-4ef6-928a-cb8e6e8426bf\",\"MatchType\":\"MatchTypedbacc055-e328-4a76-adcc-b29127ab72d1\"}"; - const string path = "tmp.json"; - File.WriteAllText(path, json); - var sut = GetProfilesService(); - - sut.ImportProfileFromPath(path); - - var imported = sut.Profiles[1]; - - Assert.Multiple(() => - { - Assert.That(imported, Is.Not.Null); - Assert.That(imported.Name, Is.EqualTo("Name7c8fd081-5cc2-41ac-8daa-34fdb59024eb")); - Assert.That(imported.Id, Is.EqualTo(2)); - }); - - if (File.Exists(path)) - { - File.Delete(path); - } - } - - [Test] - public void GetProfiles() - { - var sut = GetProfilesService(GetSeedData()); - - Assert.That(sut.Profiles, Is.Not.Null); - Assert.That(sut.Profiles, Has.Count.GreaterThan(0)); - } - - [Test] - public void ReplaceProfile() - { - var sut = GetProfilesService(GetSeedData()); - var toBeReplaced = sut.Profiles[1]; - var replacement = new Profile { Name = "WAHOO" }; - - sut.ReplaceProfile(toBeReplaced, replacement); - - Assert.Multiple(() => - { - sut.Profiles.Should().NotContainEquivalentOf(toBeReplaced); - sut.Profiles.Should().ContainEquivalentOf(replacement); - }); - } - - [Test] - public void ReplaceDefaultProfile_ThrowsException() - { - var sut = GetProfilesService(); - sut.CurrentProfile = sut.Profiles.First(x => x.Name == "Default"); - var replacement = new Profile { Name = "WAHOO" }; - - Assert.Throws( - () => sut.ReplaceProfile(sut.CurrentProfile, replacement) - ); - } -} diff --git a/YMouseButtonControl.Core.Tests/ViewModels/ProfilesListViewModelTests.cs b/YMouseButtonControl.Core.Tests/ViewModels/ProfilesListViewModelTests.cs deleted file mode 100644 index b0754dc..0000000 --- a/YMouseButtonControl.Core.Tests/ViewModels/ProfilesListViewModelTests.cs +++ /dev/null @@ -1,451 +0,0 @@ -using System.Reactive; -using AutoFixture; -using AutoFixture.Kernel; -using FluentAssertions; -using Newtonsoft.Json; -using NSubstitute; -using YMouseButtonControl.Core.DataAccess.Configuration; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.Processes; -using YMouseButtonControl.Core.Profiles.Implementations; -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.ProfilesList; -using YMouseButtonControl.Core.ViewModels.ProfilesList.Features.Add; -using YMouseButtonControl.DataAccess.LiteDb; - -namespace YMouseButtonControl.Core.Tests.ViewModels; - -public class ProfilesListViewModelTests : BaseTest -{ - [Test] - public void Ctor() - { - var pf = GetProfilesService(); - var psdvmMock = Substitute.For(); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvmMock, addProfile); - - Assert.Multiple(() => - { - Assert.That(sut, Is.Not.Null); - Assert.That(sut, Is.InstanceOf()); - }); - } - - [Test] - public void AddButtonAddsProfileToProfileList() - { - var pf = GetProfilesService(); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - var profileToReturn = new Profile { Name = "WAHOO" }; - sut.ShowProcessSelectorInteraction.RegisterHandler(context => - context.SetOutput(profileToReturn) - ); - - sut.AddButtonCommand.Execute(null); - - pf.Profiles.Should().ContainEquivalentOf(profileToReturn); - } - - [Test] - public void AddButton_NullReturned() - { - var pf = GetProfilesService(); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - sut.ShowProcessSelectorInteraction.RegisterHandler(context => context.SetOutput(null)); - - sut.AddButtonCommand.Execute(null); - - pf.Profiles.Should().NotContainNulls(); - } - - [Test] - public void EditButton_UserSelectsProcess() - { - var pf = GetProfilesService(GetSeedData()); - pf.CurrentProfile = pf.Profiles.First(x => !x.IsDefault); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - var profileToReturn = new Profile { Name = "WAHOO" }; - sut.ShowProcessSelectorInteraction.RegisterHandler(context => - context.SetOutput(profileToReturn) - ); - var profileToEdit = pf.Profiles[1]; - - sut.EditButtonCommand.Execute(Unit.Default).Subscribe(); - - Assert.Multiple(() => - { - pf.Profiles.Should().NotContainEquivalentOf(profileToEdit); - pf.CurrentProfile.Name.Should().BeSameAs("WAHOO"); - }); - } - - [Test] - public void EditButton_UserCancelsProcessSelectorDialog() - { - var pf = GetProfilesService(GetSeedData()); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - sut.ShowProcessSelectorInteraction.RegisterHandler(context => context.SetOutput(null)); - var profileToEdit = pf.CurrentProfile; - - sut.EditButtonCommand.Execute(Unit.Default).Subscribe(); - - Assert.Multiple(() => - { - pf.Profiles.Should().NotContainNulls(); - pf.Profiles.Should().ContainEquivalentOf(profileToEdit); - }); - } - - [Test] - public void EditButton_DisabledWhenCurrentProfileIsDefault() - { - var pf = GetProfilesService(); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - - sut.EditButtonCommand.CanExecute.Subscribe(x => - { - Assert.That(x, Is.False); - }); - } - - [Test] - public void EditButton_EnabledWhenNonDefaultProfileSelected() - { - var pf = GetProfilesService(GetSeedData()); - pf.CurrentProfile = pf.Profiles.First(x => !x.IsDefault); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - - sut.EditButtonCommand.CanExecute.Subscribe(x => - { - Assert.That(x, Is.True); - }); - } - - [Test] - public void RemoveButton_RemoveProfile() - { - var pf = GetProfilesService(GetSeedData()); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - var profileToRemove = pf.Profiles.First(x => !x.IsDefault); - pf.CurrentProfile = profileToRemove; - - sut.RemoveButtonCommand.Execute(Unit.Default).Subscribe(); - - pf.Profiles.Should().NotContainNulls(); - pf.Profiles.Should().NotContainEquivalentOf(profileToRemove); - } - - [Test] - public void RemoveButton_DisabledWhenDefaultProfileSelected() - { - var pf = GetProfilesService(); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - - sut.RemoveButtonCommand.CanExecute.Subscribe(x => - { - Assert.That(x, Is.False); - }); - } - - [Test] - public void RemoveButton_EnabledWhenNonDefaultProfileSelected() - { - var pf = GetProfilesService(GetSeedData()); - pf.CurrentProfile = pf.Profiles.First(x => !x.IsDefault); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - - sut.RemoveButtonCommand.CanExecute.Subscribe(x => - { - Assert.That(x, Is.True); - }); - } - - [Test] - public void UpButton_Enabled() - { - var pf = GetProfilesService(GetSeedData()); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - var profileToMove = pf.Profiles.Last(x => !x.IsDefault); - pf.CurrentProfile = profileToMove; - - sut.UpCommand.CanExecute.Subscribe(x => - { - Assert.That(x, Is.True); - }); - } - - [Test] - public void UpButton_DisabledForDefaultProfile() - { - var pf = GetProfilesService(); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - - sut.UpCommand.CanExecute.Subscribe(x => - { - Assert.That(x, Is.False); - }); - } - - [Test] - public void UpButton_DisabledForProfileImmediatelyBelowDefault() - { - var pf = GetProfilesService(GetSeedData(1)); - pf.CurrentProfile = pf.Profiles.Where(x => !x.IsDefault).MinBy(x => x.DisplayPriority); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - - sut.UpCommand.CanExecute.Subscribe(x => - { - Assert.That(x, Is.False); - }); - } - - [Test] - public void UpButton_MoveProfile() - { - var pf = GetProfilesService(GetSeedData()); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - var profileToMoveUp = pf.Profiles.Last(x => !x.IsDefault); - var p1p = profileToMoveUp.DisplayPriority; - pf.CurrentProfile = profileToMoveUp; - var profileThatWillBeShiftedDown = pf - .Profiles.Where(x => x.DisplayPriority < profileToMoveUp.DisplayPriority) - .MaxBy(x => x.DisplayPriority); - var p2p = profileThatWillBeShiftedDown.DisplayPriority; - - sut.UpCommand.Execute(Unit.Default).Subscribe(); - - Assert.Multiple(() => - { - Assert.That(profileToMoveUp.DisplayPriority, Is.EqualTo(p2p)); - Assert.That(profileThatWillBeShiftedDown.DisplayPriority, Is.EqualTo(p1p)); - }); - } - - [Test] - public void DownButton_DisabledForDefaultProfile() - { - var pf = GetProfilesService(); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - - sut.DownCommand.CanExecute.Subscribe(x => - { - Assert.That(x, Is.False); - }); - } - - [Test] - public void DownButton_DisabledForLastProfile() - { - var pf = GetProfilesService(GetSeedData(1)); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - pf.CurrentProfile = pf.Profiles.Where(x => !x.IsDefault).MaxBy(x => x.DisplayPriority); - - sut.DownCommand.CanExecute.Subscribe(x => - { - Assert.That(x, Is.False); - }); - } - - [Test] - public void DownButton_Enabled() - { - var pf = GetProfilesService(GetSeedData(2)); - pf.CurrentProfile = pf - .Profiles.Where(p => p.DisplayPriority > 0) - .MinBy(x => x.DisplayPriority); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - - sut.DownCommand.CanExecute.Subscribe(x => - { - Assert.That(x, Is.True); - }); - } - - [Test] - public void DownButton() - { - var pf = GetProfilesService(GetSeedData(2)); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - var profileToMove = pf.Profiles.First(x => !x.IsDefault); - pf.CurrentProfile = profileToMove; - var priority1 = profileToMove.DisplayPriority; - var profileToBeShiftedUp = pf - .Profiles.Where(x => x.DisplayPriority > profileToMove.DisplayPriority) - .MinBy(x => x.DisplayPriority); - var priority2 = profileToBeShiftedUp!.DisplayPriority; - - Assert.That(priority1, Is.LessThan(priority2)); - - sut.DownCommand.Execute(Unit.Default).Subscribe(); - - Assert.Multiple(() => - { - Assert.That(profileToMove.DisplayPriority, Is.EqualTo(priority2)); - Assert.That(profileToBeShiftedUp.DisplayPriority, Is.EqualTo(priority1)); - }); - } - - [Test] - public void ExportButton() - { - var pf = GetProfilesService(GetSeedData(1)); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - var profileToExport = pf.Profiles[1]; - pf.CurrentProfile = profileToExport; - const string outputPath = "tmp.json"; - sut.ShowExportFileDialog.RegisterHandler(x => x.SetOutput(outputPath)); - - sut.ExportCommand.Execute(Unit.Default).Subscribe(); - - Assert.Multiple(() => - { - Assert.That(File.Exists(outputPath)); - var deserialized = JsonConvert.DeserializeObject( - File.ReadAllText(outputPath), - new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto } - ); - profileToExport.Should().BeEquivalentTo(deserialized); - }); - - if (File.Exists(outputPath)) - { - File.Delete(outputPath); - } - } - - [Test] - public void ExportButton_DisabledForDefaultProfile() - { - var pf = GetProfilesService(); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - sut.ExportCommand.CanExecute.Subscribe(x => - { - Assert.That(x, Is.False); - }); - } - - [Test] - public void CopyButton_UserClicksCancel() - { - var pf = GetProfilesService(GetSeedData()); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - sut.ShowProcessSelectorInteraction.RegisterHandler(context => context.SetOutput(null)); - var numProfiles = pf.Profiles.Count; - sut.CopyCommand.Execute(Unit.Default).Subscribe(); - - pf.Profiles.Should().NotContainNulls(); - pf.Profiles.Count.Should().Be(numProfiles); - } - - [Test] - public void CopyButton_UserChoosesProcess() - { - var pf = GetProfilesService(GetSeedData(1)); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - var newProfile = new Profile { Name = "New Profile", Description = "Some description" }; - sut.ShowProcessSelectorInteraction.RegisterHandler(context => - context.SetOutput(newProfile) - ); - var profileToCopyFrom = pf.CurrentProfile; - sut.CopyCommand.Execute(Unit.Default).Subscribe(); - - Assert.Multiple(() => - { - pf.Profiles.Should().NotContainNulls(); - pf.Profiles.Count.Should().Be(3); - pf.Profiles.Should().ContainEquivalentOf(profileToCopyFrom); - pf.Profiles.Should() - .Contain(p => p.Name == newProfile.Name && p.Description == newProfile.Description); - }); - } - - [Test] - public void ImportButton() - { - const string data = - "{\"Checked\":true,\"Name\":\"Name7c8fd081-5cc2-41ac-8daa-34fdb59024eb\",\"MouseButton1\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription7815a17c-db7b-44f1-8d37-4f4abe1a140a\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseButton2\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription6c5331ad-732e-4a2b-b566-7dc446b35f0d\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseButton3\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescriptionaabc8b2b-49ae-48dd-adcf-2fc2ef068d09\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseButton4\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription89e8664b-29c9-4d0b-a4f8-e86805ed0485\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseButton5\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription7b3d0fd6-3dc6-400a-bc99-fa46ca932095\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseWheelUp\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription888080de-7fd7-4b9d-828d-584ce0bfdd8e\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseWheelDown\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription4975e8aa-c9a2-49f7-a34d-47932cbbac5c\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseWheelLeft\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription57cbfaf3-19a0-4d4f-976c-36dad6e95c6c\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"MouseWheelRight\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.NothingMapping, YMouseButtonControl.Core\",\"Index\":0,\"Enabled\":false,\"Description\":\"** No Change (Don't Intercept) **\",\"PriorityDescription\":\"PriorityDescription8d04cfce-5361-4027-a790-fa996eccab2a\",\"Keys\":null,\"State\":false,\"CanRaiseDialog\":false,\"SimulatedKeystrokesType\":{\"$type\":\"YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes.StickyHoldActionType, YMouseButtonControl.Core\",\"Index\":7,\"Description\":\"Sticky (held down until button is pressed again)\",\"ShortDescription\":\"sticky hold\",\"Enabled\":true},\"MouseButtonDisabled\":true},\"Description\":\"Descriptionb0ba4f6e-4929-433e-8cb1-a8aa256ef7f3\",\"WindowCaption\":\"WindowCaption41783e0a-bbd3-4c80-8053-c1662788849d\",\"Process\":\"Process9952adfe-db98-4cfc-90a7-a0e20f58aebc\",\"WindowClass\":\"WindowClass31f013da-d1bc-4c83-a67d-ee4175db575e\",\"ParentClass\":\"ParentClassb6be68c5-5be1-4ef6-928a-cb8e6e8426bf\",\"MatchType\":\"MatchTypedbacc055-e328-4a76-adcc-b29127ab72d1\"}"; - const string path = "tmp.json"; - var deserialized = JsonConvert.DeserializeObject( - data, - new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto } - ); - File.WriteAllText(path, data); - var pf = GetProfilesService(); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - sut.ShowImportFileDialog.RegisterHandler(x => x.SetOutput(path)); - - sut.ImportCommand.Execute(Unit.Default).Subscribe(); - - pf.CurrentProfile.Should().BeEquivalentTo(deserialized); - - if (File.Exists(path)) - { - File.Delete(path); - } - } - - [Test] - public void ImportButton_UserClicksCancel() - { - var pf = GetProfilesService(); - var psdvm = new ProcessSelectorDialogViewModel(Substitute.For()); - var addProfile = new AddProfile(pf); - var sut = new ProfilesListViewModel(pf, psdvm, addProfile); - sut.ShowImportFileDialog.RegisterHandler(x => x.SetOutput(null)); - - sut.ImportCommand.Execute(Unit.Default).Subscribe(); - - Assert.That(pf.Profiles, Has.Count.EqualTo(1)); - pf.Profiles.Should().NotContainNulls(); - } -} diff --git a/YMouseButtonControl.Core.Tests/YMouseButtonControl.Core.Tests.csproj b/YMouseButtonControl.Core.Tests/YMouseButtonControl.Core.Tests.csproj index f5c2ffd..b0b948b 100644 --- a/YMouseButtonControl.Core.Tests/YMouseButtonControl.Core.Tests.csproj +++ b/YMouseButtonControl.Core.Tests/YMouseButtonControl.Core.Tests.csproj @@ -15,15 +15,15 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -36,11 +36,9 @@ - - - - - + + + diff --git a/YMouseButtonControl.Core/DataAccess/Configuration/DatabaseConfiguration.cs b/YMouseButtonControl.Core/DataAccess/Configuration/DatabaseConfiguration.cs deleted file mode 100644 index f0d66fe..0000000 --- a/YMouseButtonControl.Core/DataAccess/Configuration/DatabaseConfiguration.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace YMouseButtonControl.Core.DataAccess.Configuration; - -public class DatabaseConfiguration -{ - public string? ConnectionString { get; set; } - - public bool UseInMemoryDatabase { get; set; } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Enums/ButtonMappings.cs b/YMouseButtonControl.Core/DataAccess/Models/Enums/ButtonMappings.cs deleted file mode 100644 index f89d157..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Enums/ButtonMappings.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace YMouseButtonControl.Core.DataAccess.Models.Enums; - -public enum ButtonMappings -{ - Nothing, - Disabled, - SimulatedKeystrokes, - RightClick, -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/DisabledMapping.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/DisabledMapping.cs deleted file mode 100644 index 8479698..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/DisabledMapping.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using Newtonsoft.Json; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -namespace YMouseButtonControl.Core.DataAccess.Models.Implementations; - -[JsonObject(MemberSerialization.OptOut)] -public class DisabledMapping : IButtonMapping, IEquatable -{ - public int Index { get; } = 1; - public bool Enabled { get; } - public string Description { get; } = "Disabled"; - public string? PriorityDescription { get; set; } - public string? Keys { get; } - public bool State { get; set; } - public bool CanRaiseDialog { get; } = false; - public ISimulatedKeystrokesType? SimulatedKeystrokesType { get; set; } - public bool BlockOriginalMouseInput { get; set; } = true; - - public override string ToString() - { - return Description; - } - - public bool Equals(DisabledMapping? other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - return Index == other.Index - && Enabled == other.Enabled - && Description == other.Description - && CanRaiseDialog == other.CanRaiseDialog - && Keys == other.Keys - && State == other.State - && Equals(SimulatedKeystrokesType, other.SimulatedKeystrokesType); - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != this.GetType()) - return false; - return Equals((DisabledMapping)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = Index; - hashCode = (hashCode * 397) ^ Enabled.GetHashCode(); - hashCode = (hashCode * 397) ^ Description.GetHashCode(); - hashCode = (hashCode * 397) ^ CanRaiseDialog.GetHashCode(); - if (!string.IsNullOrWhiteSpace(Keys)) - { - hashCode = (hashCode * 397) ^ Keys.GetHashCode(); - } - hashCode = (hashCode * 397) ^ State.GetHashCode(); - hashCode = - (hashCode * 397) - ^ (SimulatedKeystrokesType != null ? SimulatedKeystrokesType.GetHashCode() : 0); - return hashCode; - } - } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/NothingMapping.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/NothingMapping.cs deleted file mode 100644 index 3206e29..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/NothingMapping.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using Newtonsoft.Json; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -namespace YMouseButtonControl.Core.DataAccess.Models.Implementations; - -[JsonObject(MemberSerialization.OptOut)] -public class NothingMapping : IButtonMapping, IEquatable -{ - public int Index { get; } = 0; - public bool Enabled { get; } = false; - public string Description { get; } = "** No Change (Don't Intercept) **"; - public string? PriorityDescription { get; set; } - - public override string ToString() - { - return Description; - } - - public string? Keys { get; } - public bool State { get; set; } - public bool CanRaiseDialog { get; } = false; - public ISimulatedKeystrokesType? SimulatedKeystrokesType { get; set; } - public bool BlockOriginalMouseInput { get; set; } = false; - - public bool Equals(NothingMapping? other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - return Index == other.Index - && Enabled == other.Enabled - && Description == other.Description - && CanRaiseDialog == other.CanRaiseDialog - && Keys == other.Keys - && State == other.State - && Equals(SimulatedKeystrokesType, other.SimulatedKeystrokesType); - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != this.GetType()) - return false; - return Equals((NothingMapping)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = Index; - hashCode = (hashCode * 397) ^ Enabled.GetHashCode(); - hashCode = (hashCode * 397) ^ Description.GetHashCode(); - hashCode = (hashCode * 397) ^ CanRaiseDialog.GetHashCode(); - hashCode = (hashCode * 397) ^ (Keys != null ? Keys.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ State.GetHashCode(); - hashCode = - (hashCode * 397) - ^ (SimulatedKeystrokesType != null ? SimulatedKeystrokesType.GetHashCode() : 0); - return hashCode; - } - } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/Profile.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/Profile.cs deleted file mode 100644 index 30b69eb..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/Profile.cs +++ /dev/null @@ -1,211 +0,0 @@ -using System; -using Newtonsoft.Json; -using ReactiveUI; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -namespace YMouseButtonControl.Core.DataAccess.Models.Implementations; - -[JsonObject(MemberSerialization.OptOut)] -public class Profile : ReactiveObject, IEquatable -{ - private IButtonMapping _mb1 = new NothingMapping(); - private IButtonMapping _mb2 = new NothingMapping(); - private IButtonMapping _mb3 = new NothingMapping(); - private IButtonMapping _mb4 = new NothingMapping(); - private IButtonMapping _mb5 = new NothingMapping(); - private IButtonMapping _mwu = new NothingMapping(); - private IButtonMapping _mwd = new NothingMapping(); - private IButtonMapping _mwl = new NothingMapping(); - private IButtonMapping _mwr = new NothingMapping(); - - private int _displayPriority; - - private bool _isChecked = true; - - private string _description = "N/A"; - private string _windowCaption = "N/A"; - private string _process = "N/A"; - private string _windowClass = "N/A"; - private string _parentClass = "N/A"; - private string _matchType = "N/A"; - - [JsonIgnore] - public int Id { get; set; } - - /// - /// The display priority of a profile. Lower values should appear first in a list. Higher values should appear later in a list. - /// - public int DisplayPriority - { - get => _displayPriority; - set => this.RaiseAndSetIfChanged(ref _displayPriority, value); - } - - public bool IsDefault { get; set; } - - public bool Checked - { - get => _isChecked; - set => this.RaiseAndSetIfChanged(ref _isChecked, value); - } - - public string Name { get; set; } = string.Empty; - - public IButtonMapping MouseButton1 - { - get => _mb1; - set => this.RaiseAndSetIfChanged(ref _mb1, value); - } - - public IButtonMapping MouseButton2 - { - get => _mb2; - set => this.RaiseAndSetIfChanged(ref _mb2, value); - } - - public IButtonMapping MouseButton3 - { - get => _mb3; - set => this.RaiseAndSetIfChanged(ref _mb3, value); - } - - public IButtonMapping MouseButton4 - { - get => _mb4; - set => this.RaiseAndSetIfChanged(ref _mb4, value); - } - - public IButtonMapping MouseButton5 - { - get => _mb5; - set => this.RaiseAndSetIfChanged(ref _mb5, value); - } - - public IButtonMapping MouseWheelUp - { - get => _mwu; - set => this.RaiseAndSetIfChanged(ref _mwu, value); - } - - public IButtonMapping MouseWheelDown - { - get => _mwd; - set => this.RaiseAndSetIfChanged(ref _mwd, value); - } - - public IButtonMapping MouseWheelLeft - { - get => _mwl; - set => this.RaiseAndSetIfChanged(ref _mwl, value); - } - - public IButtonMapping MouseWheelRight - { - get => _mwr; - set => this.RaiseAndSetIfChanged(ref _mwr, value); - } - - public string Description - { - get - { - if (Name == "Default") - { - return "Default"; - } - return string.IsNullOrWhiteSpace(_description) ? _process : _description; - } - set => this.RaiseAndSetIfChanged(ref _description, value); - } - - public string WindowCaption - { - get => _windowCaption; - set => this.RaiseAndSetIfChanged(ref _windowCaption, value); - } - - public string Process - { - get => _process; - set => this.RaiseAndSetIfChanged(ref _process, value); - } - - public string WindowClass - { - get => _windowClass; - set => this.RaiseAndSetIfChanged(ref _windowClass, value); - } - - public string ParentClass - { - get => _parentClass; - set => this.RaiseAndSetIfChanged(ref _parentClass, value); - } - - public string MatchType - { - get => _matchType; - set => this.RaiseAndSetIfChanged(ref _matchType, value); - } - - public bool Equals(Profile? other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - return Checked == other.Checked - && Name == other.Name - && MouseButton1.Equals(other.MouseButton1) - && MouseButton2.Equals(other.MouseButton2) - && MouseButton3.Equals(other.MouseButton3) - && MouseButton4.Equals(other.MouseButton4) - && MouseButton5.Equals(other.MouseButton5) - && MouseWheelUp.Equals(other.MouseWheelUp) - && MouseWheelDown.Equals(other.MouseWheelDown) - && MouseWheelLeft.Equals(other.MouseWheelLeft) - && MouseWheelRight.Equals(other.MouseWheelRight) - && Description == other.Description - && WindowCaption == other.WindowCaption - && Process == other.Process - && WindowClass == other.WindowClass - && ParentClass == other.ParentClass - && MatchType == other.MatchType; - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != this.GetType()) - return false; - return Equals((Profile)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = Checked.GetHashCode(); - hashCode = (hashCode * 397) ^ Name.GetHashCode(); - hashCode = (hashCode * 397) ^ MouseButton1.GetHashCode(); - hashCode = (hashCode * 397) ^ MouseButton2.GetHashCode(); - hashCode = (hashCode * 397) ^ MouseButton3.GetHashCode(); - hashCode = (hashCode * 397) ^ MouseButton4.GetHashCode(); - hashCode = (hashCode * 397) ^ MouseButton5.GetHashCode(); - hashCode = (hashCode * 397) ^ MouseWheelUp.GetHashCode(); - hashCode = (hashCode * 397) ^ MouseWheelDown.GetHashCode(); - hashCode = (hashCode * 397) ^ MouseWheelLeft.GetHashCode(); - hashCode = (hashCode * 397) ^ MouseWheelRight.GetHashCode(); - hashCode = (hashCode * 397) ^ Description.GetHashCode(); - hashCode = (hashCode * 397) ^ WindowCaption.GetHashCode(); - hashCode = (hashCode * 397) ^ Process.GetHashCode(); - hashCode = (hashCode * 397) ^ WindowClass.GetHashCode(); - hashCode = (hashCode * 397) ^ ParentClass.GetHashCode(); - hashCode = (hashCode * 397) ^ MatchType.GetHashCode(); - return hashCode; - } - } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/RightClick.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/RightClick.cs deleted file mode 100644 index 606867b..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/RightClick.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using ReactiveUI; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -namespace YMouseButtonControl.Core.DataAccess.Models.Implementations; - -public class RightClick : ReactiveObject, IButtonMapping, IEquatable -{ - public int Index => 3; - public bool Enabled { get; } - public string? Description { get; } = "Right Click"; - public string? PriorityDescription { get; set; } - public string? Keys { get; } = null; - public bool State { get; set; } - public bool CanRaiseDialog { get; } = false; - - public bool BlockOriginalMouseInput { get; set; } = true; - public ISimulatedKeystrokesType? SimulatedKeystrokesType { get; set; } - - public override string ToString() => "Right Click"; - - public bool Equals(RightClick? other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - return Enabled == other.Enabled - && Description == other.Description - && PriorityDescription == other.PriorityDescription - && Keys == other.Keys - && State == other.State - && CanRaiseDialog == other.CanRaiseDialog - && BlockOriginalMouseInput == other.BlockOriginalMouseInput - && Equals(SimulatedKeystrokesType, other.SimulatedKeystrokesType); - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != this.GetType()) - return false; - return Equals((RightClick)obj); - } - - public override int GetHashCode() - { - return HashCode.Combine( - Enabled, - Description, - PriorityDescription, - Keys, - State, - CanRaiseDialog, - BlockOriginalMouseInput, - SimulatedKeystrokesType - ); - } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/Setting.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/Setting.cs deleted file mode 100644 index d4ed463..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/Setting.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using ReactiveUI; - -namespace YMouseButtonControl.Core.DataAccess.Models.Implementations; - -public class Setting : ReactiveObject, IEquatable -{ - private string? _value; - - public int Id { get; set; } - public required string Name { get; set; } - - public string? Value - { - get => _value; - set => this.RaiseAndSetIfChanged(ref _value, value); - } - - public bool Equals(Setting? other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - return Id == other.Id && Name == other.Name && Value == other.Value; - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != this.GetType()) - return false; - return Equals((Setting)obj); - } - - public override int GetHashCode() - { - return HashCode.Combine(Id, Name, Value); - } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokes.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokes.cs deleted file mode 100644 index a1afdaa..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokes.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using Newtonsoft.Json; -using ReactiveUI; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -namespace YMouseButtonControl.Core.DataAccess.Models.Implementations; - -[JsonObject(MemberSerialization.OptOut)] -public class SimulatedKeystrokes : ReactiveObject, IButtonMapping, IEquatable -{ - public int Index => 2; - public string Description => "Simulated Keys (undefined)"; - public string? PriorityDescription { get; set; } - public bool Enabled { get; } - public string? Keys { get; set; } - public bool State { get; set; } - - public bool CanRaiseDialog { get; } = true; - public ISimulatedKeystrokesType? SimulatedKeystrokesType { get; set; } - - /// - /// Prevent the original mouse button from going through (not YMouseButtonControl's simulated keystroke) - /// - public bool BlockOriginalMouseInput { get; set; } = true; - - public override string ToString() - { - var myStr = SimulatedKeystrokesType is not null - ? $"Simulated Keys: ({SimulatedKeystrokesType.ShortDescription})" - : Description; - - if (!string.IsNullOrWhiteSpace(PriorityDescription)) - { - myStr += $"[{PriorityDescription}]"; - } - else if (!string.IsNullOrWhiteSpace(Keys)) - { - myStr += $"[{Keys}]"; - } - - return myStr; - } - - public bool Equals(SimulatedKeystrokes? other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - return Index == other.Index - && Description == other.Description - && Enabled == other.Enabled - && CanRaiseDialog == other.CanRaiseDialog - && Keys == other.Keys - && State == other.State - && Equals(SimulatedKeystrokesType, other.SimulatedKeystrokesType); - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != this.GetType()) - return false; - return Equals((SimulatedKeystrokes)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = Index; - hashCode = (hashCode * 397) ^ Description.GetHashCode(); - hashCode = (hashCode * 397) ^ Enabled.GetHashCode(); - hashCode = (hashCode * 397) ^ CanRaiseDialog.GetHashCode(); - hashCode = (hashCode * 397) ^ (Keys != null ? Keys.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ State.GetHashCode(); - hashCode = - (hashCode * 397) - ^ (SimulatedKeystrokesType != null ? SimulatedKeystrokesType.GetHashCode() : 0); - return hashCode; - } - } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/AsMousePressedAndReleasedActionType.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/AsMousePressedAndReleasedActionType.cs deleted file mode 100644 index 3f5800d..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/AsMousePressedAndReleasedActionType.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using Newtonsoft.Json; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -namespace YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes; - -[JsonObject(MemberSerialization.OptOut)] -public class AsMousePressedAndReleasedActionType - : ISimulatedKeystrokesType, - IEquatable -{ - public int Index { get; } = 8; - public string Description { get; } = "As mouse button is pressed & when released"; - public string ShortDescription { get; } = "pressed & released"; - public bool Enabled { get; } = true; - - public override string ToString() - { - return $"{Index + 1} {Description}"; - } - - public bool Equals(AsMousePressedAndReleasedActionType? other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - return Index == other.Index - && Description == other.Description - && ShortDescription == other.ShortDescription - && Enabled == other.Enabled; - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != this.GetType()) - return false; - return Equals((AsMousePressedAndReleasedActionType)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = Index; - hashCode = (hashCode * 397) ^ Description.GetHashCode(); - hashCode = (hashCode * 397) ^ ShortDescription.GetHashCode(); - hashCode = (hashCode * 397) ^ Enabled.GetHashCode(); - return hashCode; - } - } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/DuringMouseActionType.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/DuringMouseActionType.cs deleted file mode 100644 index 0556dea..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/DuringMouseActionType.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using Newtonsoft.Json; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -namespace YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes; - -[JsonObject(MemberSerialization.OptOut)] -public class DuringMouseActionType : ISimulatedKeystrokesType, IEquatable -{ - public int Index { get; } = 2; - public string Description { get; } = "During (press on down, release on up)"; - public string ShortDescription { get; } = "during"; - public bool Enabled { get; } = true; - - public override string ToString() - { - return $"{Index + 1} {Description}"; - } - - public bool Equals(DuringMouseActionType? other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - return Index == other.Index - && Description == other.Description - && ShortDescription == other.ShortDescription - && Enabled == other.Enabled; - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != this.GetType()) - return false; - return Equals((DuringMouseActionType)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = Index; - hashCode = (hashCode * 397) ^ Description.GetHashCode(); - hashCode = (hashCode * 397) ^ ShortDescription.GetHashCode(); - hashCode = (hashCode * 397) ^ Enabled.GetHashCode(); - return hashCode; - } - } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/InAnotherThreadPressedActionType.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/InAnotherThreadPressedActionType.cs deleted file mode 100644 index 36df241..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/InAnotherThreadPressedActionType.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using Newtonsoft.Json; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -namespace YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes; - -[JsonObject(MemberSerialization.OptOut)] -public class InAnotherThreadPressedActionType - : ISimulatedKeystrokesType, - IEquatable -{ - public int Index { get; } = 3; - public string Description { get; } = "In another thread as mouse button is pressed"; - public string ShortDescription { get; } = "thread-down"; - public bool Enabled { get; } = false; - - public override string ToString() - { - return $"{Index + 1} {Description}"; - } - - public bool Equals(InAnotherThreadPressedActionType? other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - return Index == other.Index - && Description == other.Description - && ShortDescription == other.ShortDescription - && Enabled == other.Enabled; - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != this.GetType()) - return false; - return Equals((InAnotherThreadPressedActionType)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = Index; - hashCode = (hashCode * 397) ^ Description.GetHashCode(); - hashCode = (hashCode * 397) ^ ShortDescription.GetHashCode(); - hashCode = (hashCode * 397) ^ Enabled.GetHashCode(); - return hashCode; - } - } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/InAnotherThreadReleasedActionType.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/InAnotherThreadReleasedActionType.cs deleted file mode 100644 index 360ffd1..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/InAnotherThreadReleasedActionType.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using Newtonsoft.Json; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -namespace YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes; - -[JsonObject(MemberSerialization.OptOut)] -public class InAnotherThreadReleasedActionType - : ISimulatedKeystrokesType, - IEquatable -{ - public int Index { get; } = 4; - public string Description { get; } = "In another thread as mouse button is released"; - public string ShortDescription { get; } = "thread-up"; - public bool Enabled { get; } = false; - - public override string ToString() - { - return $"{Index + 1} {Description}"; - } - - public bool Equals(InAnotherThreadReleasedActionType? other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - return Index == other.Index - && Description == other.Description - && ShortDescription == other.ShortDescription - && Enabled == other.Enabled; - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != this.GetType()) - return false; - return Equals((InAnotherThreadReleasedActionType)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = Index; - hashCode = (hashCode * 397) ^ Description.GetHashCode(); - hashCode = (hashCode * 397) ^ ShortDescription.GetHashCode(); - hashCode = (hashCode * 397) ^ Enabled.GetHashCode(); - return hashCode; - } - } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/MouseButtonPressedActionType.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/MouseButtonPressedActionType.cs deleted file mode 100644 index 87624a4..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/MouseButtonPressedActionType.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using Newtonsoft.Json; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -namespace YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes; - -[JsonObject(MemberSerialization.OptOut)] -public class MouseButtonPressedActionType - : ISimulatedKeystrokesType, - IEquatable -{ - public int Index { get; } = 0; - public string Description { get; } = "As mouse button is pressed"; - public string ShortDescription { get; } = "pressed"; - public bool Enabled { get; } = true; - - public override string ToString() - { - return $"{Index + 1} {Description}"; - } - - public bool Equals(MouseButtonPressedActionType? other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - return Index == other.Index - && Description == other.Description - && ShortDescription == other.ShortDescription - && Enabled == other.Enabled; - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != this.GetType()) - return false; - return Equals((MouseButtonPressedActionType)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = Index; - hashCode = (hashCode * 397) ^ Description.GetHashCode(); - hashCode = (hashCode * 397) ^ ShortDescription.GetHashCode(); - hashCode = (hashCode * 397) ^ Enabled.GetHashCode(); - return hashCode; - } - } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/MouseButtonReleasedActionType.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/MouseButtonReleasedActionType.cs deleted file mode 100644 index 1be5ecb..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/MouseButtonReleasedActionType.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using Newtonsoft.Json; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -namespace YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes; - -[JsonObject(MemberSerialization.OptOut)] -public class MouseButtonReleasedActionType - : ISimulatedKeystrokesType, - IEquatable -{ - public int Index { get; } = 1; - public string Description { get; } = "As mouse button is released"; - public string ShortDescription { get; } = "released"; - public bool Enabled { get; } = true; - - public override string ToString() - { - return $"{Index + 1} {Description}"; - } - - public bool Equals(MouseButtonReleasedActionType? other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - return Index == other.Index - && Description == other.Description - && ShortDescription == other.ShortDescription - && Enabled == other.Enabled; - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != this.GetType()) - return false; - return Equals((MouseButtonReleasedActionType)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = Index; - hashCode = (hashCode * 397) ^ Description.GetHashCode(); - hashCode = (hashCode * 397) ^ ShortDescription.GetHashCode(); - hashCode = (hashCode * 397) ^ Enabled.GetHashCode(); - return hashCode; - } - } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/RepeatedlyWhileButtonDownActionType.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/RepeatedlyWhileButtonDownActionType.cs deleted file mode 100644 index 417f427..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/RepeatedlyWhileButtonDownActionType.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using Newtonsoft.Json; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -namespace YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes; - -[JsonObject(MemberSerialization.OptOut)] -public class RepeatedlyWhileButtonDownActionType - : ISimulatedKeystrokesType, - IEquatable -{ - public int Index { get; } = 5; - public string Description { get; } = "Repeatedly while the button is down"; - public string ShortDescription { get; } = "repeat"; - public bool Enabled { get; } = true; - - public override string ToString() - { - return $"{Index + 1} {Description}"; - } - - public bool Equals(RepeatedlyWhileButtonDownActionType? other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - return Index == other.Index - && Description == other.Description - && ShortDescription == other.ShortDescription - && Enabled == other.Enabled; - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != this.GetType()) - return false; - return Equals((RepeatedlyWhileButtonDownActionType)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = Index; - hashCode = (hashCode * 397) ^ Description.GetHashCode(); - hashCode = (hashCode * 397) ^ ShortDescription.GetHashCode(); - hashCode = (hashCode * 397) ^ Enabled.GetHashCode(); - return hashCode; - } - } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/StickyHoldActionType.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/StickyHoldActionType.cs deleted file mode 100644 index ebf3317..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/StickyHoldActionType.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using Newtonsoft.Json; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -namespace YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes; - -[JsonObject(MemberSerialization.OptOut)] -public class StickyHoldActionType : ISimulatedKeystrokesType, IEquatable -{ - public int Index { get; } = 7; - public string Description { get; } = "Sticky (held down until button is pressed again)"; - public string ShortDescription { get; } = "sticky hold"; - public bool Enabled { get; } = true; - - public override string ToString() - { - return $"{Index + 1} {Description}"; - } - - public bool Equals(StickyHoldActionType? other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - return Index == other.Index - && Description == other.Description - && ShortDescription == other.ShortDescription - && Enabled == other.Enabled; - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != this.GetType()) - return false; - return Equals((StickyHoldActionType)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = Index; - hashCode = (hashCode * 397) ^ Description.GetHashCode(); - hashCode = (hashCode * 397) ^ ShortDescription.GetHashCode(); - hashCode = (hashCode * 397) ^ Enabled.GetHashCode(); - return hashCode; - } - } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/StickyRepeatActionType.cs b/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/StickyRepeatActionType.cs deleted file mode 100644 index 60cd36c..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Implementations/SimulatedKeystrokesTypes/StickyRepeatActionType.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using Newtonsoft.Json; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -namespace YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes; - -[JsonObject(MemberSerialization.OptOut)] -public class StickyRepeatActionType : ISimulatedKeystrokesType, IEquatable -{ - public int Index { get; } = 6; - public string Description { get; } = "Sticky (repeatedly until button is pressed again)"; - public string ShortDescription { get; } = "sticky repeat"; - public bool Enabled { get; } = true; - - public override string ToString() - { - return $"{Index + 1} {Description}"; - } - - public bool Equals(StickyRepeatActionType? other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - return Index == other.Index - && Description == other.Description - && ShortDescription == other.ShortDescription - && Enabled == other.Enabled; - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != this.GetType()) - return false; - return Equals((StickyRepeatActionType)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = Index; - hashCode = (hashCode * 397) ^ Description.GetHashCode(); - hashCode = (hashCode * 397) ^ ShortDescription.GetHashCode(); - hashCode = (hashCode * 397) ^ Enabled.GetHashCode(); - return hashCode; - } - } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Interfaces/IButtonMapping.cs b/YMouseButtonControl.Core/DataAccess/Models/Interfaces/IButtonMapping.cs deleted file mode 100644 index 7f7b2b4..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Interfaces/IButtonMapping.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -public interface IButtonMapping -{ - public int Index { get; } - public bool Enabled { get; } - public string? Description { get; } - public string? PriorityDescription { get; set; } - public string? Keys { get; } - public bool State { get; set; } - public bool CanRaiseDialog { get; } - public bool BlockOriginalMouseInput { get; set; } - - public ISimulatedKeystrokesType? SimulatedKeystrokesType { get; set; } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Interfaces/IMouseButton.cs b/YMouseButtonControl.Core/DataAccess/Models/Interfaces/IMouseButton.cs deleted file mode 100644 index ad5697e..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Interfaces/IMouseButton.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -public interface IMouseButton -{ - public int Index { get; set; } - public string Description { get; set; } - public bool CanRaiseDialog { get; set; } - public string Keys { get; set; } - public IButtonMapping ButtonMapping { get; set; } -} diff --git a/YMouseButtonControl.Core/DataAccess/Models/Interfaces/ISimulatedKeystrokesType.cs b/YMouseButtonControl.Core/DataAccess/Models/Interfaces/ISimulatedKeystrokesType.cs deleted file mode 100644 index 5bf3a0a..0000000 --- a/YMouseButtonControl.Core/DataAccess/Models/Interfaces/ISimulatedKeystrokesType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -public interface ISimulatedKeystrokesType -{ - public int Index { get; } - public string Description { get; } - public string ShortDescription { get; } - public bool Enabled { get; } -} diff --git a/YMouseButtonControl.Core/DataAccess/Repositories/IRepository.cs b/YMouseButtonControl.Core/DataAccess/Repositories/IRepository.cs deleted file mode 100644 index 5622e9e..0000000 --- a/YMouseButtonControl.Core/DataAccess/Repositories/IRepository.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; - -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); - void Upsert(string id, T entity); - void Remove(string id); - void ApplyAction(IEnumerable entities); -} diff --git a/YMouseButtonControl.Core/DataAccess/UnitOfWork/IUnitOfWork.cs b/YMouseButtonControl.Core/DataAccess/UnitOfWork/IUnitOfWork.cs deleted file mode 100644 index 604303a..0000000 --- a/YMouseButtonControl.Core/DataAccess/UnitOfWork/IUnitOfWork.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using YMouseButtonControl.Core.DataAccess.Repositories; - -namespace YMouseButtonControl.Core.DataAccess.UnitOfWork; - -public interface IUnitOfWork : IDisposable -{ - IRepository GetRepository() - where T : class; - - void SaveChanges(); -} diff --git a/YMouseButtonControl.Core/DataAccess/UnitOfWork/IUnitOfWorkFactory.cs b/YMouseButtonControl.Core/DataAccess/UnitOfWork/IUnitOfWorkFactory.cs deleted file mode 100644 index cba980b..0000000 --- a/YMouseButtonControl.Core/DataAccess/UnitOfWork/IUnitOfWorkFactory.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace YMouseButtonControl.Core.DataAccess.UnitOfWork; - -public interface IUnitOfWorkFactory -{ - IUnitOfWork Create(); -} diff --git a/YMouseButtonControl.Core/KeyboardAndMouse/Enums/MouseButtonState.cs b/YMouseButtonControl.Core/KeyboardAndMouse/Enums/MouseButtonState.cs deleted file mode 100644 index 12474e5..0000000 --- a/YMouseButtonControl.Core/KeyboardAndMouse/Enums/MouseButtonState.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace YMouseButtonControl.Core.KeyboardAndMouse.Enums; - -public enum MouseButtonState -{ - Pressed, - Released, -} diff --git a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IAsMouseButtonPressedService.cs b/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IAsMouseButtonPressedService.cs deleted file mode 100644 index 306f31e..0000000 --- a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IAsMouseButtonPressedService.cs +++ /dev/null @@ -1,9 +0,0 @@ -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Enums; - -namespace YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; - -public interface IAsMouseButtonPressedService -{ - void AsMouseButtonPressed(IButtonMapping mapping, MouseButtonState state); -} diff --git a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IAsMouseButtonReleasedService.cs b/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IAsMouseButtonReleasedService.cs deleted file mode 100644 index 66d690c..0000000 --- a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IAsMouseButtonReleasedService.cs +++ /dev/null @@ -1,9 +0,0 @@ -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Enums; - -namespace YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; - -public interface IAsMouseButtonReleasedService -{ - void AsMouseButtonReleased(IButtonMapping mapping, MouseButtonState state); -} diff --git a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IDuringMousePressAndReleaseService.cs b/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IDuringMousePressAndReleaseService.cs deleted file mode 100644 index 67fbce6..0000000 --- a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IDuringMousePressAndReleaseService.cs +++ /dev/null @@ -1,9 +0,0 @@ -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Enums; - -namespace YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; - -public interface IDuringMousePressAndReleaseService -{ - void DuringMousePressAndRelease(IButtonMapping mapping, MouseButtonState state); -} diff --git a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IEventSimulatorService.cs b/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IEventSimulatorService.cs deleted file mode 100644 index 5079dd4..0000000 --- a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IEventSimulatorService.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Threading; -using SharpHook.Native; -using YMouseButtonControl.Core.KeyboardAndMouse.Models; - -namespace YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; - -public interface IEventSimulatorService -{ - SimulateKeyboardResult SimulateKeyPress(string? key); - SimulateKeyboardResult SimulateKeyRelease(string? key); - - /// - /// Press then release - /// - /// - /// - SimulateKeyboardResult SimulateKeyTap(string? key); - - /// - /// Keys to be pressed in order. - /// - /// Keys to be pressed - void PressKeys(string? keys); - - /// - /// Keys will be released in the reversed order they come. For example, sending abc to this method will release cba - /// in that order. - /// - /// Keys to be released - void ReleaseKeys(string? keys); - - void TapKeys(string? keys); - void SimulateMousePress(MouseButton mb); - void SimulateMouseRelease(MouseButton mb); - - /// - /// TODO - /// - /// - /// Optional delay between key presses - void TapKeys(string? keys, int delay, CancellationToken cancellationToken); -} diff --git a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IMouseListener.cs b/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IMouseListener.cs deleted file mode 100644 index dbc81e5..0000000 --- a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IMouseListener.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using YMouseButtonControl.Core.Services.Abstractions.Models.EventArgs; - -namespace YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; - -public interface IMouseListener : IDisposable -{ - event EventHandler OnMouseMovedEventHandler; - event EventHandler OnMousePressedEventHandler; - event EventHandler OnMouseReleasedEventHandler; - event EventHandler OnMouseWheelEventHandler; - void Run(); -} diff --git a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IRepeatedWhileButtonDownService.cs b/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IRepeatedWhileButtonDownService.cs deleted file mode 100644 index 596390a..0000000 --- a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IRepeatedWhileButtonDownService.cs +++ /dev/null @@ -1,9 +0,0 @@ -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Enums; - -namespace YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; - -public interface IRepeatedWhileButtonDownService -{ - void RepeatWhileDown(IButtonMapping mapping, MouseButtonState state); -} diff --git a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IRightClick.cs b/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IRightClick.cs deleted file mode 100644 index 111dd63..0000000 --- a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IRightClick.cs +++ /dev/null @@ -1,8 +0,0 @@ -using YMouseButtonControl.Core.KeyboardAndMouse.Enums; - -namespace YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; - -public interface IRightClick -{ - void SimulateRightClick(MouseButtonState state); -} diff --git a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/ISkipProfileService.cs b/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/ISkipProfileService.cs deleted file mode 100644 index b7ab3b4..0000000 --- a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/ISkipProfileService.cs +++ /dev/null @@ -1,9 +0,0 @@ -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.Services.Abstractions.Models.EventArgs; - -namespace YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; - -public interface ISkipProfileService -{ - bool ShouldSkipProfile(Profile p, NewMouseHookEventArgs e); -} diff --git a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IStickyHoldService.cs b/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IStickyHoldService.cs deleted file mode 100644 index 7a07d76..0000000 --- a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IStickyHoldService.cs +++ /dev/null @@ -1,9 +0,0 @@ -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Enums; - -namespace YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; - -public interface IStickyHoldService -{ - void StickyHold(IButtonMapping mapping, MouseButtonState state); -} diff --git a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IStickyRepeatService.cs b/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IStickyRepeatService.cs deleted file mode 100644 index bc18aec..0000000 --- a/YMouseButtonControl.Core/KeyboardAndMouse/Interfaces/IStickyRepeatService.cs +++ /dev/null @@ -1,9 +0,0 @@ -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Enums; - -namespace YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; - -public interface IStickyRepeatService -{ - void StickyRepeat(IButtonMapping mapping, MouseButtonState state); -} diff --git a/YMouseButtonControl.Core/KeyboardAndMouse/Models/ISimulateKeyboardResult.cs b/YMouseButtonControl.Core/KeyboardAndMouse/Models/ISimulateKeyboardResult.cs deleted file mode 100644 index b63af3f..0000000 --- a/YMouseButtonControl.Core/KeyboardAndMouse/Models/ISimulateKeyboardResult.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace YMouseButtonControl.Core.KeyboardAndMouse.Models; - -public interface ISimulateKeyboardResult -{ - string? Result { get; set; } -} diff --git a/YMouseButtonControl.Core/KeyboardAndMouse/Models/ParsedKey.cs b/YMouseButtonControl.Core/KeyboardAndMouse/Models/ParsedKey.cs deleted file mode 100644 index 8247ed5..0000000 --- a/YMouseButtonControl.Core/KeyboardAndMouse/Models/ParsedKey.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace YMouseButtonControl.Core.KeyboardAndMouse.Models; - -public class ParsedKey -{ - public string? Key { get; set; } - public bool IsModifier { get; set; } - public ushort Value { get; set; } - - public override bool Equals(object? obj) - { - if (obj == null || GetType() != obj.GetType()) - { - return false; - } - - var pk = (ParsedKey)obj; - return (Key == pk.Key) && (IsModifier == pk.IsModifier); - } - - protected bool Equals(ParsedKey other) - { - return Key == other.Key && IsModifier == other.IsModifier; - } - - public override int GetHashCode() - { - unchecked - { - return ((Key != null ? Key.GetHashCode() : 0) * 397) ^ IsModifier.GetHashCode(); - } - } -} diff --git a/YMouseButtonControl.Core/KeyboardAndMouse/Models/SimulateKeyboardResult.cs b/YMouseButtonControl.Core/KeyboardAndMouse/Models/SimulateKeyboardResult.cs deleted file mode 100644 index 459ede2..0000000 --- a/YMouseButtonControl.Core/KeyboardAndMouse/Models/SimulateKeyboardResult.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace YMouseButtonControl.Core.KeyboardAndMouse.Models; - -public class SimulateKeyboardResult : ISimulateKeyboardResult -{ - public string? Result { get; set; } -} diff --git a/YMouseButtonControl.Core/Mappings/MappingProfile.cs b/YMouseButtonControl.Core/Mappings/MappingProfile.cs new file mode 100644 index 0000000..40fd677 --- /dev/null +++ b/YMouseButtonControl.Core/Mappings/MappingProfile.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using AutoMapper; +using YMouseButtonControl.Core.ViewModels.Models; +using YMouseButtonControl.DataAccess.Models; +using Profile = YMouseButtonControl.DataAccess.Models.Profile; + +namespace YMouseButtonControl.Core.Mappings; + +public class MappingProfile : AutoMapper.Profile +{ + public MappingProfile() + { + CreateMap().IncludeAllDerived(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + + CreateMap() + .IncludeAllDerived() + .ForMember( + x => x.SimulatedKeystrokeType, + opt => opt.MapFrom() + ); + CreateMap() + .IncludeAllDerived() + .ForMember( + x => x.SimulatedKeystrokeType, + opt => opt.MapFrom() + ); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + + CreateMap() + .ForCtorParam("buttonMappings", opt => opt.MapFrom(src => src.ButtonMappings)); + CreateMap() + .ForMember(x => x.ButtonMappings, opt => opt.MapFrom()); + CreateMap(); + } +} + +public class SimulatedKeystrokeTypeVmResolver + : IValueResolver +{ + public SimulatedKeystrokeType? Resolve( + BaseButtonMappingVm source, + ButtonMapping destination, + SimulatedKeystrokeType? destMember, + ResolutionContext context + ) => + source.SimulatedKeystrokeType switch + { + null => null, + AsMousePressedAndReleasedActionTypeVm asMousePressedAndReleasedActionTypeVm => + SimulatedKeystrokeType.AsMousePressedAndReleasedActionType, + DuringMouseActionTypeVm duringMouseActionTypeVm => + SimulatedKeystrokeType.DuringMouseActionType, + InAnotherThreadPressedActionTypeVm inAnotherThreadPressedActionTypeVm => + SimulatedKeystrokeType.InAnotherThreadPressedActionType, + InAnotherThreadReleasedActionTypeVm inAnotherThreadReleasedActionTypeVm => + SimulatedKeystrokeType.InAnotherThreadReleasedActionType, + MouseButtonPressedActionTypeVm mouseButtonPressedActionTypeVm => + SimulatedKeystrokeType.MouseButtonPressedActionType, + MouseButtonReleasedActionTypeVm mouseButtonReleasedActionTypeVm => + SimulatedKeystrokeType.MouseButtonReleasedActionType, + RepeatedlyWhileButtonDownActionTypeVm repeatedlyWhileButtonDownActionTypeVm => + SimulatedKeystrokeType.RepeatedlyWhileButtonDownActionType, + StickyHoldActionTypeVm stickyHoldActionTypeVm => + SimulatedKeystrokeType.StickyHoldActionType, + StickyRepeatActionTypeVm stickyRepeatActionTypeVm => + SimulatedKeystrokeType.StickyRepeatActionType, + _ => throw new ArgumentOutOfRangeException(), + }; +} + +public class BaseButtonVmToButtonMapping + : IValueResolver?> +{ + public ICollection Resolve( + ProfileVm source, + Profile destination, + ICollection? destMember, + ResolutionContext context + ) + { + var col = new List(); + foreach (var vm in source.ButtonMappings) + { + switch (vm) + { + case DisabledMappingVm: + col.Add(context.Mapper.Map(vm)); + break; + case NothingMappingVm: + col.Add(context.Mapper.Map(vm)); + break; + case SimulatedKeystrokeVm: + col.Add(context.Mapper.Map(vm)); + break; + case RightClickVm: + col.Add(context.Mapper.Map(vm)); + break; + default: + throw new ArgumentException($"Viewmodel is of unknown type {vm.GetType()}"); + } + } + + return col; + } +} + +public class SimulatedKeystrokeTypeResolver + : IValueResolver +{ + public BaseSimulatedKeystrokeTypeVm? Resolve( + ButtonMapping source, + BaseButtonMappingVm destination, + BaseSimulatedKeystrokeTypeVm? destMember, + ResolutionContext context + ) => + source.SimulatedKeystrokeType switch + { + SimulatedKeystrokeType.AsMousePressedAndReleasedActionType => + new AsMousePressedAndReleasedActionTypeVm(), + SimulatedKeystrokeType.DuringMouseActionType => new DuringMouseActionTypeVm(), + SimulatedKeystrokeType.InAnotherThreadPressedActionType => + new InAnotherThreadPressedActionTypeVm(), + SimulatedKeystrokeType.InAnotherThreadReleasedActionType => + new InAnotherThreadReleasedActionTypeVm(), + SimulatedKeystrokeType.MouseButtonPressedActionType => + new MouseButtonPressedActionTypeVm(), + SimulatedKeystrokeType.MouseButtonReleasedActionType => + new MouseButtonReleasedActionTypeVm(), + SimulatedKeystrokeType.RepeatedlyWhileButtonDownActionType => + new RepeatedlyWhileButtonDownActionTypeVm(), + SimulatedKeystrokeType.StickyHoldActionType => new StickyHoldActionTypeVm(), + SimulatedKeystrokeType.StickyRepeatActionType => new StickyRepeatActionTypeVm(), + null => null, + _ => throw new ArgumentOutOfRangeException(), + }; +} diff --git a/YMouseButtonControl.Core/Processes/ILowLevelMouseHookService.cs b/YMouseButtonControl.Core/Processes/ILowLevelMouseHookService.cs deleted file mode 100644 index 9ac3163..0000000 --- a/YMouseButtonControl.Core/Processes/ILowLevelMouseHookService.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace YMouseButtonControl.Core.Processes; - -public interface ILowLevelMouseHookService -{ - void Run(); - void Dispose(); -} diff --git a/YMouseButtonControl.Core/Processes/IPayloadInjectorService.cs b/YMouseButtonControl.Core/Processes/IPayloadInjectorService.cs deleted file mode 100644 index efec9c3..0000000 --- a/YMouseButtonControl.Core/Processes/IPayloadInjectorService.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace YMouseButtonControl.Core.Processes; - -public interface IPayloadInjectorService -{ - void Dispose(); -} diff --git a/YMouseButtonControl.Core/Profiles/Implementations/ProfilesService.cs b/YMouseButtonControl.Core/Profiles/Implementations/ProfilesService.cs deleted file mode 100644 index 8c0dd8b..0000000 --- a/YMouseButtonControl.Core/Profiles/Implementations/ProfilesService.cs +++ /dev/null @@ -1,274 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.IO; -using System.Linq; -using System.Reactive.Linq; -using DynamicData; -using Newtonsoft.Json; -using ReactiveUI; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.DataAccess.UnitOfWork; -using YMouseButtonControl.Core.Profiles.Exceptions; -using YMouseButtonControl.Core.Profiles.Interfaces; - -namespace YMouseButtonControl.Core.Profiles.Implementations; - -public class ProfilesService : ReactiveObject, IProfilesService -{ - private readonly IUnitOfWorkFactory _unitOfWorkFactory; - private Profile? _currentProfile; - private bool _unsavedChanges; - private readonly SourceCache _profiles; - private readonly ReadOnlyObservableCollection _profilesObsCol; - - public ProfilesService(IUnitOfWorkFactory unitOfWorkFactory) - { - _profiles = new SourceCache(x => x.Id); - _profiles - .Connect() - .AutoRefresh() - .SortBy(x => x.DisplayPriority) - .Bind(out _profilesObsCol) - .Subscribe(); - _unitOfWorkFactory = unitOfWorkFactory; - CheckDefaultProfile(); - LoadProfilesFromDb(); - - _profiles - .Connect() - .Subscribe(set => - { - var change = set.Last(); - CurrentProfile = change.Reason switch - { - ChangeReason.Add => change.Current, - ChangeReason.Remove => _profiles - .Items.Where(x => x.DisplayPriority < change.Current.DisplayPriority) - .MaxBy(x => x.DisplayPriority) - ?? throw new Exception("Unable to get next lower priority on remove"), - ChangeReason.Update => change.Current, - _ => throw new Exception("Unhandled change reason"), - }; - }); - - CurrentProfile = - _profiles.Items.MinBy(x => x.DisplayPriority) - ?? throw new Exception("Unable to retrieve current profile"); - - var unsavedChanges = Connect() - .AutoRefresh() - .Select(_ => IsUnsavedChanges()) - .Subscribe(UnsavedChangesHelper); - } - - /// - /// Read only collection of profiles - /// - public ReadOnlyObservableCollection Profiles => _profilesObsCol; - - public void AddOrUpdate(Profile profile) => _profiles.AddOrUpdate(profile); - - public bool UnsavedChanges - { - get => _unsavedChanges; - set => this.RaiseAndSetIfChanged(ref _unsavedChanges, value); - } - - public IObservable> Connect() => _profiles.Connect(); - - public Profile? CurrentProfile - { - get => _currentProfile; - set => this.RaiseAndSetIfChanged(ref _currentProfile, value); - } - - private void CheckDefaultProfile() - { - using var unitOfWork = _unitOfWorkFactory.Create(); - var repository = unitOfWork.GetRepository(); - var model = repository.GetAll(); - if (model.Any(x => x.Name == "Default")) - { - return; - } - var defaultProfile = new Profile - { - Checked = true, - DisplayPriority = 0, - Name = "Default", - IsDefault = true, - Description = "Default description", - Process = "*", - MatchType = "N/A", - ParentClass = "N/A", - WindowCaption = "N/A", - WindowClass = "N/A", - MouseButton1 = new NothingMapping(), - MouseButton2 = new NothingMapping(), - MouseButton3 = new NothingMapping(), - MouseButton4 = new NothingMapping(), - MouseButton5 = new NothingMapping(), - MouseWheelUp = new NothingMapping(), - MouseWheelDown = new NothingMapping(), - MouseWheelLeft = new NothingMapping(), - MouseWheelRight = new NothingMapping(), - }; - repository.Add(defaultProfile); - } - - public Profile CopyProfile(Profile p) - { - var jsonString = JsonConvert.SerializeObject( - p, - new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto } - ); - return JsonConvert.DeserializeObject( - jsonString, - new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto } - ) ?? throw new JsonSerializationException("Error deserializing profile"); - } - - public bool IsUnsavedChanges() - { - using var unitOfWork = _unitOfWorkFactory.Create(); - var repository = unitOfWork.GetRepository(); - var dbProfiles = repository.GetAll().ToList(); - return _profiles.Items.Count() != dbProfiles.Count - || _profiles.Items.Where((p, i) => !p.Equals(dbProfiles[i])).Any(); - } - - public void WriteProfileToFile(Profile p, string path) - { - var jsonString = JsonConvert.SerializeObject( - p, - new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto } - ); - File.WriteAllText(path, jsonString); - } - - public void ImportProfileFromPath(string path) - { - var f = File.ReadAllText(path); - var deserializedProfile = - JsonConvert.DeserializeObject( - f, - new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto } - ) ?? throw new JsonSerializationException("Error deserializing profile"); - AddProfile(deserializedProfile); - } - - public void AddProfile(Profile profile) - { - profile.Id = GetNextProfileId(); - profile.DisplayPriority = GetNextProfileDisplayPriority(); - _profiles.AddOrUpdate(profile); - } - - public void ReplaceProfile(Profile oldProfile, Profile newProfile) - { - if (oldProfile.IsDefault || newProfile.IsDefault) - { - throw new InvalidReplaceException("Cannot replace the default profile"); - } - - newProfile.Id = oldProfile.Id; - _profiles.AddOrUpdate(newProfile); - } - - public void ReplaceProfile(Profile p) - { - if (p.IsDefault) - { - throw new InvalidReplaceException("Cannot replace the default profile"); - } - - _profiles.AddOrUpdate(p); - } - - public void MoveProfileUp(Profile p) - { - if (p.IsDefault) - { - throw new InvalidMoveException("Cannot move the default profile"); - } - - var nextSmallerPriority = _profiles - .Items.Where(x => x.DisplayPriority < p.DisplayPriority) - .MaxBy(x => x.DisplayPriority); - if (nextSmallerPriority is null) - { - throw new InvalidMoveException( - "Unable to retrieve max display index from profiles cache" - ); - } - - if (nextSmallerPriority.IsDefault) - { - throw new InvalidMoveException("Cannot move profile above default profile"); - } - - // swap priorities - (nextSmallerPriority.DisplayPriority, p.DisplayPriority) = ( - p.DisplayPriority, - nextSmallerPriority.DisplayPriority - ); - } - - public void MoveProfileDown(Profile p) - { - if (p.IsDefault) - { - throw new InvalidMoveException("Cannot move the default profile"); - } - - var nextLargerPriority = _profiles - .Items.Where(x => x.DisplayPriority > p.DisplayPriority) - .MinBy(x => x.DisplayPriority); - if (nextLargerPriority is null) - { - throw new InvalidMoveException( - "Unable to retrieve max display index from profiles cache" - ); - } - - // swap priorities - (nextLargerPriority.DisplayPriority, p.DisplayPriority) = ( - p.DisplayPriority, - nextLargerPriority.DisplayPriority - ); - } - - public void RemoveProfile(Profile profile) - { - if (profile.Name == "Default") - { - throw new Exception("Attempted to remove default profile"); - } - - var nextSmallerPriority = _profiles - .Items.Where(x => x.DisplayPriority < profile.DisplayPriority) - .MaxBy(x => x.DisplayPriority); - if (nextSmallerPriority is null) - { - throw new Exception("Unable to find next profile to set as current profile"); - } - - _profiles.Remove(profile); - CurrentProfile = nextSmallerPriority; - } - - private void LoadProfilesFromDb() - { - using var unitOfWork = _unitOfWorkFactory.Create(); - var repository = unitOfWork.GetRepository(); - var model = repository.GetAll(); - _profiles.AddOrUpdate(model); - } - - private int GetNextProfileId() => _profiles.Items.Max(x => x.Id) + 1; - - private int GetNextProfileDisplayPriority() => _profiles.Items.Max(x => x.DisplayPriority) + 1; - - private void UnsavedChangesHelper(bool next) => UnsavedChanges = next; -} diff --git a/YMouseButtonControl.Core/Profiles/Implementations/SettingsService.cs b/YMouseButtonControl.Core/Profiles/Implementations/SettingsService.cs deleted file mode 100644 index 59fab38..0000000 --- a/YMouseButtonControl.Core/Profiles/Implementations/SettingsService.cs +++ /dev/null @@ -1,76 +0,0 @@ -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; - -public class SettingsService : ReactiveObject, ISettingsService -{ - private readonly IUnitOfWorkFactory _unitOfWorkFactory; - private readonly SourceCache _settings; - - public SettingsService(IUnitOfWorkFactory unitOfWorkFactory) - { - _unitOfWorkFactory = unitOfWorkFactory; - _settings = new SourceCache(x => x.Id); - CheckDefaultSettings(); - LoadSettingsFromDb(); - } - - public IObservable> Connect() => _settings.Connect(); - - public bool IsUnsavedChanges() - { - using var unitOfWork = _unitOfWorkFactory.Create(); - var repository = unitOfWork.GetRepository(); - var dbSettings = repository.GetAll().ToList(); - return _settings.Items.Count() != dbSettings.Count - || _settings.Items.Where((p, i) => !p.Equals(dbSettings[i])).Any(); - } - - public Setting? GetSetting(string 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() - { - using var unitOfWork = _unitOfWorkFactory.Create(); - var repository = unitOfWork.GetRepository(); - var model = repository.GetAll(); - _settings.AddOrUpdate(model); - } - - private void CheckDefaultSettings() - { - using var uow = _unitOfWorkFactory.Create(); - var repo = uow.GetRepository(); - var model = repo.GetAll(); - if (model.Any(x => x.Name == "StartMinimized")) - { - return; - } - - var startMinimizedSetting = new Setting { Name = "StartMinimized", Value = "false" }; - repo.Add(startMinimizedSetting); - - uow.SaveChanges(); - } -} diff --git a/YMouseButtonControl.Core/Profiles/Interfaces/IProfilesService.cs b/YMouseButtonControl.Core/Profiles/Interfaces/IProfilesService.cs deleted file mode 100644 index 6c7a369..0000000 --- a/YMouseButtonControl.Core/Profiles/Interfaces/IProfilesService.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.ObjectModel; -using DynamicData; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; - -namespace YMouseButtonControl.Core.Profiles.Interfaces; - -public interface IProfilesService -{ - bool UnsavedChanges { get; set; } - Profile? CurrentProfile { get; set; } - ReadOnlyObservableCollection Profiles { get; } - IObservable> Connect(); - Profile CopyProfile(Profile p); - bool IsUnsavedChanges(); - void WriteProfileToFile(Profile p, string path); - void ImportProfileFromPath(string path); - void AddProfile(Profile profile); - void ReplaceProfile(Profile oldProfile, Profile newProfile); - void MoveProfileUp(Profile p); - void MoveProfileDown(Profile p); - void RemoveProfile(Profile profile); - void AddOrUpdate(Profile profile); -} diff --git a/YMouseButtonControl.Core/Profiles/Interfaces/ISettingsService.cs b/YMouseButtonControl.Core/Profiles/Interfaces/ISettingsService.cs deleted file mode 100644 index 29024c8..0000000 --- a/YMouseButtonControl.Core/Profiles/Interfaces/ISettingsService.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using DynamicData; -using YMouseButtonControl.Core.DataAccess.Models.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/Repositories/GenericRepository.cs b/YMouseButtonControl.Core/Repositories/GenericRepository.cs new file mode 100644 index 0000000..76bf53d --- /dev/null +++ b/YMouseButtonControl.Core/Repositories/GenericRepository.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; +using AutoMapper; +using Microsoft.EntityFrameworkCore; +using YMouseButtonControl.DataAccess.Context; + +namespace YMouseButtonControl.Core.Repositories; + +public interface IGenericRepository + where TEntity : class + where TVm : class +{ + TVm? Add(TVm vm); + Task AddAsync(TVm vm); + IEnumerable Get( + Expression>? filter = null, + Func, IOrderedQueryable>? orderBy = null, + string includeProperties = "" + ); + Task> GetAllAsync(); + Task> GetAllAsync(Expression> filter); + Task GetAsync(Expression> filter); + TVm? GetById(int id); + Task GetByIdAsync(int id); + TVm? Remove(int id); + Task RemoveAsync(int id); + TVm? Update(int id, TVm vm); + Task UpdateAsync(int id, TVm vm); +} + +public class GenericRepository(YMouseButtonControlDbContext context, IMapper mapper) + : IGenericRepository + where TEntity : class + where TVm : class +{ + private readonly YMouseButtonControlDbContext _context = context; + private readonly DbSet _dbSet = context.Set(); + private readonly IMapper _mapper = mapper; + + public virtual IEnumerable Get( + Expression>? filter = null, + Func, IOrderedQueryable>? orderBy = null, + string includeProperties = "" + ) + { + IQueryable query = _dbSet; + + if (filter != null) + { + query = query.Where(filter); + } + + query = includeProperties + .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) + .Aggregate(query, (current, includeProperty) => current.Include(includeProperty)); + + // query = query.AsNoTracking(); + + return _mapper.Map>( + orderBy != null ? orderBy(query).ToList() : query.ToList() + ); + } + + public async Task> GetAllAsync() => + _mapper.Map>(await _dbSet.ToListAsync()); + + public async Task> GetAllAsync(Expression> filter) => + _mapper.Map>(await _dbSet.Where(filter).ToListAsync()); + + public async Task GetAsync(Expression> filter) => + _mapper.Map(await _dbSet.FirstOrDefaultAsync(filter)); + + public TVm? GetById(int id) => _mapper.Map(_dbSet.Find(id)); + + public async Task GetByIdAsync(int id) => _mapper.Map(await _dbSet.FindAsync(id)); + + public TVm? Add(TVm vm) + { + var entity = _dbSet.Add(_mapper.Map(vm)).Entity; + return _mapper.Map(entity); + } + + public async Task AddAsync(TVm vm) + { + var entity = (await _dbSet.AddAsync(_mapper.Map(vm))).Entity; + return _mapper.Map(entity); + } + + /// + /// Add or update view model + /// + /// + /// + /// + public TVm? Update(int id, TVm vm) + { + var entity = _dbSet.Find(id); + return entity is null + ? _mapper.Map((_dbSet.Add(_mapper.Map(vm))).Entity) + : _mapper.Map(_mapper.Map(vm, entity)); + } + + public async Task UpdateAsync(int id, TVm vm) + { + var entity = await _dbSet.FindAsync(id); + return entity is null + ? _mapper.Map((await _dbSet.AddAsync(_mapper.Map(vm))).Entity) + : _mapper.Map(_mapper.Map(vm, entity)); + } + + public TVm? Remove(int id) + { + var entity = _dbSet.Find(id); + if (entity is not null) + { + _dbSet.Remove(entity); + } + return _mapper.Map(entity); + } + + public async Task RemoveAsync(int id) + { + var entity = await _dbSet.FindAsync(id); + if (entity is not null) + { + _dbSet.Remove(entity); + } + return _mapper.Map(entity); + } +} diff --git a/YMouseButtonControl.Core/Repositories/UnitOfWork.cs b/YMouseButtonControl.Core/Repositories/UnitOfWork.cs new file mode 100644 index 0000000..2e969ac --- /dev/null +++ b/YMouseButtonControl.Core/Repositories/UnitOfWork.cs @@ -0,0 +1,64 @@ +using System; +using System.Threading.Tasks; +using YMouseButtonControl.Core.ViewModels.Models; +using YMouseButtonControl.DataAccess.Context; +using YMouseButtonControl.DataAccess.Models; +using Profile = YMouseButtonControl.DataAccess.Models.Profile; + +namespace YMouseButtonControl.Core.Repositories; + +public interface IUnitOfWork +{ + IGenericRepository ProfileRepo { get; init; } + IGenericRepository ButtonMappingRepo { get; init; } + IGenericRepository SettingRepo { get; init; } + IGenericRepository SettingBoolRepo { get; init; } + IGenericRepository SettingStringRepo { get; init; } + void Save(); + Task SaveAsync(); + void Dispose(); +} + +public class UnitOfWork( + YMouseButtonControlDbContext context, + IGenericRepository profileRepo, + IGenericRepository buttonMappingRepo, + IGenericRepository settingRepo, + IGenericRepository settingBoolRepo, + IGenericRepository settingStringRepo +) : IUnitOfWork +{ + private readonly YMouseButtonControlDbContext _context = context; + public IGenericRepository ProfileRepo { get; init; } = profileRepo; + public IGenericRepository ButtonMappingRepo { get; init; } = + buttonMappingRepo; + public IGenericRepository SettingRepo { get; init; } = settingRepo; + public IGenericRepository SettingBoolRepo { get; init; } = + settingBoolRepo; + public IGenericRepository SettingStringRepo { get; init; } = + settingStringRepo; + + public void Save() => _context.SaveChanges(); + + public async Task SaveAsync() => await _context.SaveChangesAsync(); + + private bool _disposed; + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + _context.Dispose(); + } + } + _disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } +} diff --git a/YMouseButtonControl.Core/Services/Abstractions/Models/EventArgs/NewMouseWheelEventArgs.cs b/YMouseButtonControl.Core/Services/Abstractions/Models/EventArgs/NewMouseWheelEventArgs.cs deleted file mode 100644 index f004d80..0000000 --- a/YMouseButtonControl.Core/Services/Abstractions/Models/EventArgs/NewMouseWheelEventArgs.cs +++ /dev/null @@ -1,8 +0,0 @@ -using YMouseButtonControl.Core.Services.Abstractions.Enums; - -namespace YMouseButtonControl.Core.Services.Abstractions.Models.EventArgs; - -public class NewMouseWheelEventArgs(WheelScrollDirection direction) -{ - public WheelScrollDirection Direction { get; } = direction; -} diff --git a/YMouseButtonControl.Core/Services/KeyboardAndMouse/Enums/MouseButtonState.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Enums/MouseButtonState.cs new file mode 100644 index 0000000..3539a7a --- /dev/null +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Enums/MouseButtonState.cs @@ -0,0 +1,7 @@ +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Enums; + +public enum MouseButtonState +{ + Pressed, + Released, +} diff --git a/YMouseButtonControl.Core/Services/Abstractions/Enums/WheelScrollDirection.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Enums/WheelScrollDirection.cs similarity index 64% rename from YMouseButtonControl.Core/Services/Abstractions/Enums/WheelScrollDirection.cs rename to YMouseButtonControl.Core/Services/KeyboardAndMouse/Enums/WheelScrollDirection.cs index e9d8f4d..2463d1a 100644 --- a/YMouseButtonControl.Core/Services/Abstractions/Enums/WheelScrollDirection.cs +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Enums/WheelScrollDirection.cs @@ -1,4 +1,4 @@ -namespace YMouseButtonControl.Core.Services.Abstractions.Enums; +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Enums; public enum WheelScrollDirection { diff --git a/YMouseButtonControl.Core/DataAccess/Models/Enums/YMouseButton.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Enums/YMouseButton.cs similarity index 74% rename from YMouseButtonControl.Core/DataAccess/Models/Enums/YMouseButton.cs rename to YMouseButtonControl.Core/Services/KeyboardAndMouse/Enums/YMouseButton.cs index ab4b19f..771372a 100644 --- a/YMouseButtonControl.Core/DataAccess/Models/Enums/YMouseButton.cs +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Enums/YMouseButton.cs @@ -1,4 +1,4 @@ -namespace YMouseButtonControl.Core.DataAccess.Models.Enums; +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Enums; public enum YMouseButton : ushort { diff --git a/YMouseButtonControl.Core/Services/Abstractions/Models/EventArgs/NewMouseHookEventArgs.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/EventArgs/NewMouseHookEventArgs.cs similarity index 68% rename from YMouseButtonControl.Core/Services/Abstractions/Models/EventArgs/NewMouseHookEventArgs.cs rename to YMouseButtonControl.Core/Services/KeyboardAndMouse/EventArgs/NewMouseHookEventArgs.cs index 3721ee6..28b4a9e 100644 --- a/YMouseButtonControl.Core/Services/Abstractions/Models/EventArgs/NewMouseHookEventArgs.cs +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/EventArgs/NewMouseHookEventArgs.cs @@ -1,6 +1,6 @@ -using YMouseButtonControl.Core.DataAccess.Models.Enums; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Enums; -namespace YMouseButtonControl.Core.Services.Abstractions.Models.EventArgs; +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.EventArgs; public class NewMouseHookEventArgs(YMouseButton button, short x, short y, string? activeWindow) : System.EventArgs diff --git a/YMouseButtonControl.Core/Services/Abstractions/Models/EventArgs/NewMouseHookMoveEventArgs.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/EventArgs/NewMouseHookMoveEventArgs.cs similarity index 65% rename from YMouseButtonControl.Core/Services/Abstractions/Models/EventArgs/NewMouseHookMoveEventArgs.cs rename to YMouseButtonControl.Core/Services/KeyboardAndMouse/EventArgs/NewMouseHookMoveEventArgs.cs index f4adbcb..3aa53b7 100644 --- a/YMouseButtonControl.Core/Services/Abstractions/Models/EventArgs/NewMouseHookMoveEventArgs.cs +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/EventArgs/NewMouseHookMoveEventArgs.cs @@ -1,4 +1,4 @@ -namespace YMouseButtonControl.Core.Services.Abstractions.Models.EventArgs; +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.EventArgs; public class NewMouseHookMoveEventArgs(short x, short y) : System.EventArgs { diff --git a/YMouseButtonControl.Core/Services/KeyboardAndMouse/EventArgs/NewMouseWheelEventArgs.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/EventArgs/NewMouseWheelEventArgs.cs new file mode 100644 index 0000000..c41a6c3 --- /dev/null +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/EventArgs/NewMouseWheelEventArgs.cs @@ -0,0 +1,8 @@ +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Enums; + +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.EventArgs; + +public class NewMouseWheelEventArgs(WheelScrollDirection direction) +{ + public WheelScrollDirection Direction { get; } = direction; +} diff --git a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/EventSimulatorService.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/EventSimulatorService.cs similarity index 92% rename from YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/EventSimulatorService.cs rename to YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/EventSimulatorService.cs index fa4290c..1baebe7 100644 --- a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/EventSimulatorService.cs +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/EventSimulatorService.cs @@ -4,10 +4,35 @@ using Serilog; using SharpHook; using SharpHook.Native; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Models; -namespace YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations; +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations; + +public interface IEventSimulatorService +{ + /// + /// Keys to be pressed in order. + /// + /// Keys to be pressed + void PressKeys(string? keys); + + /// + /// Keys will be released in the reversed order they come. For example, sending abc to this method will release cba + /// in that order. + /// + /// Keys to be released + void ReleaseKeys(string? keys); + + void TapKeys(string? keys); + void SimulateMousePress(MouseButton mb); + void SimulateMouseRelease(MouseButton mb); + + /// + /// TODO + /// + /// + /// Optional delay between key presses + void TapKeys(string? keys, int delay, CancellationToken cancellationToken); +} public class EventSimulatorService(IEventSimulator eventSimulator) : IEventSimulatorService { @@ -25,26 +50,16 @@ public void SimulateMouseRelease(MouseButton mb) t.Start(); } - public SimulateKeyboardResult SimulateKeyPress(string? key) + public void SimulateKeyPress(string? key) { _logger.Information("Simulate press {Key}", key); - return new SimulateKeyboardResult - { - Result = eventSimulator - .SimulateKeyPress(KeyCodes[key ?? throw new NullReferenceException(key)]) - .ToString(), - }; + eventSimulator.SimulateKeyPress(KeyCodes[key ?? throw new NullReferenceException(key)]); } - public SimulateKeyboardResult SimulateKeyRelease(string? key) + public void SimulateKeyRelease(string? key) { _logger.Information("Simulate release {Key}", key); - return new SimulateKeyboardResult - { - Result = eventSimulator - .SimulateKeyRelease(KeyCodes[key ?? throw new NullReferenceException(key)]) - .ToString(), - }; + eventSimulator.SimulateKeyRelease(KeyCodes[key ?? throw new NullReferenceException(key)]); } /// @@ -52,13 +67,12 @@ public SimulateKeyboardResult SimulateKeyRelease(string? key) /// /// /// - public SimulateKeyboardResult SimulateKeyTap(string? key) + public void SimulateKeyTap(string? key) { _logger.Information("Simulate key tap {Key}", key); var keyCode = KeyCodes[key ?? throw new NullReferenceException(key)]; eventSimulator.SimulateKeyPress(keyCode); eventSimulator.SimulateKeyRelease(keyCode); - return new SimulateKeyboardResult { Result = "Success" }; } /// @@ -507,3 +521,10 @@ private static List ParseKeys(string? keys) { "mb5", MouseButton.Button5 }, }; } + +internal class ParsedKey +{ + public string? Key { get; set; } + public bool IsModifier { get; set; } + public ushort Value { get; set; } +} diff --git a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/MouseListenerService.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/MouseListenerService.cs similarity index 93% rename from YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/MouseListenerService.cs rename to YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/MouseListenerService.cs index 9589d7d..4cc1397 100644 --- a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/MouseListenerService.cs +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/MouseListenerService.cs @@ -1,20 +1,26 @@ using System; using System.Linq; -using System.Net; using System.Reactive.Linq; using System.Threading; using Serilog; using SharpHook; using SharpHook.Native; using SharpHook.Reactive; -using YMouseButtonControl.Core.DataAccess.Models.Enums; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; -using YMouseButtonControl.Core.Processes; -using YMouseButtonControl.Core.Profiles.Interfaces; -using YMouseButtonControl.Core.Services.Abstractions.Enums; -using YMouseButtonControl.Core.Services.Abstractions.Models.EventArgs; - -namespace YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Enums; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.EventArgs; +using YMouseButtonControl.Core.Services.Processes; +using YMouseButtonControl.Core.Services.Profiles; + +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations; + +public interface IMouseListener : IDisposable +{ + event EventHandler OnMouseMovedEventHandler; + event EventHandler OnMousePressedEventHandler; + event EventHandler OnMouseReleasedEventHandler; + event EventHandler OnMouseWheelEventHandler; + void Run(); +} /// /// Wrapper around sharphook for listening to mouse events diff --git a/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/AsMouseButtonPressedService.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/AsMouseButtonPressedService.cs new file mode 100644 index 0000000..8cdb803 --- /dev/null +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/AsMouseButtonPressedService.cs @@ -0,0 +1,24 @@ +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Enums; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Interfaces; +using YMouseButtonControl.Core.ViewModels.Models; + +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations.SimulatedKeystrokesTypes; + +public interface IAsMouseButtonPressedService +{ + void AsMouseButtonPressed(BaseButtonMappingVm mapping, MouseButtonState state); +} + +public class AsMouseButtonPressedService(IEventSimulatorService eventSimulatorService) + : IAsMouseButtonPressedService +{ + public void AsMouseButtonPressed(BaseButtonMappingVm mapping, MouseButtonState state) + { + if (state != MouseButtonState.Pressed) + { + return; + } + + eventSimulatorService.TapKeys(mapping.Keys); + } +} diff --git a/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/AsMouseButtonReleasedService.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/AsMouseButtonReleasedService.cs new file mode 100644 index 0000000..c090230 --- /dev/null +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/AsMouseButtonReleasedService.cs @@ -0,0 +1,24 @@ +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Enums; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Interfaces; +using YMouseButtonControl.Core.ViewModels.Models; + +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations.SimulatedKeystrokesTypes; + +public interface IAsMouseButtonReleasedService +{ + void AsMouseButtonReleased(BaseButtonMappingVm mapping, MouseButtonState state); +} + +public class AsMouseButtonReleasedService(IEventSimulatorService eventSimulatorService) + : IAsMouseButtonReleasedService +{ + public void AsMouseButtonReleased(BaseButtonMappingVm mapping, MouseButtonState state) + { + if (state != MouseButtonState.Released) + { + return; + } + + eventSimulatorService.TapKeys(mapping.Keys); + } +} diff --git a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/DuringMousePressAndReleaseService.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/DuringMousePressAndReleaseService.cs similarity index 52% rename from YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/DuringMousePressAndReleaseService.cs rename to YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/DuringMousePressAndReleaseService.cs index 3f5439a..9350b58 100644 --- a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/DuringMousePressAndReleaseService.cs +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/DuringMousePressAndReleaseService.cs @@ -1,14 +1,19 @@ using System; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Enums; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Enums; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Interfaces; +using YMouseButtonControl.Core.ViewModels.Models; -namespace YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations.SimulatedKeystrokesTypes; +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations.SimulatedKeystrokesTypes; + +public interface IDuringMousePressAndReleaseService +{ + void DuringMousePressAndRelease(BaseButtonMappingVm mapping, MouseButtonState state); +} public class DuringMousePressAndReleaseService(IEventSimulatorService eventSimulatorService) : IDuringMousePressAndReleaseService { - public void DuringMousePressAndRelease(IButtonMapping mapping, MouseButtonState state) + public void DuringMousePressAndRelease(BaseButtonMappingVm mapping, MouseButtonState state) { switch (state) { diff --git a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/RepeatedWhileButtonDownService.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/RepeatedWhileButtonDownService.cs similarity index 74% rename from YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/RepeatedWhileButtonDownService.cs rename to YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/RepeatedWhileButtonDownService.cs index 88d5de8..a500679 100644 --- a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/RepeatedWhileButtonDownService.cs +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/RepeatedWhileButtonDownService.cs @@ -1,10 +1,15 @@ using System; using System.Threading; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Enums; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Enums; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Interfaces; +using YMouseButtonControl.Core.ViewModels.Models; -namespace YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations.SimulatedKeystrokesTypes; +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations.SimulatedKeystrokesTypes; + +public interface IRepeatedWhileButtonDownService +{ + void RepeatWhileDown(BaseButtonMappingVm mapping, MouseButtonState state); +} public class RepeatedWhileButtonDownService(IEventSimulatorService eventSimulatorService) : IRepeatedWhileButtonDownService @@ -14,7 +19,7 @@ public class RepeatedWhileButtonDownService(IEventSimulatorService eventSimulato private readonly object _lock = new(); private const int RepeatRateMs = 33; - public void RepeatWhileDown(IButtonMapping mapping, MouseButtonState state) + public void RepeatWhileDown(BaseButtonMappingVm mapping, MouseButtonState state) { switch (state) { diff --git a/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/StickyHoldService.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/StickyHoldService.cs new file mode 100644 index 0000000..99e037e --- /dev/null +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/StickyHoldService.cs @@ -0,0 +1,32 @@ +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Enums; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Interfaces; +using YMouseButtonControl.Core.ViewModels.Models; + +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations.SimulatedKeystrokesTypes; + +public interface IStickyHoldService +{ + void StickyHold(BaseButtonMappingVm mapping, MouseButtonState state); +} + +public class StickyHoldService(IEventSimulatorService eventSimulatorService) : IStickyHoldService +{ + public void StickyHold(BaseButtonMappingVm mapping, MouseButtonState state) + { + if (state != MouseButtonState.Pressed) + { + return; + } + + if (mapping.State) + { + eventSimulatorService.ReleaseKeys(mapping.Keys); + mapping.State = false; + } + else + { + eventSimulatorService.PressKeys(mapping.Keys); + mapping.State = true; + } + } +} diff --git a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/StickyRepeatService.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/StickyRepeatService.cs similarity index 67% rename from YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/StickyRepeatService.cs rename to YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/StickyRepeatService.cs index 720dd31..07eaa59 100644 --- a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/StickyRepeatService.cs +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedKeystrokesTypes/StickyRepeatService.cs @@ -1,10 +1,15 @@ using System.Threading; using Serilog; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Enums; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Enums; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Interfaces; +using YMouseButtonControl.Core.ViewModels.Models; -namespace YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations.SimulatedKeystrokesTypes; +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations.SimulatedKeystrokesTypes; + +public interface IStickyRepeatService +{ + void StickyRepeat(BaseButtonMappingVm mapping, MouseButtonState state); +} public class StickyRepeatService(IEventSimulatorService eventSimulatorService) : IStickyRepeatService @@ -16,7 +21,7 @@ public class StickyRepeatService(IEventSimulatorService eventSimulatorService) private CancellationTokenSource? _cts; private readonly ILogger _log = Log.Logger.ForContext(); - public void StickyRepeat(IButtonMapping mapping, MouseButtonState state) + public void StickyRepeat(BaseButtonMappingVm mapping, MouseButtonState state) { if (state != MouseButtonState.Pressed) { @@ -31,7 +36,7 @@ public void StickyRepeat(IButtonMapping mapping, MouseButtonState state) { lock (_lock) { - _log.Information("=====CANCELATION REQUESTED======="); + _log.Information("=====CANCELLATION REQUESTED======="); _cts?.Cancel(); _shouldStop = true; } @@ -47,7 +52,7 @@ public void StickyRepeat(IButtonMapping mapping, MouseButtonState state) } } - private void StartThread(IButtonMapping mapping) + private void StartThread(BaseButtonMappingVm mapping) { _cts = new CancellationTokenSource(); _thread = new Thread(() => @@ -58,7 +63,7 @@ private void StartThread(IButtonMapping mapping) { if (_shouldStop) { - _log.Information("=====CANCELATION REQUESTED======="); + _log.Information("=====CANCELLATION REQUESTED======="); _cts.Cancel(); break; } diff --git a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedMousePressTypes/RightClick.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedMousePressTypes/RightClick.cs similarity index 72% rename from YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedMousePressTypes/RightClick.cs rename to YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedMousePressTypes/RightClick.cs index 1fe1086..57a731b 100644 --- a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedMousePressTypes/RightClick.cs +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedMousePressTypes/RightClick.cs @@ -1,11 +1,15 @@ using System; using System.Threading; using SharpHook.Native; -using YMouseButtonControl.Core.DataAccess.Models.Enums; -using YMouseButtonControl.Core.KeyboardAndMouse.Enums; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Enums; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Interfaces; -namespace YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations.SimulatedMousePressTypes; +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations.SimulatedMousePressTypes; + +public interface IRightClick +{ + void SimulateRightClick(MouseButtonState state); +} public class RightClick(IEventSimulatorService eventSimulatorService) : IRightClick { diff --git a/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedMousePressTypes/StickyHoldLeftClick.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedMousePressTypes/StickyHoldLeftClick.cs new file mode 100644 index 0000000..7cf882d --- /dev/null +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Implementations/SimulatedMousePressTypes/StickyHoldLeftClick.cs @@ -0,0 +1,3 @@ +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations.SimulatedMousePressTypes; + +public class StickyHoldLeftClick { } diff --git a/YMouseButtonControl.Core/Services/KeyboardAndMouse/Interfaces/ISkipProfileService.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Interfaces/ISkipProfileService.cs new file mode 100644 index 0000000..b2c928c --- /dev/null +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/Interfaces/ISkipProfileService.cs @@ -0,0 +1,9 @@ +using YMouseButtonControl.Core.Services.KeyboardAndMouse.EventArgs; +using YMouseButtonControl.Core.ViewModels.Models; + +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse.Interfaces; + +public interface ISkipProfileService +{ + bool ShouldSkipProfile(ProfileVm p, NewMouseHookEventArgs e); +} diff --git a/YMouseButtonControl.Core/KeyboardAndMouse/KeyboardSimulatorWorker.cs b/YMouseButtonControl.Core/Services/KeyboardAndMouse/KeyboardSimulatorWorker.cs similarity index 78% rename from YMouseButtonControl.Core/KeyboardAndMouse/KeyboardSimulatorWorker.cs rename to YMouseButtonControl.Core/Services/KeyboardAndMouse/KeyboardSimulatorWorker.cs index e457af2..c43ba42 100644 --- a/YMouseButtonControl.Core/KeyboardAndMouse/KeyboardSimulatorWorker.cs +++ b/YMouseButtonControl.Core/Services/KeyboardAndMouse/KeyboardSimulatorWorker.cs @@ -1,15 +1,15 @@ using System; using Serilog; -using YMouseButtonControl.Core.DataAccess.Models.Enums; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Enums; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; -using YMouseButtonControl.Core.Profiles.Interfaces; -using YMouseButtonControl.Core.Services.Abstractions.Models.EventArgs; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Enums; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.EventArgs; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations.SimulatedKeystrokesTypes; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations.SimulatedMousePressTypes; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Interfaces; +using YMouseButtonControl.Core.Services.Profiles; +using YMouseButtonControl.Core.ViewModels.Models; -namespace YMouseButtonControl.Core.KeyboardAndMouse; +namespace YMouseButtonControl.Core.Services.KeyboardAndMouse; public class KeyboardSimulatorWorker( IProfilesService profilesService, @@ -85,7 +85,7 @@ private void OnMouseReleased(object? sender, NewMouseHookEventArgs e) } } - private void RouteMouseButton(YMouseButton yMouseButton, Profile p, MouseButtonState state) + private void RouteMouseButton(YMouseButton yMouseButton, ProfileVm p, MouseButtonState state) { switch (yMouseButton) { @@ -121,39 +121,42 @@ private void RouteMouseButton(YMouseButton yMouseButton, Profile p, MouseButtonS } } - private void RouteButtonMapping(IButtonMapping mapping, MouseButtonState state) + private void RouteButtonMapping(BaseButtonMappingVm mapping, MouseButtonState state) { switch (mapping) { - case SimulatedKeystrokes: + case SimulatedKeystrokeVm: RouteSimulatedKeystrokesType(mapping, state); break; - case RightClick: + case RightClickVm: rightClick.SimulateRightClick(state); break; } } - private void RouteSimulatedKeystrokesType(IButtonMapping buttonMapping, MouseButtonState state) + private void RouteSimulatedKeystrokesType( + BaseButtonMappingVm buttonMapping, + MouseButtonState state + ) { - switch (buttonMapping.SimulatedKeystrokesType) + switch (buttonMapping.SimulatedKeystrokeType) { - case MouseButtonPressedActionType: + case MouseButtonPressedActionTypeVm: asMouseButtonPressedService.AsMouseButtonPressed(buttonMapping, state); break; - case MouseButtonReleasedActionType: + case MouseButtonReleasedActionTypeVm: asMouseButtonReleasedService.AsMouseButtonReleased(buttonMapping, state); break; - case DuringMouseActionType: + case DuringMouseActionTypeVm: duringMousePressAndReleaseService.DuringMousePressAndRelease(buttonMapping, state); break; - case RepeatedlyWhileButtonDownActionType: + case RepeatedlyWhileButtonDownActionTypeVm: repeatedWhileButtonDownService.RepeatWhileDown(buttonMapping, state); break; - case StickyRepeatActionType: + case StickyRepeatActionTypeVm: stickyRepeatService.StickyRepeat(buttonMapping, state); break; - case StickyHoldActionType: + case StickyHoldActionTypeVm: stickyHoldService.StickyHold(buttonMapping, state); break; } diff --git a/YMouseButtonControl.Core/Processes/ICurrentWindowService.cs b/YMouseButtonControl.Core/Services/Processes/ICurrentWindowService.cs similarity index 58% rename from YMouseButtonControl.Core/Processes/ICurrentWindowService.cs rename to YMouseButtonControl.Core/Services/Processes/ICurrentWindowService.cs index b85ea20..bd0d5fb 100644 --- a/YMouseButtonControl.Core/Processes/ICurrentWindowService.cs +++ b/YMouseButtonControl.Core/Services/Processes/ICurrentWindowService.cs @@ -1,4 +1,4 @@ -namespace YMouseButtonControl.Core.Processes; +namespace YMouseButtonControl.Core.Services.Processes; public interface ICurrentWindowService { diff --git a/YMouseButtonControl.Core/Processes/IProcessMonitorService.cs b/YMouseButtonControl.Core/Services/Processes/IProcessMonitorService.cs similarity index 54% rename from YMouseButtonControl.Core/Processes/IProcessMonitorService.cs rename to YMouseButtonControl.Core/Services/Processes/IProcessMonitorService.cs index 50a3209..89ffa37 100644 --- a/YMouseButtonControl.Core/Processes/IProcessMonitorService.cs +++ b/YMouseButtonControl.Core/Services/Processes/IProcessMonitorService.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; -using YMouseButtonControl.Core.Services.Abstractions.Models; -namespace YMouseButtonControl.Core.Processes; +namespace YMouseButtonControl.Core.Services.Processes; public interface IProcessMonitorService { diff --git a/YMouseButtonControl.Core/Services/Abstractions/Models/ProcessModel.cs b/YMouseButtonControl.Core/Services/Processes/ProcessModel.cs similarity index 83% rename from YMouseButtonControl.Core/Services/Abstractions/Models/ProcessModel.cs rename to YMouseButtonControl.Core/Services/Processes/ProcessModel.cs index 8d50caf..ee6ff13 100644 --- a/YMouseButtonControl.Core/Services/Abstractions/Models/ProcessModel.cs +++ b/YMouseButtonControl.Core/Services/Processes/ProcessModel.cs @@ -3,7 +3,7 @@ using System.IO; using ReactiveUI; -namespace YMouseButtonControl.Core.Services.Abstractions.Models; +namespace YMouseButtonControl.Core.Services.Processes; public class ProcessModel(Process process) : ReactiveObject, IDisposable { diff --git a/YMouseButtonControl.Core/Profiles/Exceptions/InvalidMoveException.cs b/YMouseButtonControl.Core/Services/Profiles/Exceptions/InvalidMoveException.cs similarity index 82% rename from YMouseButtonControl.Core/Profiles/Exceptions/InvalidMoveException.cs rename to YMouseButtonControl.Core/Services/Profiles/Exceptions/InvalidMoveException.cs index 9234543..732c5f1 100644 --- a/YMouseButtonControl.Core/Profiles/Exceptions/InvalidMoveException.cs +++ b/YMouseButtonControl.Core/Services/Profiles/Exceptions/InvalidMoveException.cs @@ -1,6 +1,6 @@ using System; -namespace YMouseButtonControl.Core.Profiles.Exceptions; +namespace YMouseButtonControl.Core.Services.Profiles.Exceptions; public class InvalidMoveException : Exception { diff --git a/YMouseButtonControl.Core/Profiles/Exceptions/InvalidReplaceException.cs b/YMouseButtonControl.Core/Services/Profiles/Exceptions/InvalidReplaceException.cs similarity index 82% rename from YMouseButtonControl.Core/Profiles/Exceptions/InvalidReplaceException.cs rename to YMouseButtonControl.Core/Services/Profiles/Exceptions/InvalidReplaceException.cs index c2151d3..f7ea706 100644 --- a/YMouseButtonControl.Core/Profiles/Exceptions/InvalidReplaceException.cs +++ b/YMouseButtonControl.Core/Services/Profiles/Exceptions/InvalidReplaceException.cs @@ -1,6 +1,6 @@ using System; -namespace YMouseButtonControl.Core.Profiles.Exceptions; +namespace YMouseButtonControl.Core.Services.Profiles.Exceptions; public class InvalidReplaceException : Exception { diff --git a/YMouseButtonControl.Core/Services/Profiles/ProfilesService.cs b/YMouseButtonControl.Core/Services/Profiles/ProfilesService.cs new file mode 100644 index 0000000..dfa869c --- /dev/null +++ b/YMouseButtonControl.Core/Services/Profiles/ProfilesService.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Reactive.Linq; +using Avalonia.Media.TextFormatting.Unicode; +using DynamicData; +using DynamicData.Binding; +using Newtonsoft.Json; +using ReactiveUI; +using YMouseButtonControl.Core.Repositories; +using YMouseButtonControl.Core.Services.Profiles.Exceptions; +using YMouseButtonControl.Core.ViewModels.Models; + +namespace YMouseButtonControl.Core.Services.Profiles; + +public interface IProfilesService +{ + ProfileVm? CurrentProfile { get; set; } + ReadOnlyObservableCollection Profiles { get; } + IObservable> Connect(); + ProfileVm CopyProfile(ProfileVm p); + void WriteProfileToFile(ProfileVm p, string path); + void ImportProfileFromPath(string path); + void AddProfile(ProfileVm profileVm); + void ReplaceProfile(ProfileVm oldProfileVm, ProfileVm newProfileVm); + void MoveProfileUp(ProfileVm p); + void MoveProfileDown(ProfileVm p); + void RemoveProfile(ProfileVm profileVm); + void AddOrUpdate(ProfileVm profileVm); +} + +public class ProfilesService : ReactiveObject, IProfilesService, IDisposable +{ + private readonly IUnitOfWork _unitOfWork; + private ProfileVm? _currentProfile; + private readonly SourceCache _profiles; + private readonly ReadOnlyObservableCollection _profilesObsCol; + + public ProfilesService(IUnitOfWork unitOfWork) + { + _unitOfWork = unitOfWork; + + _profiles = new SourceCache(x => x.Id); + _profiles + .Connect() + .AutoRefresh() + .SortBy(x => x.DisplayPriority) + .Bind(out _profilesObsCol) + .Subscribe(); + _profiles.AddOrUpdate(_unitOfWork.ProfileRepo.Get(includeProperties: "ButtonMappings")); + // + // CurrentProfile = + // _profiles.Items.MinBy(x => x.DisplayPriority) + // ?? throw new Exception("Unable to retrieve current profile"); + } + + /// + /// Read only collection of profiles + /// + public ReadOnlyObservableCollection Profiles => _profilesObsCol; + + public void AddOrUpdate(ProfileVm profile) => _profiles.AddOrUpdate(profile); + + public IObservable> Connect() => _profiles.Connect(); + + public ProfileVm? CurrentProfile + { + get => _currentProfile; + set => this.RaiseAndSetIfChanged(ref _currentProfile, value); + } + + public ProfileVm CopyProfile(ProfileVm p) + { + var jsonString = JsonConvert.SerializeObject( + p, + new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto } + ); + return JsonConvert.DeserializeObject( + jsonString, + new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto } + ) ?? throw new JsonSerializationException("Error deserializing profile"); + } + + public bool IsUnsavedChanges() + { + var dbProfiles = _unitOfWork.ProfileRepo.Get().ToList(); + return !dbProfiles.SequenceEqual(_profiles.Items); + } + + public void WriteProfileToFile(ProfileVm p, string path) + { + var jsonString = JsonConvert.SerializeObject( + p, + new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Auto, + Formatting = Formatting.Indented, + } + ); + File.WriteAllText(path, jsonString); + } + + public void ImportProfileFromPath(string path) + { + var f = File.ReadAllText(path); + var deserializedProfile = + JsonConvert.DeserializeObject( + f, + new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto } + ) ?? throw new JsonSerializationException("Error deserializing profile"); + AddProfile(deserializedProfile); + } + + public void AddProfile(ProfileVm profile) + { + _profiles.AddOrUpdate(profile); + } + + public void ReplaceProfile(ProfileVm oldProfile, ProfileVm newProfile) + { + if (oldProfile.IsDefault || newProfile.IsDefault) + { + throw new InvalidReplaceException("Cannot replace the default profile"); + } + + newProfile.Id = oldProfile.Id; + _profiles.AddOrUpdate(newProfile); + } + + public void MoveProfileUp(ProfileVm p) + { + if (p.IsDefault) + { + throw new InvalidMoveException("Cannot move the default profile"); + } + + _profiles.Edit(updater => + { + var nextSmaller = _profiles + .Items.Where(x => x.DisplayPriority < p.DisplayPriority) + .MaxBy(x => x.DisplayPriority); + if (nextSmaller is null) + { + throw new InvalidMoveException( + "Unable to retrieve max display index from profiles cache" + ); + } + + if (nextSmaller.IsDefault) + { + throw new InvalidMoveException("Cannot move profile above default profile"); + } + + // swap priorities + (nextSmaller.DisplayPriority, p.DisplayPriority) = ( + p.DisplayPriority, + nextSmaller.DisplayPriority + ); + }); + } + + public void MoveProfileDown(ProfileVm p) + { + if (p.IsDefault) + { + throw new InvalidMoveException("Cannot move the default profile"); + } + + var nextLargerPriority = _profiles + .Items.Where(x => x.DisplayPriority > p.DisplayPriority) + .MinBy(x => x.DisplayPriority); + if (nextLargerPriority is null) + { + throw new InvalidMoveException( + "Unable to retrieve max display index from profiles cache" + ); + } + + // swap priorities + (nextLargerPriority.DisplayPriority, p.DisplayPriority) = ( + p.DisplayPriority, + nextLargerPriority.DisplayPriority + ); + } + + public void RemoveProfile(ProfileVm profile) + { + if (profile.IsDefault) + { + throw new Exception("Attempted to remove default profile"); + } + + var nextSmallerPriority = _profiles + .Items.Where(x => x.DisplayPriority < profile.DisplayPriority) + .MaxBy(x => x.DisplayPriority); + if (nextSmallerPriority is null) + { + throw new Exception("Unable to find next profile to set as current profile"); + } + + _profiles.Remove(profile); + CurrentProfile = nextSmallerPriority; + } + + public void Dispose() + { + _profiles.Dispose(); + } +} diff --git a/YMouseButtonControl.Core/Services/Settings/SettingsService.cs b/YMouseButtonControl.Core/Services/Settings/SettingsService.cs new file mode 100644 index 0000000..8c7e512 --- /dev/null +++ b/YMouseButtonControl.Core/Services/Settings/SettingsService.cs @@ -0,0 +1,71 @@ +using System; +using System.Linq; +using DynamicData; +using ReactiveUI; +using YMouseButtonControl.Core.Repositories; +using YMouseButtonControl.Core.ViewModels.Models; + +namespace YMouseButtonControl.Core.Services.Settings; + +public interface ISettingsService +{ + IObservable> Connect(); + bool IsUnsavedChanges(); + BaseSettingVm? GetSetting(string name); + SettingBoolVm? GetBoolSetting(string name); + BaseSettingVm? UpdateSetting(int id, BaseSettingVm vm); + void Save(); + SettingBoolVm? UpdateSetting(SettingBoolVm vm); +} + +public class SettingsService : ReactiveObject, ISettingsService +{ + private readonly IUnitOfWork _unitOfWork; + private readonly SourceCache _settings; + + public SettingsService(IUnitOfWork unitOfWork) + { + _unitOfWork = unitOfWork; + _settings = new SourceCache(x => x.Id); + LoadSettingsFromDb(); + } + + public IObservable> Connect() => _settings.Connect(); + + public bool IsUnsavedChanges() + { + var dbSettings = _unitOfWork.SettingRepo.Get().ToList(); + return _settings.Items.Count() != dbSettings.Count + || _settings.Items.Where((p, i) => !p.Equals(dbSettings[i])).Any(); + } + + public BaseSettingVm? GetSetting(string name) => + _unitOfWork.SettingRepo.Get().FirstOrDefault(x => x.Name == name); + + public SettingBoolVm? GetBoolSetting(string name) => + _unitOfWork.SettingBoolRepo.Get().FirstOrDefault(x => x.Name == name); + + public BaseSettingVm? UpdateSetting(int id, BaseSettingVm vm) + { + var dbSetting = _unitOfWork.SettingRepo.GetById(id); + if (dbSetting is null) + { + return null; + } + _unitOfWork.SettingRepo.Update(dbSetting.Id, vm); + return dbSetting; + } + + public SettingBoolVm? UpdateSetting(SettingBoolVm vm) + { + return _unitOfWork.SettingBoolRepo.Update(vm.Id, vm); + } + + public void Save() => _unitOfWork.Save(); + + private void LoadSettingsFromDb() + { + var model = _unitOfWork.SettingRepo.Get(); + _settings.AddOrUpdate(model); + } +} diff --git a/YMouseButtonControl.Core/Services/IStartupInstallerService.cs b/YMouseButtonControl.Core/Services/StartupInstaller/IStartupInstallerService.cs similarity index 72% rename from YMouseButtonControl.Core/Services/IStartupInstallerService.cs rename to YMouseButtonControl.Core/Services/StartupInstaller/IStartupInstallerService.cs index de020ad..c45a998 100644 --- a/YMouseButtonControl.Core/Services/IStartupInstallerService.cs +++ b/YMouseButtonControl.Core/Services/StartupInstaller/IStartupInstallerService.cs @@ -1,4 +1,4 @@ -namespace YMouseButtonControl.Core.Services; +namespace YMouseButtonControl.Core.Services.StartupInstaller; public interface IStartupInstallerService { diff --git a/YMouseButtonControl.Core/ViewModels/Implementations/AppViewModel.cs b/YMouseButtonControl.Core/ViewModels/AppViewModel/AppViewModel.cs similarity index 91% rename from YMouseButtonControl.Core/ViewModels/Implementations/AppViewModel.cs rename to YMouseButtonControl.Core/ViewModels/AppViewModel/AppViewModel.cs index 9679d85..0fb38a9 100644 --- a/YMouseButtonControl.Core/ViewModels/Implementations/AppViewModel.cs +++ b/YMouseButtonControl.Core/ViewModels/AppViewModel/AppViewModel.cs @@ -2,15 +2,14 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; -using Avalonia.ReactiveUI; using ReactiveUI; -using YMouseButtonControl.Core.Services; -using YMouseButtonControl.Core.Services.BackgroundTasks; -using YMouseButtonControl.Core.ViewModels.Interfaces; +using YMouseButtonControl.Core.Services.StartupInstaller; using YMouseButtonControl.Core.ViewModels.MainWindow; using YMouseButtonControl.Core.Views; -namespace YMouseButtonControl.Core.ViewModels.Implementations; +namespace YMouseButtonControl.Core.ViewModels.AppViewModel; + +public interface IAppViewModel; public class AppViewModel : ViewModelBase, IAppViewModel { @@ -24,8 +23,7 @@ public class AppViewModel : ViewModelBase, IAppViewModel public AppViewModel( IStartupInstallerService startupInstallerService, IMainWindow mainWindow, - IMainWindowViewModel mainWindowViewModel, - IBackgroundTasksRunner backgroundTasksRunner + IMainWindowViewModel mainWindowViewModel ) { RunAtStartupIsEnabled = startupInstallerService.ButtonEnabled(); diff --git a/YMouseButtonControl.Core/ViewModels/DialogBase.cs b/YMouseButtonControl.Core/ViewModels/DialogBase.cs new file mode 100644 index 0000000..992e367 --- /dev/null +++ b/YMouseButtonControl.Core/ViewModels/DialogBase.cs @@ -0,0 +1,5 @@ +using ReactiveUI; + +namespace YMouseButtonControl.Core.ViewModels; + +public class DialogBase : ReactiveObject { } diff --git a/YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/DialogBase.cs b/YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/DialogBase.cs deleted file mode 100644 index c0dc4da..0000000 --- a/YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/DialogBase.cs +++ /dev/null @@ -1,5 +0,0 @@ -using ReactiveUI; - -namespace YMouseButtonControl.Core.ViewModels.Implementations.Dialogs; - -public class DialogBase : ReactiveObject { } diff --git a/YMouseButtonControl.Core/ViewModels/Implementations/ProfilesInformationViewModel.cs b/YMouseButtonControl.Core/ViewModels/Implementations/ProfilesInformationViewModel.cs deleted file mode 100644 index cf50140..0000000 --- a/YMouseButtonControl.Core/ViewModels/Implementations/ProfilesInformationViewModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -using YMouseButtonControl.Core.Profiles.Interfaces; -using YMouseButtonControl.Core.ViewModels.Interfaces; - -namespace YMouseButtonControl.Core.ViewModels.Implementations; - -public class ProfilesInformationViewModel(IProfilesService profilesService) - : ViewModelBase, - IProfilesInformationViewModel -{ - public IProfilesService ProfilesService { get; } = profilesService; -} diff --git a/YMouseButtonControl.Core/ViewModels/Interfaces/Dialogs/IGlobalSettingsDialogViewModel.cs b/YMouseButtonControl.Core/ViewModels/Interfaces/Dialogs/IGlobalSettingsDialogViewModel.cs deleted file mode 100644 index f0b0294..0000000 --- a/YMouseButtonControl.Core/ViewModels/Interfaces/Dialogs/IGlobalSettingsDialogViewModel.cs +++ /dev/null @@ -1,8 +0,0 @@ -using YMouseButtonControl.Core.DataAccess.Models.Implementations; - -namespace YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; - -public interface IGlobalSettingsDialogViewModel -{ - Setting StartMinimized { get; set; } -} diff --git a/YMouseButtonControl.Core/ViewModels/Interfaces/Dialogs/IProcessSelectorDialogViewModel.cs b/YMouseButtonControl.Core/ViewModels/Interfaces/Dialogs/IProcessSelectorDialogViewModel.cs deleted file mode 100644 index 4fc069d..0000000 --- a/YMouseButtonControl.Core/ViewModels/Interfaces/Dialogs/IProcessSelectorDialogViewModel.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Windows.Input; - -namespace YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; - -public interface IProcessSelectorDialogViewModel -{ - ICommand RefreshButtonCommand { get; } -} diff --git a/YMouseButtonControl.Core/ViewModels/Interfaces/Dialogs/IShowSimulatedKeystrokesDialogService.cs b/YMouseButtonControl.Core/ViewModels/Interfaces/Dialogs/IShowSimulatedKeystrokesDialogService.cs deleted file mode 100644 index 6a5638d..0000000 --- a/YMouseButtonControl.Core/ViewModels/Interfaces/Dialogs/IShowSimulatedKeystrokesDialogService.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Threading.Tasks; -using ReactiveUI; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.ViewModels.Implementations.Dialogs; -using YMouseButtonControl.Core.ViewModels.Models; - -namespace YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; - -public interface IShowSimulatedKeystrokesDialogService -{ - Interaction< - SimulatedKeystrokesDialogViewModel, - SimulatedKeystrokesDialogModel? - > ShowSimulatedKeystrokesPickerInteraction { get; } - Task ShowSimulatedKeystrokesDialog(string buttonName); - Task ShowSimulatedKeystrokesDialog( - string buttonName, - IButtonMapping mapping - ); -} diff --git a/YMouseButtonControl.Core/ViewModels/Interfaces/IAppViewModel.cs b/YMouseButtonControl.Core/ViewModels/Interfaces/IAppViewModel.cs deleted file mode 100644 index e35a545..0000000 --- a/YMouseButtonControl.Core/ViewModels/Interfaces/IAppViewModel.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace YMouseButtonControl.Core.ViewModels.Interfaces; - -public interface IAppViewModel { } diff --git a/YMouseButtonControl.Core/ViewModels/Interfaces/ILayerViewModel.cs b/YMouseButtonControl.Core/ViewModels/Interfaces/ILayerViewModel.cs deleted file mode 100644 index 3fc9f8a..0000000 --- a/YMouseButtonControl.Core/ViewModels/Interfaces/ILayerViewModel.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace YMouseButtonControl.Core.ViewModels.Interfaces; - -public interface ILayerViewModel { } diff --git a/YMouseButtonControl.Core/ViewModels/Interfaces/IProfilesInformationViewModel.cs b/YMouseButtonControl.Core/ViewModels/Interfaces/IProfilesInformationViewModel.cs deleted file mode 100644 index 8563952..0000000 --- a/YMouseButtonControl.Core/ViewModels/Interfaces/IProfilesInformationViewModel.cs +++ /dev/null @@ -1,8 +0,0 @@ -using YMouseButtonControl.Core.Profiles.Interfaces; - -namespace YMouseButtonControl.Core.ViewModels.Interfaces; - -public interface IProfilesInformationViewModel -{ - public IProfilesService ProfilesService { get; } -} diff --git a/YMouseButtonControl.Core/ViewModels/Interfaces/IProfilesListViewModel.cs b/YMouseButtonControl.Core/ViewModels/Interfaces/IProfilesListViewModel.cs deleted file mode 100644 index e94d4cc..0000000 --- a/YMouseButtonControl.Core/ViewModels/Interfaces/IProfilesListViewModel.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace YMouseButtonControl.Core.ViewModels.Interfaces; - -public interface IProfilesListViewModel { } diff --git a/YMouseButtonControl.Core/ViewModels/Implementations/LayerViewModel.cs b/YMouseButtonControl.Core/ViewModels/LayerViewModel/LayerViewModel.cs similarity index 79% rename from YMouseButtonControl.Core/ViewModels/Implementations/LayerViewModel.cs rename to YMouseButtonControl.Core/ViewModels/LayerViewModel/LayerViewModel.cs index 7103042..b5c254f 100644 --- a/YMouseButtonControl.Core/ViewModels/Implementations/LayerViewModel.cs +++ b/YMouseButtonControl.Core/ViewModels/LayerViewModel/LayerViewModel.cs @@ -11,17 +11,16 @@ using Avalonia.Media; using Avalonia.Styling; using ReactiveUI; -using YMouseButtonControl.Core.DataAccess.Models.Enums; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; -using YMouseButtonControl.Core.Profiles.Interfaces; -using YMouseButtonControl.Core.Services.Abstractions.Enums; -using YMouseButtonControl.Core.Services.Abstractions.Models.EventArgs; -using YMouseButtonControl.Core.ViewModels.Interfaces; -using YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; - -namespace YMouseButtonControl.Core.ViewModels.Implementations; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Enums; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.EventArgs; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations; +using YMouseButtonControl.Core.Services.Profiles; +using YMouseButtonControl.Core.ViewModels.Models; +using YMouseButtonControl.DataAccess.Models; + +namespace YMouseButtonControl.Core.ViewModels.LayerViewModel; + +public interface ILayerViewModel; public class LayerViewModel : ViewModelBase, ILayerViewModel { @@ -123,10 +122,11 @@ public IProfilesService ProfilesService public IShowSimulatedKeystrokesDialogService ShowSimulatedKeystrokesDialogService { get; } private async Task OnComboIndexChangedAsync( - IReadOnlyList list, - Action setComboList, + IReadOnlyList list, + Action setComboList, int index, - Action setMouseMapping, + Action setMouseMapping, + MouseButton mouseButton, string buttonName, bool settingsGearClicked = false ) @@ -138,12 +138,13 @@ private async Task OnComboIndexChangedAsync( var mapping = list[index]; var newMapping = mapping; if ( - mapping is SimulatedKeystrokes + mapping is SimulatedKeystrokeVm && (string.IsNullOrWhiteSpace(mapping.Keys) || settingsGearClicked) ) { newMapping = await ShowSimulatedKeystrokesDialogService.ShowSimulatedKeystrokesDialog( buttonName, + mouseButton, mapping ); if (newMapping is null) @@ -156,7 +157,7 @@ mapping is SimulatedKeystrokes setMouseMapping(newMapping); } - private static bool CanClickGearButton(IButtonMapping? mapping) => + private static bool CanClickGearButton(BaseButtonMappingVm? mapping) => mapping is not null && mapping.CanRaiseDialog && !string.IsNullOrWhiteSpace(mapping.Keys); public LayerViewModel( @@ -217,12 +218,15 @@ await OnComboIndexChangedAsync( index: x, setMouseMapping: value => { - Debug.Assert( - _profilesService.CurrentProfile != null, - "_profilesService.CurrentProfile != null" - ); - _profilesService.CurrentProfile.MouseButton1 = value; + if ( + _profilesService.CurrentProfile is not null + && !_profilesService.CurrentProfile.MouseButton1.Equals(value) + ) + { + _profilesService.CurrentProfile.MouseButton1 = value; + } }, + mouseButton: MouseButton.Mb1, buttonName: "Left Mouse Button" ) ); @@ -239,12 +243,15 @@ await OnComboIndexChangedAsync( x, value => { - Debug.Assert( - _profilesService.CurrentProfile != null, - "_profilesService.CurrentProfile != null" - ); - _profilesService.CurrentProfile.MouseButton2 = value; + if ( + _profilesService.CurrentProfile is not null + && !_profilesService.CurrentProfile.MouseButton2.Equals(value) + ) + { + _profilesService.CurrentProfile.MouseButton2 = value; + } }, + mouseButton: MouseButton.Mb2, buttonName: "Right Mouse Button" ) ); @@ -261,12 +268,15 @@ await OnComboIndexChangedAsync( x, value => { - Debug.Assert( - _profilesService.CurrentProfile != null, - "_profilesService.CurrentProfile != null" - ); - _profilesService.CurrentProfile.MouseButton3 = value; + if ( + _profilesService.CurrentProfile is not null + && !_profilesService.CurrentProfile.MouseButton3.Equals(value) + ) + { + _profilesService.CurrentProfile.MouseButton3 = value; + } }, + mouseButton: MouseButton.Mb3, buttonName: "Middle Mouse Button" ) ); @@ -274,21 +284,24 @@ await OnComboIndexChangedAsync( .DistinctUntilChanged() .Subscribe(async x => await OnComboIndexChangedAsync( - MouseButton4Combo, - value => + list: MouseButton4Combo, + setComboList: value => { MouseButton4Combo[x] = value; Mb4Index = x; }, - x, - value => + index: x, + setMouseMapping: value => { - Debug.Assert( - _profilesService.CurrentProfile != null, - "_profilesService.CurrentProfile != null" - ); - _profilesService.CurrentProfile.MouseButton4 = value; + if ( + _profilesService.CurrentProfile is not null + && !_profilesService.CurrentProfile.MouseButton4.Equals(value) + ) + { + _profilesService.CurrentProfile.MouseButton4 = value; + } }, + mouseButton: MouseButton.Mb4, buttonName: "Mouse Button 4" ) ); @@ -305,12 +318,15 @@ await OnComboIndexChangedAsync( x, value => { - Debug.Assert( - _profilesService.CurrentProfile != null, - "_profilesService.CurrentProfile != null" - ); - _profilesService.CurrentProfile.MouseButton5 = value; + if ( + _profilesService.CurrentProfile is not null + && !_profilesService.CurrentProfile.MouseButton5.Equals(value) + ) + { + _profilesService.CurrentProfile.MouseButton5 = value; + } }, + mouseButton: MouseButton.Mb5, buttonName: "Mouse Button 5" ) ); @@ -327,12 +343,15 @@ await OnComboIndexChangedAsync( x, value => { - Debug.Assert( - _profilesService.CurrentProfile != null, - "_profilesService.CurrentProfile != null" - ); - _profilesService.CurrentProfile.MouseWheelUp = value; + if ( + _profilesService.CurrentProfile is not null + && !_profilesService.CurrentProfile.MouseWheelUp.Equals(value) + ) + { + _profilesService.CurrentProfile.MouseWheelUp = value; + } }, + mouseButton: MouseButton.Mwu, buttonName: "Mouse Wheel Up" ) ); @@ -349,12 +368,15 @@ await OnComboIndexChangedAsync( x, value => { - Debug.Assert( - _profilesService.CurrentProfile != null, - "_profilesService.CurrentProfile != null" - ); - _profilesService.CurrentProfile.MouseWheelDown = value; + if ( + _profilesService.CurrentProfile is not null + && !_profilesService.CurrentProfile.MouseWheelDown.Equals(value) + ) + { + _profilesService.CurrentProfile.MouseWheelDown = value; + } }, + mouseButton: MouseButton.Mwd, buttonName: "Mouse Wheel Down" ) ); @@ -371,12 +393,15 @@ await OnComboIndexChangedAsync( x, value => { - Debug.Assert( - _profilesService.CurrentProfile != null, - "_profilesService.CurrentProfile != null" - ); - _profilesService.CurrentProfile.MouseWheelLeft = value; + if ( + _profilesService.CurrentProfile is not null + && !_profilesService.CurrentProfile.MouseWheelLeft.Equals(value) + ) + { + _profilesService.CurrentProfile.MouseWheelLeft = value; + } }, + mouseButton: MouseButton.Mwl, buttonName: "Mouse Wheel Left" ) ); @@ -393,12 +418,15 @@ await OnComboIndexChangedAsync( x, value => { - Debug.Assert( - _profilesService.CurrentProfile != null, - "_profilesService.CurrentProfile != null" - ); - _profilesService.CurrentProfile.MouseWheelRight = value; + if ( + _profilesService.CurrentProfile is not null + && !_profilesService.CurrentProfile.MouseWheelRight.Equals(value) + ) + { + _profilesService.CurrentProfile.MouseWheelRight = value; + } }, + mouseButton: MouseButton.Mwr, buttonName: "Mouse Wheel Right" ) ); @@ -452,6 +480,7 @@ await OnComboIndexChangedAsync( ); _profilesService.CurrentProfile.MouseButton1 = value; }, + mouseButton: MouseButton.Mb1, buttonName: "Left Mouse Button", true ); @@ -477,6 +506,7 @@ await OnComboIndexChangedAsync( ); _profilesService.CurrentProfile.MouseButton2 = value; }, + mouseButton: MouseButton.Mb2, buttonName: "Right Mouse Button", true ); @@ -502,6 +532,7 @@ await OnComboIndexChangedAsync( ); _profilesService.CurrentProfile.MouseButton3 = value; }, + mouseButton: MouseButton.Mb3, buttonName: "Middle Mouse Button", true ); @@ -527,6 +558,7 @@ await OnComboIndexChangedAsync( ); _profilesService.CurrentProfile.MouseButton4 = value; }, + mouseButton: MouseButton.Mb4, buttonName: "Mouse Button 4", true ); @@ -552,6 +584,7 @@ await OnComboIndexChangedAsync( ); _profilesService.CurrentProfile.MouseButton5 = value; }, + mouseButton: MouseButton.Mb5, buttonName: "Mouse Button 5", true ); @@ -577,6 +610,7 @@ await OnComboIndexChangedAsync( ); _profilesService.CurrentProfile.MouseWheelUp = value; }, + mouseButton: MouseButton.Mwu, buttonName: "Mouse Wheel Up", true ); @@ -602,6 +636,7 @@ await OnComboIndexChangedAsync( ); _profilesService.CurrentProfile.MouseWheelDown = value; }, + mouseButton: MouseButton.Mwd, buttonName: "Mouse Wheel Down", true ); @@ -627,6 +662,7 @@ await OnComboIndexChangedAsync( ); _profilesService.CurrentProfile.MouseWheelLeft = value; }, + mouseButton: MouseButton.Mwl, buttonName: "Mouse Wheel Left", true ); @@ -652,6 +688,7 @@ await OnComboIndexChangedAsync( ); _profilesService.CurrentProfile.MouseWheelRight = value; }, + mouseButton: MouseButton.Mwr, buttonName: "Mouse Wheel Right", true ); @@ -754,92 +791,92 @@ public IBrush MouseButton1BackgroundColor set => this.RaiseAndSetIfChanged(ref _mouseButton1BackgroundColor, value); } - public ObservableCollection MouseButton1Combo { get; set; } = - new(GetButtonMappings()); + public ObservableCollection MouseButton1Combo { get; set; } = + new(GetButtonMappings(MouseButton.Mb1)); - public ObservableCollection MouseButton2Combo { get; set; } = - new(GetButtonMappings()); + public ObservableCollection MouseButton2Combo { get; set; } = + new(GetButtonMappings(MouseButton.Mb2)); - public ObservableCollection MouseButton3Combo { get; set; } = - new(GetButtonMappings()); + public ObservableCollection MouseButton3Combo { get; set; } = + new(GetButtonMappings(MouseButton.Mb3)); - public ObservableCollection MouseButton4Combo { get; set; } = - new(GetButtonMappings()); + public ObservableCollection MouseButton4Combo { get; set; } = + new(GetButtonMappings(MouseButton.Mb4)); - public ObservableCollection MouseButton5Combo { get; set; } = - new(GetButtonMappings()); + public ObservableCollection MouseButton5Combo { get; set; } = + new(GetButtonMappings(MouseButton.Mb5)); - public ObservableCollection MouseWheelUpCombo { get; set; } = - new(GetButtonMappings()); + public ObservableCollection MouseWheelUpCombo { get; set; } = + new(GetButtonMappings(MouseButton.Mwu)); - public ObservableCollection MouseWheelDownCombo { get; set; } = - new(GetButtonMappings()); + public ObservableCollection MouseWheelDownCombo { get; set; } = + new(GetButtonMappings(MouseButton.Mwd)); - public ObservableCollection MouseWheelLeftCombo { get; set; } = - new(GetButtonMappings()); + public ObservableCollection MouseWheelLeftCombo { get; set; } = + new(GetButtonMappings(MouseButton.Mwl)); - public ObservableCollection MouseWheelRightCombo { get; set; } = - new(GetButtonMappings()); + public ObservableCollection MouseWheelRightCombo { get; set; } = + new(GetButtonMappings(MouseButton.Mwr)); - private void OnSelectedCurrentProfileChanged(Profile newProfile) + private void OnSelectedCurrentProfileChanged(ProfileVm newProfile) { - foreach (var mapping in GetButtonMappings()) + foreach (var mapping in GetButtonMappings(MouseButton.Mb1)) { MouseButton1Combo[mapping.Index] = mapping; } MouseButton1Combo[newProfile.MouseButton1.Index] = newProfile.MouseButton1; Mb1Index = newProfile.MouseButton1.Index; - foreach (var mapping in GetButtonMappings()) + foreach (var mapping in GetButtonMappings(MouseButton.Mb2)) { MouseButton2Combo[mapping.Index] = mapping; } MouseButton2Combo[newProfile.MouseButton2.Index] = newProfile.MouseButton2; Mb2Index = newProfile.MouseButton2.Index; - foreach (var mapping in GetButtonMappings()) + foreach (var mapping in GetButtonMappings(MouseButton.Mb3)) { MouseButton3Combo[mapping.Index] = mapping; } MouseButton3Combo[newProfile.MouseButton3.Index] = newProfile.MouseButton3; Mb3Index = newProfile.MouseButton3.Index; - foreach (var mapping in GetButtonMappings()) + foreach (var mapping in GetButtonMappings(MouseButton.Mb4)) { MouseButton4Combo[mapping.Index] = mapping; } MouseButton4Combo[newProfile.MouseButton4.Index] = newProfile.MouseButton4; Mb4Index = newProfile.MouseButton4.Index; - foreach (var mapping in GetButtonMappings()) + foreach (var mapping in GetButtonMappings(MouseButton.Mb5)) { MouseButton5Combo[mapping.Index] = mapping; } MouseButton5Combo[newProfile.MouseButton5.Index] = newProfile.MouseButton5; Mb5Index = newProfile.MouseButton5.Index; - foreach (var mapping in GetButtonMappings()) + foreach (var mapping in GetButtonMappings(MouseButton.Mwu)) { MouseWheelUpCombo[mapping.Index] = mapping; } MouseWheelUpCombo[newProfile.MouseWheelUp.Index] = newProfile.MouseWheelUp; MwuIndex = newProfile.MouseWheelUp.Index; - foreach (var mapping in GetButtonMappings()) + foreach (var mapping in GetButtonMappings(MouseButton.Mwd)) { MouseWheelDownCombo[mapping.Index] = mapping; } MouseWheelDownCombo[newProfile.MouseWheelDown.Index] = newProfile.MouseWheelDown; MwdIndex = newProfile.MouseWheelDown.Index; - foreach (var mapping in GetButtonMappings()) + foreach (var mapping in GetButtonMappings(MouseButton.Mwl)) { MouseWheelLeftCombo[mapping.Index] = mapping; } MouseWheelLeftCombo[newProfile.MouseWheelLeft.Index] = newProfile.MouseWheelLeft; MwlIndex = newProfile.MouseWheelLeft.Index; - foreach (var mapping in GetButtonMappings()) + foreach (var mapping in GetButtonMappings(MouseButton.Mwr)) { MouseWheelRightCombo[mapping.Index] = mapping; } @@ -952,18 +989,38 @@ private void OnMouseClicked(object? sender, NewMouseHookEventArgs e) } } - private static IEnumerable GetButtonMappings() => - ButtonMappingDictionary.Select(x => x.Value()); + private static IEnumerable GetButtonMappings(MouseButton mouseButton) => + ButtonMappingDictionary.Select(x => x.Value(mouseButton)); private static readonly Dictionary< ButtonMappings, - Func + Func > ButtonMappingDictionary = new() { - { ButtonMappings.Nothing, () => new NothingMapping() }, - { ButtonMappings.Disabled, () => new DisabledMapping() }, - { ButtonMappings.SimulatedKeystrokes, () => new SimulatedKeystrokes() }, - { ButtonMappings.RightClick, () => new RightClick() }, + { + ButtonMappings.Nothing, + mb => new NothingMappingVm { MouseButton = mb } + }, + { + ButtonMappings.Disabled, + mb => new DisabledMappingVm { MouseButton = mb } + }, + { + ButtonMappings.SimulatedKeystrokes, + mb => new SimulatedKeystrokeVm { MouseButton = mb } + }, + { + ButtonMappings.RightClick, + mb => new RightClickVm { MouseButton = mb } + }, }; + + private enum ButtonMappings + { + Nothing, + Disabled, + SimulatedKeystrokes, + RightClick, + } } diff --git a/YMouseButtonControl.Core/ViewModels/LayerViewModel/ShowSimulatedKeystrokesDialogService.cs b/YMouseButtonControl.Core/ViewModels/LayerViewModel/ShowSimulatedKeystrokesDialogService.cs new file mode 100644 index 0000000..ba6ab54 --- /dev/null +++ b/YMouseButtonControl.Core/ViewModels/LayerViewModel/ShowSimulatedKeystrokesDialogService.cs @@ -0,0 +1,52 @@ +using System.Reactive.Linq; +using System.Threading.Tasks; +using ReactiveUI; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations; +using YMouseButtonControl.Core.ViewModels.Models; +using YMouseButtonControl.DataAccess.Models; + +namespace YMouseButtonControl.Core.ViewModels.LayerViewModel; + +public interface IShowSimulatedKeystrokesDialogService +{ + Interaction< + SimulatedKeystrokesDialogViewModel, + SimulatedKeystrokeVm? + > ShowSimulatedKeystrokesPickerInteraction { get; } + + Task ShowSimulatedKeystrokesDialog( + string buttonName, + MouseButton mouseButton, + BaseButtonMappingVm mapping + ); +} + +public class ShowSimulatedKeystrokesDialogService(IMouseListener mouseListener) + : IShowSimulatedKeystrokesDialogService +{ + public Interaction< + SimulatedKeystrokesDialogViewModel, + SimulatedKeystrokeVm? + > ShowSimulatedKeystrokesPickerInteraction { get; } = new(); + + public async Task ShowSimulatedKeystrokesDialog( + string buttonName, + MouseButton mouseButton + ) => await ShowSimulatedKeystrokesDialog(buttonName, mouseButton, null); + + public async Task ShowSimulatedKeystrokesDialog( + string buttonName, + MouseButton mouseButton, + BaseButtonMappingVm? mapping + ) + { + return await ShowSimulatedKeystrokesPickerInteraction.Handle( + new SimulatedKeystrokesDialogViewModel( + mouseListener, + buttonName, + mouseButton, + mapping as SimulatedKeystrokeVm + ) + ); + } +} diff --git a/YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/SimulatedKeystrokesDialogViewModel.cs b/YMouseButtonControl.Core/ViewModels/LayerViewModel/SimulatedKeystrokesDialogViewModel.cs similarity index 81% rename from YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/SimulatedKeystrokesDialogViewModel.cs rename to YMouseButtonControl.Core/ViewModels/LayerViewModel/SimulatedKeystrokesDialogViewModel.cs index 09721ae..4743778 100644 --- a/YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/SimulatedKeystrokesDialogViewModel.cs +++ b/YMouseButtonControl.Core/ViewModels/LayerViewModel/SimulatedKeystrokesDialogViewModel.cs @@ -4,13 +4,12 @@ using System.Reactive; using Avalonia.Collections; using ReactiveUI; -using YMouseButtonControl.Core.DataAccess.Models.Implementations.SimulatedKeystrokesTypes; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; -using YMouseButtonControl.Core.Services.Abstractions.Models.EventArgs; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.EventArgs; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations; using YMouseButtonControl.Core.ViewModels.Models; +using YMouseButtonControl.DataAccess.Models; -namespace YMouseButtonControl.Core.ViewModels.Implementations.Dialogs; +namespace YMouseButtonControl.Core.ViewModels.LayerViewModel; public class SimulatedKeystrokesDialogViewModel : DialogBase { @@ -32,22 +31,25 @@ public class SimulatedKeystrokesDialogViewModel : DialogBase private bool _blockOriginalMouseInput = true; private short _x; private short _y; - private ISimulatedKeystrokesType? _currentSimulatedKeystrokesType; + private BaseSimulatedKeystrokeTypeVm? _currentSimulatedKeystrokesType; private readonly IMouseListener _mouseListener; + private BaseButtonMappingVm? _currentMapping; public SimulatedKeystrokesDialogViewModel( IMouseListener mouseListener, string buttonName, - IButtonMapping? currentMapping = null + MouseButton mouseButton, + SimulatedKeystrokeVm? currentMapping = null ) { _title = $"SimulatedKeystrokes - {buttonName}"; _mouseListener = mouseListener; + currentMapping ??= new SimulatedKeystrokeVm(); _mouseListener.OnMouseMovedEventHandler += MouseListenerOnOnMouseMovedEventHandler; _description = currentMapping?.PriorityDescription ?? string.Empty; _customKeys = currentMapping?.Keys ?? string.Empty; SimulatedKeystrokesType = - currentMapping?.SimulatedKeystrokesType ?? new MouseButtonPressedActionType(); + currentMapping?.SimulatedKeystrokeType ?? new MouseButtonPressedActionTypeVm(); _caretIndex = 0; var canExecuteOkCmd = this.WhenAnyValue( @@ -58,18 +60,18 @@ public SimulatedKeystrokesDialogViewModel( && skt is not null && ( keys != currentMapping?.Keys - || !Equals(skt, currentMapping.SimulatedKeystrokesType) + || !Equals(skt, currentMapping.SimulatedKeystrokeType) ) ); OkCommand = ReactiveCommand.Create( () => - new SimulatedKeystrokesDialogModel - { - CustomKeys = CustomKeys, - SimulatedKeystrokesType = SimulatedKeystrokesType, - Description = Description, - BlockOriginalMouseInput = BlockOriginalMouseInput, - }, + { + currentMapping!.Keys = CustomKeys; + currentMapping.MouseButton = mouseButton; + currentMapping.SimulatedKeystrokeType = SimulatedKeystrokesType; + currentMapping.BlockOriginalMouseInput = BlockOriginalMouseInput; + return currentMapping; + }, canExecuteOkCmd ); @@ -95,7 +97,7 @@ NewMouseHookMoveEventArgs e ComputedXy = $"{X},{Y}"; } - public ISimulatedKeystrokesType? SimulatedKeystrokesType + public BaseSimulatedKeystrokeTypeVm? SimulatedKeystrokesType { get => _currentSimulatedKeystrokesType; set => this.RaiseAndSetIfChanged(ref _currentSimulatedKeystrokesType, value); @@ -139,10 +141,10 @@ public bool BlockOriginalMouseInput set => this.RaiseAndSetIfChanged(ref _blockOriginalMouseInput, value); } - public AvaloniaList SimulatedKeystrokesTypes { get; set; } = + public AvaloniaList SimulatedKeystrokesTypes { get; set; } = new(GetSimulatedKeystrokesTypes()); - public ReactiveCommand OkCommand { get; } + public ReactiveCommand OkCommand { get; } public ReactiveCommand SplitButtonCommand { get; } @@ -304,21 +306,27 @@ public int CaretIndex set => this.RaiseAndSetIfChanged(ref _caretIndex, value); } - private static readonly List> SimulatedKeystrokeTypesList = + public BaseButtonMappingVm? CurrentMapping + { + get => _currentMapping; + set => this.RaiseAndSetIfChanged(ref _currentMapping, value); + } + + private static readonly List> SimulatedKeystrokeTypesList = [ - () => new MouseButtonPressedActionType(), - () => new MouseButtonReleasedActionType(), - () => new DuringMouseActionType(), - () => new InAnotherThreadPressedActionType(), - () => new InAnotherThreadReleasedActionType(), - () => new RepeatedlyWhileButtonDownActionType(), - () => new StickyRepeatActionType(), - () => new StickyHoldActionType(), - () => new AsMousePressedAndReleasedActionType(), + () => new MouseButtonPressedActionTypeVm(), + () => new MouseButtonReleasedActionTypeVm(), + () => new DuringMouseActionTypeVm(), + () => new InAnotherThreadPressedActionTypeVm(), + () => new InAnotherThreadReleasedActionTypeVm(), + () => new RepeatedlyWhileButtonDownActionTypeVm(), + () => new StickyRepeatActionTypeVm(), + () => new StickyHoldActionTypeVm(), + () => new AsMousePressedAndReleasedActionTypeVm(), ]; private string? _computedXy; - private static IEnumerable GetSimulatedKeystrokesTypes() => + private static IEnumerable GetSimulatedKeystrokesTypes() => SimulatedKeystrokeTypesList.Select(x => x()); } diff --git a/YMouseButtonControl.Core/ViewModels/MainWindow/Features/Apply/ApplyProfiles.cs b/YMouseButtonControl.Core/ViewModels/MainWindow/Features/Apply/ApplyProfiles.cs index ba07b93..060cf09 100644 --- a/YMouseButtonControl.Core/ViewModels/MainWindow/Features/Apply/ApplyProfiles.cs +++ b/YMouseButtonControl.Core/ViewModels/MainWindow/Features/Apply/ApplyProfiles.cs @@ -1,6 +1,5 @@ -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.DataAccess.UnitOfWork; -using YMouseButtonControl.Core.Profiles.Interfaces; +using YMouseButtonControl.Core.Repositories; +using YMouseButtonControl.Core.Services.Profiles; namespace YMouseButtonControl.Core.ViewModels.MainWindow.Features.Apply; @@ -9,12 +8,19 @@ public interface IApply void ApplyProfiles(); } -public class Apply(IUnitOfWorkFactory unitOfWorkFactory, IProfilesService profilesService) : IApply +public class Apply(IUnitOfWork unitOfWork, IProfilesService profilesService) : IApply { public void ApplyProfiles() { - using var unitOfWork = unitOfWorkFactory.Create(); - var repository = unitOfWork.GetRepository(); - repository.ApplyAction(profilesService.Profiles); + foreach (var dbVm in unitOfWork.ProfileRepo.Get()) + { + unitOfWork.ProfileRepo.Remove(dbVm.Id); + } + unitOfWork.Save(); + foreach (var vm in profilesService.Profiles) + { + unitOfWork.ProfileRepo.Update(vm.Id, vm); + } + unitOfWork.Save(); } } diff --git a/YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/GlobalSettingsDialogViewModel.cs b/YMouseButtonControl.Core/ViewModels/MainWindow/GlobalSettingsDialogViewModel.cs similarity index 64% rename from YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/GlobalSettingsDialogViewModel.cs rename to YMouseButtonControl.Core/ViewModels/MainWindow/GlobalSettingsDialogViewModel.cs index 02caeec..8cb3db2 100644 --- a/YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/GlobalSettingsDialogViewModel.cs +++ b/YMouseButtonControl.Core/ViewModels/MainWindow/GlobalSettingsDialogViewModel.cs @@ -2,29 +2,32 @@ using System.Reactive; using System.Reactive.Linq; using ReactiveUI; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.Profiles.Interfaces; -using YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; +using YMouseButtonControl.Core.Services.Settings; +using YMouseButtonControl.Core.ViewModels.Models; -namespace YMouseButtonControl.Core.ViewModels.Implementations.Dialogs; +namespace YMouseButtonControl.Core.ViewModels.MainWindow; + +public interface IGlobalSettingsDialogViewModel +{ + SettingBoolVm StartMinimized { get; set; } +} public class GlobalSettingsDialogViewModel : DialogBase, IGlobalSettingsDialogViewModel { - private Setting _startMinimized; + private SettingBoolVm _startMinimized; private readonly ObservableAsPropertyHelper? _applyIsExec; public GlobalSettingsDialogViewModel(ISettingsService settingsService) { _startMinimized = - settingsService.GetSetting("StartMinimized") - ?? throw new Exception($"Error retrieving StartMinimized setting"); + settingsService.GetBoolSetting("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) + if (settingsService.GetSetting("StartMinimized") is not SettingBoolVm curVal) { return true; } @@ -38,14 +41,16 @@ public GlobalSettingsDialogViewModel(ISettingsService settingsService) ApplyCommand = ReactiveCommand.Create( () => { - settingsService.UpdateSetting(StartMinimized.Id, StartMinimized.Value!); + settingsService.UpdateSetting(StartMinimized); + + settingsService.Save(); }, canSave ); _applyIsExec = ApplyCommand.IsExecuting.ToProperty(this, x => x.AppIsExec); } - public Setting StartMinimized + public SettingBoolVm StartMinimized { get => _startMinimized; set => this.RaiseAndSetIfChanged(ref _startMinimized, value); diff --git a/YMouseButtonControl.Core/ViewModels/MainWindow/IMainWindowViewModel.cs b/YMouseButtonControl.Core/ViewModels/MainWindow/IMainWindowViewModel.cs deleted file mode 100644 index 5e1d129..0000000 --- a/YMouseButtonControl.Core/ViewModels/MainWindow/IMainWindowViewModel.cs +++ /dev/null @@ -1,19 +0,0 @@ -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; - -public interface IMainWindowViewModel -{ - IProfilesInformationViewModel ProfilesInformationViewModel { get; } - IProfilesListViewModel ProfilesListViewModel { get; } - ILayerViewModel LayerViewModel { get; } - ReactiveCommand ApplyCommand { get; } - ReactiveCommand CloseCommand { get; } - ReactiveCommand SettingsCommand { 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 2310bdf..971940c 100644 --- a/YMouseButtonControl.Core/ViewModels/MainWindow/MainWindowViewModel.cs +++ b/YMouseButtonControl.Core/ViewModels/MainWindow/MainWindowViewModel.cs @@ -1,29 +1,50 @@ using System; +using System.Collections.ObjectModel; using System.Diagnostics; +using System.Linq; using System.Reactive; using System.Reactive.Linq; using System.Threading.Tasks; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; +using DynamicData; +using DynamicData.Binding; using ReactiveUI; -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.Repositories; +using YMouseButtonControl.Core.Services.Profiles; +using YMouseButtonControl.Core.Services.Settings; +using YMouseButtonControl.Core.ViewModels.LayerViewModel; using YMouseButtonControl.Core.ViewModels.MainWindow.Features.Apply; +using YMouseButtonControl.Core.ViewModels.Models; +using YMouseButtonControl.Core.ViewModels.ProfilesInformationViewModel; +using YMouseButtonControl.Core.ViewModels.ProfilesList; namespace YMouseButtonControl.Core.ViewModels.MainWindow; +public interface IMainWindowViewModel +{ + IProfilesInformationViewModel ProfilesInformationViewModel { get; } + IProfilesListViewModel ProfilesListViewModel { get; } + ILayerViewModel LayerViewModel { get; } + ReactiveCommand ApplyCommand { get; } + ReactiveCommand CloseCommand { get; } + ReactiveCommand SettingsCommand { get; } + Interaction ShowSettingsDialogInteraction { get; } + ProfileVm? CurrentProfile { get; } +} + public class MainWindowViewModel : ViewModelBase, IMainWindowViewModel { #region Fields private readonly IProfilesService _ps; + private readonly ISettingsService _ss; private readonly IProfilesListViewModel _profilesListViewModel; private readonly IGlobalSettingsDialogViewModel _globalSettingsDialogViewModel; - private string? _profileName; + private readonly IUnitOfWork _unitOfWork; + private readonly ObservableAsPropertyHelper? _isExecutingSave; + private readonly ReadOnlyObservableCollection _profileVms; + private bool _canSave; #endregion @@ -31,16 +52,20 @@ public class MainWindowViewModel : ViewModelBase, IMainWindowViewModel public MainWindowViewModel( IProfilesService ps, + ISettingsService ss, ILayerViewModel layerViewModel, IProfilesListViewModel profilesListViewModel, IProfilesInformationViewModel profilesInformationViewModel, IGlobalSettingsDialogViewModel globalSettingsDialogViewModel, - IApply apply + IApply apply, + IUnitOfWork unitOfWork ) { _profilesListViewModel = profilesListViewModel; _globalSettingsDialogViewModel = globalSettingsDialogViewModel; + _unitOfWork = unitOfWork; _ps = ps; + _ss = ss; LayerViewModel = layerViewModel; ProfilesInformationViewModel = profilesInformationViewModel; SettingsCommand = ReactiveCommand.CreateFromTask(ShowSettingsDialogAsync); @@ -55,17 +80,58 @@ is IClassicDesktopStyleApplicationLifetime lifetime lifetime.MainWindow?.Hide(); } }); - var canApply = this.WhenAnyValue(x => x._ps.UnsavedChanges).DistinctUntilChanged(); - ApplyCommand = ReactiveCommand.Create(apply.ApplyProfiles, canApply); - ApplyCommand.Subscribe(_ => + var myOp = _ps.Connect() + .AutoRefresh() + .RefCount() + .Bind(out _profileVms) + .DisposeMany() + .Subscribe(CanSaveHelper); + // var watchSettings + var isExecutingObservable = this.WhenAnyValue(x => x.IsExecutingSave) + .Subscribe(_ => CanSave = false); + var canSaveCmd = this.WhenAnyValue(x => x.CanSave); + ApplyCommand = ReactiveCommand.Create(apply.ApplyProfiles, canSaveCmd); + _isExecutingSave = ApplyCommand.IsExecuting.ToProperty(this, x => x.IsExecutingSave); + } + + private void CanSaveHelper(IChangeSet changeSet) + { + foreach (var cs in changeSet) { - _ps.UnsavedChanges = false; - }); - this.WhenAnyValue(x => x._ps.CurrentProfile).WhereNotNull().Subscribe(OnProfileChanged); - Debug.Assert(_ps.CurrentProfile != null, "_ps.CurrentProfile != null"); - ProfileName = _ps.CurrentProfile.Name; + var entity = _unitOfWork + .ProfileRepo.Get(x => x.Id == cs.Current.Id, includeProperties: "ButtonMappings") + .FirstOrDefault(); + switch (cs.Reason) + { + case ChangeReason.Add: + CanSave = entity is null; + break; + case ChangeReason.Update: + CanSave = !entity?.Equals(cs.Current) ?? true; + break; + case ChangeReason.Remove: + CanSave = entity is not null; + break; + case ChangeReason.Refresh: + CanSave = !entity?.Equals(cs.Current) ?? true; + break; + case ChangeReason.Moved: + break; + default: + throw new ArgumentOutOfRangeException(); + } + } } + public ProfileVm? CurrentProfile => _ps.CurrentProfile; + + public bool CanSave + { + get => _canSave; + set => this.RaiseAndSetIfChanged(ref _canSave, value); + } + public bool IsExecutingSave => _isExecutingSave?.Value ?? false; + #endregion #region Properties @@ -82,18 +148,10 @@ is IClassicDesktopStyleApplicationLifetime lifetime public Interaction ShowSettingsDialogInteraction { get; } - public string? ProfileName - { - get => _profileName; - set => this.RaiseAndSetIfChanged(ref _profileName, value); - } - #endregion private async Task ShowSettingsDialogAsync() { await ShowSettingsDialogInteraction.Handle(_globalSettingsDialogViewModel); } - - private void OnProfileChanged(Profile profile) => ProfileName = profile.Name; } diff --git a/YMouseButtonControl.Core/ViewModels/Models/BaseButtonMappingVm.cs b/YMouseButtonControl.Core/ViewModels/Models/BaseButtonMappingVm.cs new file mode 100644 index 0000000..dba345d --- /dev/null +++ b/YMouseButtonControl.Core/ViewModels/Models/BaseButtonMappingVm.cs @@ -0,0 +1,174 @@ +using System; +using Newtonsoft.Json; +using ReactiveUI; +using YMouseButtonControl.DataAccess.Models; + +namespace YMouseButtonControl.Core.ViewModels.Models; + +[JsonObject(MemberSerialization.OptOut)] +public abstract class BaseButtonMappingVm : ReactiveObject, IEquatable +{ + private string? _keys; + private int _index; + private bool _enabled; + private string? _description; + private string? _priorityDescription; + private bool _state; + private bool _blockOriginalMouseInput; + private BaseSimulatedKeystrokeTypeVm? _simulatedKeystrokeTypeVm; + + [JsonIgnore] + public int Id { get; set; } + + public MouseButton MouseButton { get; set; } + + public int Index + { + get => _index; + set => this.RaiseAndSetIfChanged(ref _index, value); + } + public bool Enabled + { + get => _enabled; + set => this.RaiseAndSetIfChanged(ref _enabled, value); + } + public string? Description + { + get => _description; + set => this.RaiseAndSetIfChanged(ref _description, value); + } + public string? PriorityDescription + { + get => _priorityDescription; + set => this.RaiseAndSetIfChanged(ref _priorityDescription, value); + } + + public string? Keys + { + get => _keys; + set => this.RaiseAndSetIfChanged(ref _keys, value); + } + public bool State + { + get => _state; + set => this.RaiseAndSetIfChanged(ref _state, value); + } + public bool CanRaiseDialog { get; set; } + public BaseSimulatedKeystrokeTypeVm? SimulatedKeystrokeType + { + get => _simulatedKeystrokeTypeVm; + set => this.RaiseAndSetIfChanged(ref _simulatedKeystrokeTypeVm, value); + } + public bool BlockOriginalMouseInput + { + get => _blockOriginalMouseInput; + set => this.RaiseAndSetIfChanged(ref _blockOriginalMouseInput, value); + } + + public override string? ToString() + { + return Description; + } + + public bool Equals(BaseButtonMappingVm? other) + { + if (ReferenceEquals(null, other)) + return false; + if (ReferenceEquals(this, other)) + return true; + return Id == other.Id + && Index == other.Index + && Enabled == other.Enabled + && Description == other.Description + && PriorityDescription == other.PriorityDescription + && Keys == other.Keys + && State == other.State + && CanRaiseDialog == other.CanRaiseDialog + && Equals(SimulatedKeystrokeType, other.SimulatedKeystrokeType) + && BlockOriginalMouseInput == other.BlockOriginalMouseInput; + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) + return false; + if (ReferenceEquals(this, obj)) + return true; + if (obj.GetType() != this.GetType()) + return false; + return Equals((BaseButtonMappingVm)obj); + } + + public override int GetHashCode() + { + var hashCode = new HashCode(); + hashCode.Add(Id); + hashCode.Add(Index); + hashCode.Add(Enabled); + hashCode.Add(Description); + hashCode.Add(PriorityDescription); + hashCode.Add(Keys); + hashCode.Add(State); + hashCode.Add(CanRaiseDialog); + hashCode.Add(SimulatedKeystrokeType); + hashCode.Add(BlockOriginalMouseInput); + return hashCode.ToHashCode(); + } +} + +public class DisabledMappingVm : BaseButtonMappingVm +{ + public DisabledMappingVm() + { + Index = 1; + Description = "Disabled"; + } +} + +public class NothingMappingVm : BaseButtonMappingVm +{ + public NothingMappingVm() + { + Index = 0; + Description = "** No Change (Don't Intercept) **"; + } +} + +public class SimulatedKeystrokeVm : BaseButtonMappingVm +{ + public SimulatedKeystrokeVm() + { + Index = 2; + Description = "Simulated Keys (undefined)"; + CanRaiseDialog = true; + BlockOriginalMouseInput = true; + } + + public override string? ToString() + { + var myStr = SimulatedKeystrokeType is not null + ? $"Simulated Keys: ({SimulatedKeystrokeType.ShortDescription})" + : Description; + + if (!string.IsNullOrWhiteSpace(PriorityDescription)) + { + myStr += $"[{PriorityDescription}]"; + } + + if (!string.IsNullOrWhiteSpace(Keys)) + { + myStr += $"[{Keys}]"; + } + + return myStr; + } +} + +public class RightClickVm : BaseButtonMappingVm +{ + public RightClickVm() + { + Index = 3; + Description = "Right Click"; + } +} diff --git a/YMouseButtonControl.Core/ViewModels/Models/BaseSettingVm.cs b/YMouseButtonControl.Core/ViewModels/Models/BaseSettingVm.cs new file mode 100644 index 0000000..16098cc --- /dev/null +++ b/YMouseButtonControl.Core/ViewModels/Models/BaseSettingVm.cs @@ -0,0 +1,105 @@ +using System; +using ReactiveUI; + +namespace YMouseButtonControl.Core.ViewModels.Models; + +public abstract class BaseSettingVm : ReactiveObject, IEquatable +{ + public int Id { get; set; } + public required string Name { get; set; } + + public bool Equals(BaseSettingVm? other) + { + if (ReferenceEquals(null, other)) + return false; + if (ReferenceEquals(this, other)) + return true; + return Id == other.Id && Name == other.Name; + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) + return false; + if (ReferenceEquals(this, obj)) + return true; + if (obj.GetType() != this.GetType()) + return false; + return Equals((BaseSettingVm)obj); + } + + public override int GetHashCode() + { + return HashCode.Combine(Id, Name); + } +} + +public class SettingBoolVm : BaseSettingVm, IEquatable +{ + private bool _value; + public bool Value + { + get => _value; + set => this.RaiseAndSetIfChanged(ref _value, value); + } + + public bool Equals(SettingBoolVm? other) + { + if (ReferenceEquals(null, other)) + return false; + if (ReferenceEquals(this, other)) + return true; + return base.Equals(other) && _value == other._value; + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) + return false; + if (ReferenceEquals(this, obj)) + return true; + if (obj.GetType() != this.GetType()) + return false; + return Equals((SettingBoolVm)obj); + } + + public override int GetHashCode() + { + return HashCode.Combine(base.GetHashCode(), _value); + } +} + +public class SettingStringVm : BaseSettingVm, IEquatable +{ + private string? _value; + public string? Value + { + get => _value; + set => this.RaiseAndSetIfChanged(ref _value, value); + } + + public bool Equals(SettingStringVm? other) + { + if (ReferenceEquals(null, other)) + return false; + if (ReferenceEquals(this, other)) + return true; + return base.Equals(other) && _value == other._value; + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) + return false; + if (ReferenceEquals(this, obj)) + return true; + if (obj.GetType() != this.GetType()) + return false; + return Equals((SettingStringVm)obj); + } + + public override int GetHashCode() + { + return HashCode.Combine(base.GetHashCode(), _value); + } +} diff --git a/YMouseButtonControl.Core/ViewModels/Models/BaseSimulatedKeystrokeTypeVm.cs b/YMouseButtonControl.Core/ViewModels/Models/BaseSimulatedKeystrokeTypeVm.cs new file mode 100644 index 0000000..6eb13bd --- /dev/null +++ b/YMouseButtonControl.Core/ViewModels/Models/BaseSimulatedKeystrokeTypeVm.cs @@ -0,0 +1,165 @@ +using System; +using Newtonsoft.Json; +using ReactiveUI; + +namespace YMouseButtonControl.Core.ViewModels.Models; + +[JsonObject(MemberSerialization.OptOut)] +public abstract class BaseSimulatedKeystrokeTypeVm + : ReactiveObject, + IEquatable +{ + private int _index; + private string? _description; + private string? _shortDescription; + private bool _enabled; + public int Index + { + get => _index; + set => this.RaiseAndSetIfChanged(ref _index, value); + } + public string? Description + { + get => _description; + set => this.RaiseAndSetIfChanged(ref _description, value); + } + public string? ShortDescription + { + get => _shortDescription; + set => this.RaiseAndSetIfChanged(ref _shortDescription, value); + } + public bool Enabled + { + get => _enabled; + set => this.RaiseAndSetIfChanged(ref _enabled, value); + } + + public override string ToString() => $"{Index + 1} {Description}"; + + public bool Equals(BaseSimulatedKeystrokeTypeVm? other) + { + if (ReferenceEquals(null, other)) + return false; + if (ReferenceEquals(this, other)) + return true; + return Index == other.Index + && Description == other.Description + && ShortDescription == other.ShortDescription + && Enabled == other.Enabled; + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) + return false; + if (ReferenceEquals(this, obj)) + return true; + if (obj.GetType() != this.GetType()) + return false; + return Equals((BaseSimulatedKeystrokeTypeVm)obj); + } + + public override int GetHashCode() + { + return HashCode.Combine(Index, Description, ShortDescription, Enabled); + } +} + +public class AsMousePressedAndReleasedActionTypeVm : BaseSimulatedKeystrokeTypeVm +{ + public AsMousePressedAndReleasedActionTypeVm() + { + Index = 8; + Description = "As mouse button is pressed & when released"; + ShortDescription = "pressed & released"; + Enabled = true; + } +} + +public class DuringMouseActionTypeVm : BaseSimulatedKeystrokeTypeVm +{ + public DuringMouseActionTypeVm() + { + Index = 2; + Description = "During (press on down, release on up)"; + ShortDescription = "during"; + Enabled = true; + } +} + +public class InAnotherThreadPressedActionTypeVm : BaseSimulatedKeystrokeTypeVm +{ + public InAnotherThreadPressedActionTypeVm() + { + Index = 3; + Description = "In another thread as mouse button is pressed"; + ShortDescription = "thread-down"; + Enabled = false; + } +} + +public class InAnotherThreadReleasedActionTypeVm : BaseSimulatedKeystrokeTypeVm +{ + public InAnotherThreadReleasedActionTypeVm() + { + Index = 4; + Description = "In another thread as mouse button is released"; + ShortDescription = "thread-up"; + Enabled = false; + } +} + +public class MouseButtonPressedActionTypeVm : BaseSimulatedKeystrokeTypeVm +{ + public MouseButtonPressedActionTypeVm() + { + Index = 0; + Description = "As mouse button is pressed"; + ShortDescription = "pressed"; + Enabled = true; + } +} + +public class MouseButtonReleasedActionTypeVm : BaseSimulatedKeystrokeTypeVm +{ + public MouseButtonReleasedActionTypeVm() + { + Index = 1; + Description = "As mouse button is released"; + ShortDescription = "released"; + Enabled = true; + } +} + +public class RepeatedlyWhileButtonDownActionTypeVm : BaseSimulatedKeystrokeTypeVm +{ + public RepeatedlyWhileButtonDownActionTypeVm() + { + Index = 5; + Description = "Repeatedly while the button is down"; + ShortDescription = "repeat"; + Enabled = true; + } +} + +public class StickyHoldActionTypeVm : BaseSimulatedKeystrokeTypeVm +{ + public StickyHoldActionTypeVm() + { + Index = 7; + Description = "Sticky (held down until button is pressed again)"; + ShortDescription = "sticky hold"; + Enabled = true; + } +} + +public class StickyRepeatActionTypeVm : BaseSimulatedKeystrokeTypeVm +{ + public StickyRepeatActionTypeVm() + { + Index = 6; + Description = "Sticky (repeatedly until button is pressed again)"; + ShortDescription = "sticky repeat"; + Enabled = true; + } +} diff --git a/YMouseButtonControl.Core/ViewModels/Models/ProfileVm.cs b/YMouseButtonControl.Core/ViewModels/Models/ProfileVm.cs new file mode 100644 index 0000000..60571de --- /dev/null +++ b/YMouseButtonControl.Core/ViewModels/Models/ProfileVm.cs @@ -0,0 +1,242 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using DynamicData; +using Newtonsoft.Json; +using ReactiveUI; +using YMouseButtonControl.DataAccess.Models; + +namespace YMouseButtonControl.Core.ViewModels.Models; + +[JsonObject(MemberSerialization.OptOut)] +public class ProfileVm : ReactiveObject, IEquatable +{ + private string? _description; + private bool _checked; + private string _name = string.Empty; + private string _windowCaption = "N/A"; + private string _process = "N/A"; + private string _windowClass = "N/A"; + private string _parentClass = "N/A"; + private string _matchType = "N/A"; + private int _displayPriority; + + private readonly SourceCache _btnSc; + + public ProfileVm(List buttonMappings) + { + _btnSc = new SourceCache(x => x.MouseButton); + _btnSc.Edit(x => x.AddOrUpdate(buttonMappings)); + } + + [JsonIgnore] + public int Id { get; set; } + public bool IsDefault { get; set; } + public bool Checked + { + get => _checked; + set => this.RaiseAndSetIfChanged(ref _checked, value); + } + public string Name + { + get => _name; + set => this.RaiseAndSetIfChanged(ref _name, value); + } + + public required string Description + { + get + { + if (Name == "Default") + { + return "Default"; + } + + return string.IsNullOrWhiteSpace(_description) ? Process : _description; + } + set => this.RaiseAndSetIfChanged(ref _description, value); + } + + public string WindowCaption + { + get => _windowCaption; + set => this.RaiseAndSetIfChanged(ref _windowCaption, value); + } + + public required string Process + { + get => _process; + set => this.RaiseAndSetIfChanged(ref _process, value); + } + public required string WindowClass + { + get => _windowClass; + set => this.RaiseAndSetIfChanged(ref _windowClass, value); + } + public required string ParentClass + { + get => _parentClass; + set => this.RaiseAndSetIfChanged(ref _parentClass, value); + } + public required string MatchType + { + get => _matchType; + set => this.RaiseAndSetIfChanged(ref _matchType, value); + } + + public List ButtonMappings => _btnSc.Items.ToList(); + + [JsonIgnore] + public BaseButtonMappingVm MouseButton1 + { + get => _btnSc.Items.First(x => x.MouseButton == MouseButton.Mb1); + set + { + _btnSc.Edit(updater => updater.AddOrUpdate(value)); + this.RaisePropertyChanged(); + } + } + + [JsonIgnore] + public BaseButtonMappingVm MouseButton2 + { + get => _btnSc.Items.First(x => x.MouseButton == MouseButton.Mb2); + set + { + _btnSc.Edit(updater => updater.AddOrUpdate(value)); + this.RaisePropertyChanged(); + } + } + + [JsonIgnore] + public BaseButtonMappingVm MouseButton3 + { + get => _btnSc.Items.First(x => x.MouseButton == MouseButton.Mb3); + set + { + _btnSc.Edit(updater => updater.AddOrUpdate(value)); + this.RaisePropertyChanged(); + } + } + + [JsonIgnore] + public BaseButtonMappingVm MouseButton4 + { + get => _btnSc.Items.First(x => x.MouseButton == MouseButton.Mb4); + set + { + _btnSc.Edit(updater => updater.AddOrUpdate(value)); + this.RaisePropertyChanged(); + } + } + + [JsonIgnore] + public BaseButtonMappingVm MouseButton5 + { + get => _btnSc.Items.First(x => x.MouseButton == MouseButton.Mb5); + set + { + _btnSc.Edit(updater => updater.AddOrUpdate(value)); + this.RaisePropertyChanged(); + } + } + + [JsonIgnore] + public BaseButtonMappingVm MouseWheelUp + { + get => _btnSc.Items.First(x => x.MouseButton == MouseButton.Mwu); + set + { + _btnSc.Edit(updater => updater.AddOrUpdate(value)); + this.RaisePropertyChanged(); + } + } + + [JsonIgnore] + public BaseButtonMappingVm MouseWheelDown + { + get => _btnSc.Items.First(x => x.MouseButton == MouseButton.Mwd); + set + { + _btnSc.Edit(updater => updater.AddOrUpdate(value)); + this.RaisePropertyChanged(); + } + } + + [JsonIgnore] + public BaseButtonMappingVm MouseWheelLeft + { + get => _btnSc.Items.First(x => x.MouseButton == MouseButton.Mwl); + set + { + _btnSc.Edit(updater => updater.AddOrUpdate(value)); + this.RaisePropertyChanged(); + } + } + + [JsonIgnore] + public BaseButtonMappingVm MouseWheelRight + { + get => _btnSc.Items.First(x => x.MouseButton == MouseButton.Mwr); + set + { + _btnSc.Edit(updater => updater.AddOrUpdate(value)); + this.RaisePropertyChanged(); + } + } + + public int DisplayPriority + { + get => _displayPriority; + set => this.RaiseAndSetIfChanged(ref _displayPriority, value); + } + + public bool Equals(ProfileVm? other) + { + if (ReferenceEquals(null, other)) + return false; + if (ReferenceEquals(this, other)) + return true; + return Description == other.Description + && Checked == other.Checked + && Name == other.Name + && WindowCaption == other.WindowCaption + && Process == other.Process + && WindowClass == other.WindowClass + && ParentClass == other.ParentClass + && MatchType == other.MatchType + && IsDefault == other.IsDefault + && ButtonMappings.SequenceEqual(other.ButtonMappings) + && DisplayPriority == other.DisplayPriority; + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) + return false; + if (ReferenceEquals(this, obj)) + return true; + if (obj.GetType() != this.GetType()) + return false; + return Equals((ProfileVm)obj); + } + + public override int GetHashCode() + { + var hashCode = new HashCode(); + hashCode.Add(_description); + hashCode.Add(_checked); + hashCode.Add(_name); + hashCode.Add(_windowCaption); + hashCode.Add(_process); + hashCode.Add(_windowClass); + hashCode.Add(_parentClass); + hashCode.Add(_matchType); + hashCode.Add(_btnSc); + hashCode.Add(Id); + hashCode.Add(IsDefault); + hashCode.Add(ButtonMappings); + hashCode.Add(DisplayPriority); + return hashCode.ToHashCode(); + } +} diff --git a/YMouseButtonControl.Core/ViewModels/Models/SimulatedKeystrokesDialogModel.cs b/YMouseButtonControl.Core/ViewModels/Models/SimulatedKeystrokesDialogModel.cs deleted file mode 100644 index 4ddbcb4..0000000 --- a/YMouseButtonControl.Core/ViewModels/Models/SimulatedKeystrokesDialogModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; - -namespace YMouseButtonControl.Core.ViewModels.Models; - -public class SimulatedKeystrokesDialogModel -{ - public string? CustomKeys { get; set; } - public ISimulatedKeystrokesType? SimulatedKeystrokesType { get; set; } - public string? Description { get; set; } - public bool BlockOriginalMouseInput { get; set; } -} diff --git a/YMouseButtonControl.Core/ViewModels/ProfilesInformationViewModel/ProfilesInformationViewModel.cs b/YMouseButtonControl.Core/ViewModels/ProfilesInformationViewModel/ProfilesInformationViewModel.cs new file mode 100644 index 0000000..9b27dad --- /dev/null +++ b/YMouseButtonControl.Core/ViewModels/ProfilesInformationViewModel/ProfilesInformationViewModel.cs @@ -0,0 +1,15 @@ +using YMouseButtonControl.Core.Services.Profiles; + +namespace YMouseButtonControl.Core.ViewModels.ProfilesInformationViewModel; + +public interface IProfilesInformationViewModel +{ + public IProfilesService ProfilesService { get; } +} + +public class ProfilesInformationViewModel(IProfilesService profilesService) + : ViewModelBase, + IProfilesInformationViewModel +{ + public IProfilesService ProfilesService { get; } = profilesService; +} diff --git a/YMouseButtonControl.Core/ViewModels/ProfilesList/Features/Add/AddProfile.cs b/YMouseButtonControl.Core/ViewModels/ProfilesList/Features/Add/AddProfile.cs index 75d4a96..ae3ca17 100644 --- a/YMouseButtonControl.Core/ViewModels/ProfilesList/Features/Add/AddProfile.cs +++ b/YMouseButtonControl.Core/ViewModels/ProfilesList/Features/Add/AddProfile.cs @@ -1,17 +1,17 @@ using System.Linq; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.Profiles.Interfaces; +using YMouseButtonControl.Core.Services.Profiles; +using YMouseButtonControl.Core.ViewModels.Models; namespace YMouseButtonControl.Core.ViewModels.ProfilesList.Features.Add; public interface IAddProfile { - void Add(Profile profile); + void Add(ProfileVm profile); } public class AddProfile(IProfilesService profilesService) : IAddProfile { - public void Add(Profile profile) + public void Add(ProfileVm profile) { profile.Id = GetNextProfileId(); profile.DisplayPriority = GetNextProfileDisplayPriority(); diff --git a/YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/ProcessSelectorDialogViewModel.cs b/YMouseButtonControl.Core/ViewModels/ProfilesList/ProcessSelectorDialogViewModel.cs similarity index 61% rename from YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/ProcessSelectorDialogViewModel.cs rename to YMouseButtonControl.Core/ViewModels/ProfilesList/ProcessSelectorDialogViewModel.cs index 0338139..8f60391 100644 --- a/YMouseButtonControl.Core/ViewModels/Implementations/Dialogs/ProcessSelectorDialogViewModel.cs +++ b/YMouseButtonControl.Core/ViewModels/ProfilesList/ProcessSelectorDialogViewModel.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Collections.ObjectModel; using System.Reactive; using System.Reactive.Linq; @@ -6,12 +7,16 @@ using DynamicData; using DynamicData.Binding; using ReactiveUI; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.Processes; -using YMouseButtonControl.Core.Services.Abstractions.Models; -using YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; +using YMouseButtonControl.Core.Services.Processes; +using YMouseButtonControl.Core.ViewModels.Models; +using YMouseButtonControl.DataAccess.Models; -namespace YMouseButtonControl.Core.ViewModels.Implementations.Dialogs; +namespace YMouseButtonControl.Core.ViewModels.ProfilesList; + +public interface IProcessSelectorDialogViewModel +{ + ICommand RefreshButtonCommand { get; } +} public class ProcessSelectorDialogViewModel : DialogBase, IProcessSelectorDialogViewModel { @@ -40,12 +45,41 @@ public ProcessSelectorDialogViewModel(IProcessMonitorService processMonitorServi ); OkCommand = ReactiveCommand.Create( () => - new Profile + { + var mb1 = new NothingMappingVm { MouseButton = MouseButton.Mb1 }; + var mb2 = new NothingMappingVm { MouseButton = MouseButton.Mb2 }; + var mb3 = new NothingMappingVm { MouseButton = MouseButton.Mb3 }; + var mb4 = new NothingMappingVm { MouseButton = MouseButton.Mb4 }; + var mb5 = new NothingMappingVm { MouseButton = MouseButton.Mb5 }; + var mwu = new NothingMappingVm { MouseButton = MouseButton.Mwu }; + var mwd = new NothingMappingVm { MouseButton = MouseButton.Mwd }; + var mwl = new NothingMappingVm { MouseButton = MouseButton.Mwl }; + var mwr = new NothingMappingVm { MouseButton = MouseButton.Mwr }; + + var buttonMappings = new List() + { + mb1, + mb2, + mb3, + mb4, + mb5, + mwu, + mwd, + mwl, + mwr, + }; + + return new ProfileVm(buttonMappings) { Name = SelectedProcessModel!.Process.MainModule!.ModuleName, Description = SelectedProcessModel.Process.MainWindowTitle, Process = SelectedProcessModel.Process.MainModule.ModuleName, - }, + WindowCaption = "N/A", + WindowClass = "N/A", + ParentClass = "N/A", + MatchType = "N/A", + }; + }, canExecuteOkCommand ); } @@ -70,7 +104,7 @@ public string? ProcessFilter public ICommand RefreshButtonCommand { get; } - public ReactiveCommand OkCommand { get; } + public ReactiveCommand OkCommand { get; } public ReadOnlyObservableCollection Filtered => _filtered; diff --git a/YMouseButtonControl.Core/ViewModels/ProfilesList/ProfilesListViewModel.cs b/YMouseButtonControl.Core/ViewModels/ProfilesList/ProfilesListViewModel.cs index 0dd917c..9247924 100644 --- a/YMouseButtonControl.Core/ViewModels/ProfilesList/ProfilesListViewModel.cs +++ b/YMouseButtonControl.Core/ViewModels/ProfilesList/ProfilesListViewModel.cs @@ -1,24 +1,27 @@ +using System; +using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Reactive; using System.Reactive.Linq; +using System.Security; using System.Threading.Tasks; using System.Windows.Input; 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.Services.Profiles; +using YMouseButtonControl.Core.ViewModels.Models; using YMouseButtonControl.Core.ViewModels.ProfilesList.Features.Add; namespace YMouseButtonControl.Core.ViewModels.ProfilesList; +public interface IProfilesListViewModel; + public class ProfilesListViewModel : ViewModelBase, IProfilesListViewModel { private IProfilesService _profilesService; private readonly IProcessSelectorDialogViewModel _processSelectorDialogViewModel; private readonly IAddProfile _addProfile; + private int _selectedIndex; public ICommand AddButtonCommand { get; } public ReactiveCommand EditButtonCommand { get; } @@ -30,7 +33,7 @@ public class ProfilesListViewModel : ViewModelBase, IProfilesListViewModel public ReactiveCommand ImportCommand { get; } public Interaction< IProcessSelectorDialogViewModel, - Profile? + ProfileVm? > ShowProcessSelectorInteraction { get; } public ProfilesListViewModel( @@ -46,52 +49,84 @@ IAddProfile addProfile ImportCommand = ReactiveCommand.CreateFromTask(OnImportClickedAsync); var exportCanExecute = this.WhenAnyValue( x => x.ProfilesService.CurrentProfile, - curProf => - { - Debug.Assert(curProf != null, nameof(curProf) + " != null"); - return !curProf.IsDefault; - } + curProf => !curProf?.IsDefault ?? false ); ExportCommand = ReactiveCommand.CreateFromTask(OnExportClickedAsync, exportCanExecute); var removeCanExecute = this.WhenAnyValue( x => x.ProfilesService.CurrentProfile, - curProf => - { - Debug.Assert(curProf != null, nameof(curProf) + " != null"); - return !curProf.IsDefault; - } + curProf => !curProf?.IsDefault ?? false ); RemoveButtonCommand = ReactiveCommand.Create(OnRemoveButtonClicked, removeCanExecute); - var upCommandCanExecute = this.WhenAnyValue(x => x.ProfilesService.CurrentProfile) - .WhereNotNull() - .Select(x => - !x.IsDefault + var upCommandCanExecute = this.WhenAnyValue( + x => x.ProfilesService.CurrentProfile, + x => x.ProfilesService.CurrentProfile!.DisplayPriority, + selector: (curProf, _) => + curProf is not null + && !curProf.IsDefault && _profilesService.Profiles.Any(p => - !p.IsDefault && p.DisplayPriority < x.DisplayPriority + !p.IsDefault && p.DisplayPriority < curProf.DisplayPriority ) - ); + ); UpCommand = ReactiveCommand.Create(UpButtonClicked, upCommandCanExecute); - var downCommandCanExecute = this.WhenAnyValue(x => x.ProfilesService.CurrentProfile) - .WhereNotNull() - .Select(curProf => - !curProf.IsDefault + var downCommandCanExecute = this.WhenAnyValue( + x => x.ProfilesService.CurrentProfile, + x => x.ProfilesService.CurrentProfile!.DisplayPriority, + selector: (curProf, _) => + curProf is not null + && !curProf.IsDefault && _profilesService.Profiles.Any(p => p.DisplayPriority > curProf.DisplayPriority) - ); + ); DownCommand = ReactiveCommand.Create(DownButtonClicked, downCommandCanExecute); _processSelectorDialogViewModel = processSelectorDialogViewModel; _addProfile = addProfile; ShowProcessSelectorInteraction = - new Interaction(); + new Interaction(); var editCanExecute = this.WhenAnyValue( x => x.ProfilesService.CurrentProfile, - curProf => - { - Debug.Assert(curProf != null, nameof(curProf) + " != null"); - return !curProf.IsDefault; - } + curProf => !curProf?.IsDefault ?? false ); EditButtonCommand = ReactiveCommand.CreateFromTask(EditButtonClickedAsync, editCanExecute); CopyCommand = ReactiveCommand.CreateFromTask(OnCopyClickedAsync); + + // _profilesService.CurrentProfile = _profilesService.Profiles[SelectedIndex]; + SelectedIndex = _profilesService.Profiles.First(x => x.IsDefault).DisplayPriority; + this.WhenAnyValue(x => x.SelectedIndex) + .Subscribe(x => + { + if (_profilesService.CurrentProfile is null) + { + _profilesService.CurrentProfile = _profilesService.Profiles[x]; + } + else + { + if (SelectedIndex < 0) + { + SelectedIndex = _profilesService.CurrentProfile!.DisplayPriority; + } + else + { + if (_profilesService.Profiles.Count < x) + { + // _profilesService.CurrentProfile = _profilesService.Profiles.First(y => + // y.IsDefault + // ); + SelectedIndex = _profilesService + .Profiles.First(y => y.IsDefault) + .DisplayPriority; + } + else + { + _profilesService.CurrentProfile = _profilesService.Profiles[x]; + } + } + } + }); + } + + public int SelectedIndex + { + get => _selectedIndex; + set => this.RaiseAndSetIfChanged(ref _selectedIndex, value); } public Interaction ShowExportFileDialog { get; } @@ -180,6 +215,7 @@ private void DownButtonClicked() "_profilesService.CurrentProfile != null" ); _profilesService.MoveProfileDown(_profilesService.CurrentProfile); + // SelectedIndex++; } private async Task EditButtonClickedAsync() diff --git a/YMouseButtonControl.Core/ViewModels/Services/DialogResultBase.cs b/YMouseButtonControl.Core/ViewModels/Services/DialogResultBase.cs deleted file mode 100644 index 1a0def3..0000000 --- a/YMouseButtonControl.Core/ViewModels/Services/DialogResultBase.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace YMouseButtonControl.Core.ViewModels.Services; - -public class DialogResultBase { } diff --git a/YMouseButtonControl.Core/ViewModels/Services/NavigationParameterBase.cs b/YMouseButtonControl.Core/ViewModels/Services/NavigationParameterBase.cs deleted file mode 100644 index 644b116..0000000 --- a/YMouseButtonControl.Core/ViewModels/Services/NavigationParameterBase.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace YMouseButtonControl.Core.ViewModels.Services; - -public class NavigationParameterBase { } diff --git a/YMouseButtonControl.Core/ViewModels/Services/ShowSimulatedKeystrokesDialogService.cs b/YMouseButtonControl.Core/ViewModels/Services/ShowSimulatedKeystrokesDialogService.cs deleted file mode 100644 index 9c25c27..0000000 --- a/YMouseButtonControl.Core/ViewModels/Services/ShowSimulatedKeystrokesDialogService.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Reactive.Linq; -using System.Threading.Tasks; -using ReactiveUI; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; -using YMouseButtonControl.Core.ViewModels.Implementations.Dialogs; -using YMouseButtonControl.Core.ViewModels.Interfaces.Dialogs; -using YMouseButtonControl.Core.ViewModels.Models; - -namespace YMouseButtonControl.Core.ViewModels.Services; - -public class ShowSimulatedKeystrokesDialogService(IMouseListener mouseListener) - : IShowSimulatedKeystrokesDialogService -{ - public Interaction< - SimulatedKeystrokesDialogViewModel, - SimulatedKeystrokesDialogModel? - > ShowSimulatedKeystrokesPickerInteraction { get; } = new(); - - public async Task ShowSimulatedKeystrokesDialog(string buttonName) - { - return await ShowSimulatedKeystrokesDialog(buttonName, null); - } - - public async Task ShowSimulatedKeystrokesDialog( - string buttonName, - IButtonMapping? mapping - ) - { - var result = await ShowSimulatedKeystrokesPickerInteraction.Handle( - new SimulatedKeystrokesDialogViewModel(mouseListener, buttonName, mapping) - ); - if (result is null) - { - return null; - } - - return new SimulatedKeystrokes - { - Keys = result.CustomKeys, - PriorityDescription = result.Description, - SimulatedKeystrokesType = result.SimulatedKeystrokesType, - BlockOriginalMouseInput = result.BlockOriginalMouseInput, - }; - } -} diff --git a/YMouseButtonControl.Core/ViewModels/Implementations/ViewModelBase.cs b/YMouseButtonControl.Core/ViewModels/ViewModelBase.cs similarity index 52% rename from YMouseButtonControl.Core/ViewModels/Implementations/ViewModelBase.cs rename to YMouseButtonControl.Core/ViewModels/ViewModelBase.cs index 74b5b76..8b21d28 100644 --- a/YMouseButtonControl.Core/ViewModels/Implementations/ViewModelBase.cs +++ b/YMouseButtonControl.Core/ViewModels/ViewModelBase.cs @@ -1,5 +1,5 @@ using ReactiveUI; -namespace YMouseButtonControl.Core.ViewModels.Implementations; +namespace YMouseButtonControl.Core.ViewModels; public class ViewModelBase : ReactiveObject { } diff --git a/YMouseButtonControl.Core/YMouseButtonControl.Core.csproj b/YMouseButtonControl.Core/YMouseButtonControl.Core.csproj index 3dbafa0..5af5edd 100644 --- a/YMouseButtonControl.Core/YMouseButtonControl.Core.csproj +++ b/YMouseButtonControl.Core/YMouseButtonControl.Core.csproj @@ -18,19 +18,22 @@ - - + + + + - - - + + + + diff --git a/YMouseButtonControl.DataAccess.LiteDb/LiteDbUnitOfWork.cs b/YMouseButtonControl.DataAccess.LiteDb/LiteDbUnitOfWork.cs deleted file mode 100644 index 4c77b80..0000000 --- a/YMouseButtonControl.DataAccess.LiteDb/LiteDbUnitOfWork.cs +++ /dev/null @@ -1,20 +0,0 @@ -using LiteDB; -using YMouseButtonControl.Core.DataAccess.Repositories; -using YMouseButtonControl.Core.DataAccess.UnitOfWork; - -namespace YMouseButtonControl.DataAccess.LiteDb; - -public class LiteDbUnitOfWork(LiteDatabase database) : IUnitOfWork -{ - public IRepository GetRepository() - where T : class - { - var collection = database.GetCollection(); - - return new Repository(collection); - } - - public void SaveChanges() => database.Commit(); - - public void Dispose() => database.Dispose(); -} diff --git a/YMouseButtonControl.DataAccess.LiteDb/LiteDbUnitOfWorkFactory.cs b/YMouseButtonControl.DataAccess.LiteDb/LiteDbUnitOfWorkFactory.cs deleted file mode 100644 index 64171c6..0000000 --- a/YMouseButtonControl.DataAccess.LiteDb/LiteDbUnitOfWorkFactory.cs +++ /dev/null @@ -1,22 +0,0 @@ -using LiteDB; -using YMouseButtonControl.Core.DataAccess.Configuration; -using YMouseButtonControl.Core.DataAccess.UnitOfWork; - -namespace YMouseButtonControl.DataAccess.LiteDb; - -public class LiteDbUnitOfWorkFactory(DatabaseConfiguration databaseConfiguration) - : IUnitOfWorkFactory -{ - public IUnitOfWork Create() => - new LiteDbUnitOfWork( - databaseConfiguration.UseInMemoryDatabase - ? CreateInMemoryDatabase() - : CreateDatabaseFromConnectionString() - ); - - private static LiteDatabase CreateInMemoryDatabase() => - new("Filename=:memory:;Connection=shared"); - - private LiteDatabase CreateDatabaseFromConnectionString() => - new(databaseConfiguration.ConnectionString); -} diff --git a/YMouseButtonControl.DataAccess.LiteDb/Repository.cs b/YMouseButtonControl.DataAccess.LiteDb/Repository.cs deleted file mode 100644 index 0e2512d..0000000 --- a/YMouseButtonControl.DataAccess.LiteDb/Repository.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Collections.Generic; -using LiteDB; -using YMouseButtonControl.Core.DataAccess.Repositories; - -namespace YMouseButtonControl.DataAccess.LiteDb; - -public class Repository(ILiteCollection collection) : IRepository - where T : class -{ - 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); - - public void Update(string id, T entity) => collection.Update(id, entity); - - public void Upsert(string id, T entity) => collection.Upsert(id, entity); - - public void Remove(string id) => collection.Delete(id); - - public void ApplyAction(IEnumerable entities) - { - collection.DeleteAll(); - collection.InsertBulk(entities); - } -} diff --git a/YMouseButtonControl.DataAccess.LiteDb/YMouseButtonControl.DataAccess.LiteDb.csproj b/YMouseButtonControl.DataAccess.LiteDb/YMouseButtonControl.DataAccess.LiteDb.csproj deleted file mode 100644 index 73dd05f..0000000 --- a/YMouseButtonControl.DataAccess.LiteDb/YMouseButtonControl.DataAccess.LiteDb.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - net8.0 - latest - enable - - - - true - - - - true - - - - - - - - - - - diff --git a/YMouseButtonControl.DataAccess/Context/YMouseButtonControlDbContext.cs b/YMouseButtonControl.DataAccess/Context/YMouseButtonControlDbContext.cs new file mode 100644 index 0000000..3195cd8 --- /dev/null +++ b/YMouseButtonControl.DataAccess/Context/YMouseButtonControlDbContext.cs @@ -0,0 +1,123 @@ +using Microsoft.EntityFrameworkCore; +using YMouseButtonControl.DataAccess.Models; + +namespace YMouseButtonControl.DataAccess.Context; + +public class YMouseButtonControlDbContext(DbContextOptions options) + : DbContext(options) +{ + public DbSet Settings { get; set; } + public DbSet SettingBools { get; set; } + public DbSet SettingStrings { get; set; } + public DbSet Profiles { get; set; } + public DbSet ButtonMappings { get; set; } + public DbSet DisabledMappings { get; set; } + public DbSet NothingMappings { get; set; } + public DbSet SimulatedKeystrokes { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + + modelBuilder + .Entity() + .HasData( + [ + new NothingMapping + { + Id = 1, + ProfileId = 1, + MouseButton = MouseButton.Mb1, + }, + new NothingMapping + { + Id = 2, + ProfileId = 1, + MouseButton = MouseButton.Mb2, + }, + new NothingMapping + { + Id = 3, + ProfileId = 1, + MouseButton = MouseButton.Mb3, + }, + new NothingMapping + { + Id = 4, + ProfileId = 1, + MouseButton = MouseButton.Mb4, + }, + new NothingMapping + { + Id = 5, + ProfileId = 1, + MouseButton = MouseButton.Mb5, + }, + new NothingMapping + { + Id = 6, + ProfileId = 1, + MouseButton = MouseButton.Mwu, + }, + new NothingMapping + { + Id = 7, + ProfileId = 1, + MouseButton = MouseButton.Mwd, + }, + new NothingMapping + { + Id = 8, + ProfileId = 1, + MouseButton = MouseButton.Mwl, + }, + new NothingMapping + { + Id = 9, + ProfileId = 1, + MouseButton = MouseButton.Mwr, + }, + ] + ); + modelBuilder + .Entity() + .HasData( + [ + new Profile + { + Id = 1, + Checked = true, + Name = "Default", + IsDefault = true, + Description = "Default description", + Process = "*", + MatchType = "N/A", + ParentClass = "N/A", + WindowCaption = "N/A", + WindowClass = "N/A", + }, + ] + ); + modelBuilder + .Entity() + .HasData( + [ + new SettingBool + { + Id = 1, + Name = "StartMinimized", + Value = false, + }, + ] + ); + } +} diff --git a/YMouseButtonControl.DataAccess/Migrations/20240928181229_Initial.Designer.cs b/YMouseButtonControl.DataAccess/Migrations/20240928181229_Initial.Designer.cs new file mode 100644 index 0000000..4e091e8 --- /dev/null +++ b/YMouseButtonControl.DataAccess/Migrations/20240928181229_Initial.Designer.cs @@ -0,0 +1,292 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using YMouseButtonControl.DataAccess.Context; + +#nullable disable + +namespace YMouseButtonControl.DataAccess.Migrations +{ + [DbContext(typeof(YMouseButtonControlDbContext))] + [Migration("20240928181229_Initial")] + partial class Initial + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "8.0.8"); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.ButtonMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BlockOriginalMouseInput") + .HasColumnType("INTEGER"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(21) + .HasColumnType("TEXT"); + + b.Property("Keys") + .HasColumnType("TEXT"); + + b.Property("MouseButton") + .HasColumnType("INTEGER"); + + b.Property("ProfileId") + .HasColumnType("INTEGER"); + + b.Property("SimulatedKeystrokeType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ProfileId"); + + b.ToTable("ButtonMappings"); + + b.HasDiscriminator().HasValue("ButtonMapping"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.Profile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Checked") + .HasColumnType("INTEGER"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DisplayPriority") + .HasColumnType("INTEGER"); + + b.Property("IsDefault") + .HasColumnType("INTEGER"); + + b.Property("MatchType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ParentClass") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Process") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("WindowCaption") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("WindowClass") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Profiles"); + + b.HasData( + new + { + Id = 1, + Checked = true, + Description = "Default description", + DisplayPriority = 0, + IsDefault = true, + MatchType = "N/A", + Name = "Default", + ParentClass = "N/A", + Process = "*", + WindowCaption = "N/A", + WindowClass = "N/A" + }); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(13) + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Settings"); + + b.HasDiscriminator().HasValue("Setting"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.DisabledMapping", b => + { + b.HasBaseType("YMouseButtonControl.DataAccess.Models.ButtonMapping"); + + b.HasDiscriminator().HasValue("DisabledMapping"); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.NothingMapping", b => + { + b.HasBaseType("YMouseButtonControl.DataAccess.Models.ButtonMapping"); + + b.HasDiscriminator().HasValue("NothingMapping"); + + b.HasData( + new + { + Id = 1, + BlockOriginalMouseInput = false, + MouseButton = 0, + ProfileId = 1 + }, + new + { + Id = 2, + BlockOriginalMouseInput = false, + MouseButton = 1, + ProfileId = 1 + }, + new + { + Id = 3, + BlockOriginalMouseInput = false, + MouseButton = 2, + ProfileId = 1 + }, + new + { + Id = 4, + BlockOriginalMouseInput = false, + MouseButton = 3, + ProfileId = 1 + }, + new + { + Id = 5, + BlockOriginalMouseInput = false, + MouseButton = 4, + ProfileId = 1 + }, + new + { + Id = 6, + BlockOriginalMouseInput = false, + MouseButton = 5, + ProfileId = 1 + }, + new + { + Id = 7, + BlockOriginalMouseInput = false, + MouseButton = 6, + ProfileId = 1 + }, + new + { + Id = 8, + BlockOriginalMouseInput = false, + MouseButton = 7, + ProfileId = 1 + }, + new + { + Id = 9, + BlockOriginalMouseInput = false, + MouseButton = 8, + ProfileId = 1 + }); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.RightClick", b => + { + b.HasBaseType("YMouseButtonControl.DataAccess.Models.ButtonMapping"); + + b.HasDiscriminator().HasValue("RightClick"); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.SimulatedKeystroke", b => + { + b.HasBaseType("YMouseButtonControl.DataAccess.Models.ButtonMapping"); + + b.HasDiscriminator().HasValue("SimulatedKeystroke"); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.SettingBool", b => + { + b.HasBaseType("YMouseButtonControl.DataAccess.Models.Setting"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasDiscriminator().HasValue("SettingBool"); + + b.HasData( + new + { + Id = 1, + Name = "StartMinimized", + Value = false + }); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.SettingString", b => + { + b.HasBaseType("YMouseButtonControl.DataAccess.Models.Setting"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.ToTable("Settings", t => + { + t.Property("Value") + .HasColumnName("SettingString_Value"); + }); + + b.HasDiscriminator().HasValue("SettingString"); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.ButtonMapping", b => + { + b.HasOne("YMouseButtonControl.DataAccess.Models.Profile", "Profile") + .WithMany("ButtonMappings") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.Profile", b => + { + b.Navigation("ButtonMappings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/YMouseButtonControl.DataAccess/Migrations/20240928181229_Initial.cs b/YMouseButtonControl.DataAccess/Migrations/20240928181229_Initial.cs new file mode 100644 index 0000000..1bfd5d8 --- /dev/null +++ b/YMouseButtonControl.DataAccess/Migrations/20240928181229_Initial.cs @@ -0,0 +1,122 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional + +namespace YMouseButtonControl.DataAccess.Migrations +{ + /// + public partial class Initial : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Profiles", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + IsDefault = table.Column(type: "INTEGER", nullable: false), + Checked = table.Column(type: "INTEGER", nullable: false), + DisplayPriority = table.Column(type: "INTEGER", nullable: false), + Name = table.Column(type: "TEXT", nullable: false), + Description = table.Column(type: "TEXT", nullable: false), + WindowCaption = table.Column(type: "TEXT", nullable: false), + Process = table.Column(type: "TEXT", nullable: false), + WindowClass = table.Column(type: "TEXT", nullable: false), + ParentClass = table.Column(type: "TEXT", nullable: false), + MatchType = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Profiles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Settings", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Name = table.Column(type: "TEXT", nullable: false), + Discriminator = table.Column(type: "TEXT", maxLength: 13, nullable: false), + Value = table.Column(type: "INTEGER", nullable: true), + SettingString_Value = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Settings", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ButtonMappings", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Keys = table.Column(type: "TEXT", nullable: true), + MouseButton = table.Column(type: "INTEGER", nullable: false), + ProfileId = table.Column(type: "INTEGER", nullable: false), + SimulatedKeystrokeType = table.Column(type: "INTEGER", nullable: true), + BlockOriginalMouseInput = table.Column(type: "INTEGER", nullable: false), + Discriminator = table.Column(type: "TEXT", maxLength: 21, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ButtonMappings", x => x.Id); + table.ForeignKey( + name: "FK_ButtonMappings_Profiles_ProfileId", + column: x => x.ProfileId, + principalTable: "Profiles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.InsertData( + table: "Profiles", + columns: new[] { "Id", "Checked", "Description", "DisplayPriority", "IsDefault", "MatchType", "Name", "ParentClass", "Process", "WindowCaption", "WindowClass" }, + values: new object[] { 1, true, "Default description", 0, true, "N/A", "Default", "N/A", "*", "N/A", "N/A" }); + + migrationBuilder.InsertData( + table: "Settings", + columns: new[] { "Id", "Discriminator", "Name", "Value" }, + values: new object[] { 1, "SettingBool", "StartMinimized", false }); + + migrationBuilder.InsertData( + table: "ButtonMappings", + columns: new[] { "Id", "BlockOriginalMouseInput", "Discriminator", "Keys", "MouseButton", "ProfileId", "SimulatedKeystrokeType" }, + values: new object[,] + { + { 1, false, "NothingMapping", null, 0, 1, null }, + { 2, false, "NothingMapping", null, 1, 1, null }, + { 3, false, "NothingMapping", null, 2, 1, null }, + { 4, false, "NothingMapping", null, 3, 1, null }, + { 5, false, "NothingMapping", null, 4, 1, null }, + { 6, false, "NothingMapping", null, 5, 1, null }, + { 7, false, "NothingMapping", null, 6, 1, null }, + { 8, false, "NothingMapping", null, 7, 1, null }, + { 9, false, "NothingMapping", null, 8, 1, null } + }); + + migrationBuilder.CreateIndex( + name: "IX_ButtonMappings_ProfileId", + table: "ButtonMappings", + column: "ProfileId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ButtonMappings"); + + migrationBuilder.DropTable( + name: "Settings"); + + migrationBuilder.DropTable( + name: "Profiles"); + } + } +} diff --git a/YMouseButtonControl.DataAccess/Migrations/YMouseButtonControlDbContextModelSnapshot.cs b/YMouseButtonControl.DataAccess/Migrations/YMouseButtonControlDbContextModelSnapshot.cs new file mode 100644 index 0000000..4da191b --- /dev/null +++ b/YMouseButtonControl.DataAccess/Migrations/YMouseButtonControlDbContextModelSnapshot.cs @@ -0,0 +1,289 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using YMouseButtonControl.DataAccess.Context; + +#nullable disable + +namespace YMouseButtonControl.DataAccess.Migrations +{ + [DbContext(typeof(YMouseButtonControlDbContext))] + partial class YMouseButtonControlDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "8.0.8"); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.ButtonMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BlockOriginalMouseInput") + .HasColumnType("INTEGER"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(21) + .HasColumnType("TEXT"); + + b.Property("Keys") + .HasColumnType("TEXT"); + + b.Property("MouseButton") + .HasColumnType("INTEGER"); + + b.Property("ProfileId") + .HasColumnType("INTEGER"); + + b.Property("SimulatedKeystrokeType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ProfileId"); + + b.ToTable("ButtonMappings"); + + b.HasDiscriminator().HasValue("ButtonMapping"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.Profile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Checked") + .HasColumnType("INTEGER"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DisplayPriority") + .HasColumnType("INTEGER"); + + b.Property("IsDefault") + .HasColumnType("INTEGER"); + + b.Property("MatchType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ParentClass") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Process") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("WindowCaption") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("WindowClass") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Profiles"); + + b.HasData( + new + { + Id = 1, + Checked = true, + Description = "Default description", + DisplayPriority = 0, + IsDefault = true, + MatchType = "N/A", + Name = "Default", + ParentClass = "N/A", + Process = "*", + WindowCaption = "N/A", + WindowClass = "N/A" + }); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(13) + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Settings"); + + b.HasDiscriminator().HasValue("Setting"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.DisabledMapping", b => + { + b.HasBaseType("YMouseButtonControl.DataAccess.Models.ButtonMapping"); + + b.HasDiscriminator().HasValue("DisabledMapping"); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.NothingMapping", b => + { + b.HasBaseType("YMouseButtonControl.DataAccess.Models.ButtonMapping"); + + b.HasDiscriminator().HasValue("NothingMapping"); + + b.HasData( + new + { + Id = 1, + BlockOriginalMouseInput = false, + MouseButton = 0, + ProfileId = 1 + }, + new + { + Id = 2, + BlockOriginalMouseInput = false, + MouseButton = 1, + ProfileId = 1 + }, + new + { + Id = 3, + BlockOriginalMouseInput = false, + MouseButton = 2, + ProfileId = 1 + }, + new + { + Id = 4, + BlockOriginalMouseInput = false, + MouseButton = 3, + ProfileId = 1 + }, + new + { + Id = 5, + BlockOriginalMouseInput = false, + MouseButton = 4, + ProfileId = 1 + }, + new + { + Id = 6, + BlockOriginalMouseInput = false, + MouseButton = 5, + ProfileId = 1 + }, + new + { + Id = 7, + BlockOriginalMouseInput = false, + MouseButton = 6, + ProfileId = 1 + }, + new + { + Id = 8, + BlockOriginalMouseInput = false, + MouseButton = 7, + ProfileId = 1 + }, + new + { + Id = 9, + BlockOriginalMouseInput = false, + MouseButton = 8, + ProfileId = 1 + }); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.RightClick", b => + { + b.HasBaseType("YMouseButtonControl.DataAccess.Models.ButtonMapping"); + + b.HasDiscriminator().HasValue("RightClick"); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.SimulatedKeystroke", b => + { + b.HasBaseType("YMouseButtonControl.DataAccess.Models.ButtonMapping"); + + b.HasDiscriminator().HasValue("SimulatedKeystroke"); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.SettingBool", b => + { + b.HasBaseType("YMouseButtonControl.DataAccess.Models.Setting"); + + b.Property("Value") + .HasColumnType("INTEGER"); + + b.HasDiscriminator().HasValue("SettingBool"); + + b.HasData( + new + { + Id = 1, + Name = "StartMinimized", + Value = false + }); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.SettingString", b => + { + b.HasBaseType("YMouseButtonControl.DataAccess.Models.Setting"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.ToTable("Settings", t => + { + t.Property("Value") + .HasColumnName("SettingString_Value"); + }); + + b.HasDiscriminator().HasValue("SettingString"); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.ButtonMapping", b => + { + b.HasOne("YMouseButtonControl.DataAccess.Models.Profile", "Profile") + .WithMany("ButtonMappings") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("YMouseButtonControl.DataAccess.Models.Profile", b => + { + b.Navigation("ButtonMappings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/YMouseButtonControl.DataAccess/Models/ButtonMapping.cs b/YMouseButtonControl.DataAccess/Models/ButtonMapping.cs new file mode 100644 index 0000000..5c86b2f --- /dev/null +++ b/YMouseButtonControl.DataAccess/Models/ButtonMapping.cs @@ -0,0 +1,39 @@ +namespace YMouseButtonControl.DataAccess.Models; + +public enum MouseButton +{ + Mb1, + Mb2, + Mb3, + Mb4, + Mb5, + Mwu, + Mwd, + Mwl, + Mwr, +} + +public abstract class ButtonMapping +{ + public int Id { get; set; } + public string? Keys { get; set; } + public required MouseButton MouseButton { get; set; } + public int ProfileId { get; set; } + public virtual Profile? Profile { get; set; } + public SimulatedKeystrokeType? SimulatedKeystrokeType { get; set; } + public bool BlockOriginalMouseInput { get; set; } +} + +public class DisabledMapping : ButtonMapping; + +public class NothingMapping : ButtonMapping; + +public class SimulatedKeystroke : ButtonMapping +{ + public SimulatedKeystroke() + { + BlockOriginalMouseInput = true; + } +} + +public class RightClick : ButtonMapping; diff --git a/YMouseButtonControl.DataAccess/Models/Profile.cs b/YMouseButtonControl.DataAccess/Models/Profile.cs new file mode 100644 index 0000000..c3c41df --- /dev/null +++ b/YMouseButtonControl.DataAccess/Models/Profile.cs @@ -0,0 +1,20 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace YMouseButtonControl.DataAccess.Models; + +public class Profile +{ + public int Id { get; set; } + public bool IsDefault { get; set; } + public bool Checked { get; set; } + public int DisplayPriority { get; set; } + public required string Name { get; set; } + public required string Description { get; set; } + public required string WindowCaption { get; set; } + public required string Process { get; set; } + public required string WindowClass { get; set; } + public required string ParentClass { get; set; } + public required string MatchType { get; set; } + + public virtual ICollection? ButtonMappings { get; set; } +} diff --git a/YMouseButtonControl.DataAccess/Models/Setting.cs b/YMouseButtonControl.DataAccess/Models/Setting.cs new file mode 100644 index 0000000..5674b90 --- /dev/null +++ b/YMouseButtonControl.DataAccess/Models/Setting.cs @@ -0,0 +1,17 @@ +namespace YMouseButtonControl.DataAccess.Models; + +public abstract class Setting +{ + public int Id { get; set; } + public required string Name { get; set; } +} + +public class SettingBool : Setting +{ + public bool Value { get; set; } +} + +public class SettingString : Setting +{ + public string? Value { get; set; } +} diff --git a/YMouseButtonControl.DataAccess/Models/SimulatedKeystrokeType.cs b/YMouseButtonControl.DataAccess/Models/SimulatedKeystrokeType.cs new file mode 100644 index 0000000..6d32881 --- /dev/null +++ b/YMouseButtonControl.DataAccess/Models/SimulatedKeystrokeType.cs @@ -0,0 +1,14 @@ +namespace YMouseButtonControl.DataAccess.Models; + +public enum SimulatedKeystrokeType +{ + AsMousePressedAndReleasedActionType, + DuringMouseActionType, + InAnotherThreadPressedActionType, + InAnotherThreadReleasedActionType, + MouseButtonPressedActionType, + MouseButtonReleasedActionType, + RepeatedlyWhileButtonDownActionType, + StickyHoldActionType, + StickyRepeatActionType, +} diff --git a/YMouseButtonControl.DataAccess/YMouseButtonControl.DataAccess.csproj b/YMouseButtonControl.DataAccess/YMouseButtonControl.DataAccess.csproj new file mode 100644 index 0000000..fc66022 --- /dev/null +++ b/YMouseButtonControl.DataAccess/YMouseButtonControl.DataAccess.csproj @@ -0,0 +1,23 @@ + + + + net8.0 + enable + enable + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/AsMouseButtonPressedService.cs b/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/AsMouseButtonPressedService.cs deleted file mode 100644 index 7aa897d..0000000 --- a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/AsMouseButtonPressedService.cs +++ /dev/null @@ -1,19 +0,0 @@ -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Enums; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; - -namespace YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations.SimulatedKeystrokesTypes; - -public class AsMouseButtonPressedService(IEventSimulatorService eventSimulatorService) - : IAsMouseButtonPressedService -{ - public void AsMouseButtonPressed(IButtonMapping mapping, MouseButtonState state) - { - if (state != MouseButtonState.Pressed) - { - return; - } - - eventSimulatorService.TapKeys(mapping.Keys); - } -} diff --git a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/AsMouseButtonReleasedService.cs b/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/AsMouseButtonReleasedService.cs deleted file mode 100644 index bd43364..0000000 --- a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/AsMouseButtonReleasedService.cs +++ /dev/null @@ -1,19 +0,0 @@ -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Enums; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; - -namespace YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations.SimulatedKeystrokesTypes; - -public class AsMouseButtonReleasedService(IEventSimulatorService eventSimulatorService) - : IAsMouseButtonReleasedService -{ - public void AsMouseButtonReleased(IButtonMapping mapping, MouseButtonState state) - { - if (state != MouseButtonState.Released) - { - return; - } - - eventSimulatorService.TapKeys(mapping.Keys); - } -} diff --git a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/StickyHoldService.cs b/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/StickyHoldService.cs deleted file mode 100644 index d56f335..0000000 --- a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedKeystrokesTypes/StickyHoldService.cs +++ /dev/null @@ -1,27 +0,0 @@ -using YMouseButtonControl.Core.DataAccess.Models.Interfaces; -using YMouseButtonControl.Core.KeyboardAndMouse.Enums; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; - -namespace YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations.SimulatedKeystrokesTypes; - -public class StickyHoldService(IEventSimulatorService eventSimulatorService) : IStickyHoldService -{ - public void StickyHold(IButtonMapping mapping, MouseButtonState state) - { - if (state != MouseButtonState.Pressed) - { - return; - } - - if (mapping.State) - { - eventSimulatorService.ReleaseKeys(mapping.Keys); - mapping.State = false; - } - else - { - eventSimulatorService.PressKeys(mapping.Keys); - mapping.State = true; - } - } -} diff --git a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedMousePressTypes/StickyHoldLeftClick.cs b/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedMousePressTypes/StickyHoldLeftClick.cs deleted file mode 100644 index 4583977..0000000 --- a/YMouseButtonControl.KeyboardAndMouse.SharpHook/Implementations/SimulatedMousePressTypes/StickyHoldLeftClick.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations.SimulatedMousePressTypes; - -public class StickyHoldLeftClick { } diff --git a/YMouseButtonControl.KeyboardAndMouse.SharpHook/YMouseButtonControl.KeyboardAndMouse.SharpHook.csproj b/YMouseButtonControl.KeyboardAndMouse.SharpHook/YMouseButtonControl.KeyboardAndMouse.SharpHook.csproj deleted file mode 100644 index 63df1e8..0000000 --- a/YMouseButtonControl.KeyboardAndMouse.SharpHook/YMouseButtonControl.KeyboardAndMouse.SharpHook.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - net8.0 - default - enable - - - - true - - - - true - - - - - - - - - - - - - diff --git a/YMouseButtonControl.Linux.Tests/StartupInstallerTests.cs b/YMouseButtonControl.Linux.Tests/StartupInstallerTests.cs index 1ada3e3..e7000ca 100644 --- a/YMouseButtonControl.Linux.Tests/StartupInstallerTests.cs +++ b/YMouseButtonControl.Linux.Tests/StartupInstallerTests.cs @@ -1,4 +1,4 @@ -using YMouseButtonControl.Services.Linux.Services; +using YMouseButtonControl.Linux.Services; namespace YMouseButtonControl.Linux.Tests; diff --git a/YMouseButtonControl.Linux.Tests/YMouseButtonControl.Linux.Tests.csproj b/YMouseButtonControl.Linux.Tests/YMouseButtonControl.Linux.Tests.csproj index 5a52c48..56ef86c 100644 --- a/YMouseButtonControl.Linux.Tests/YMouseButtonControl.Linux.Tests.csproj +++ b/YMouseButtonControl.Linux.Tests/YMouseButtonControl.Linux.Tests.csproj @@ -10,15 +10,21 @@ - - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - + diff --git a/YMouseButtonControl.Services.Windows/BackgroundTasksRunner.cs b/YMouseButtonControl.Linux/Services/BackgroundTasksRunner.cs similarity index 79% rename from YMouseButtonControl.Services.Windows/BackgroundTasksRunner.cs rename to YMouseButtonControl.Linux/Services/BackgroundTasksRunner.cs index 19f0d82..c905057 100644 --- a/YMouseButtonControl.Services.Windows/BackgroundTasksRunner.cs +++ b/YMouseButtonControl.Linux/Services/BackgroundTasksRunner.cs @@ -1,8 +1,8 @@ -using YMouseButtonControl.Core.KeyboardAndMouse; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; using YMouseButtonControl.Core.Services.BackgroundTasks; +using YMouseButtonControl.Core.Services.KeyboardAndMouse; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations; -namespace YMouseButtonControl.Services.Windows; +namespace YMouseButtonControl.Linux.Services; public class BackgroundTasksRunner : IBackgroundTasksRunner { @@ -16,14 +16,13 @@ KeyboardSimulatorWorker keyboardSimulatorWorker { _mouseListener = mouseListener; _keyboardSimulatorWorker = keyboardSimulatorWorker; - _mouseListener.Run(); _keyboardSimulatorWorker.Run(); } public void Dispose() { - _keyboardSimulatorWorker.Dispose(); _mouseListener.Dispose(); + _keyboardSimulatorWorker.Dispose(); } } diff --git a/YMouseButtonControl.Services.Linux/CurrentWindowService.cs b/YMouseButtonControl.Linux/Services/CurrentWindowService.cs similarity index 70% rename from YMouseButtonControl.Services.Linux/CurrentWindowService.cs rename to YMouseButtonControl.Linux/Services/CurrentWindowService.cs index 91bc739..821df4a 100644 --- a/YMouseButtonControl.Services.Linux/CurrentWindowService.cs +++ b/YMouseButtonControl.Linux/Services/CurrentWindowService.cs @@ -1,6 +1,6 @@ -using YMouseButtonControl.Core.Processes; +using YMouseButtonControl.Core.Services.Processes; -namespace YMouseButtonControl.Services.Linux; +namespace YMouseButtonControl.Linux.Services; public class CurrentWindowService : ICurrentWindowService { diff --git a/YMouseButtonControl.Services.Linux/ProcessMonitorService.cs b/YMouseButtonControl.Linux/Services/ProcessMonitorService.cs similarity index 67% rename from YMouseButtonControl.Services.Linux/ProcessMonitorService.cs rename to YMouseButtonControl.Linux/Services/ProcessMonitorService.cs index 1b593ff..1e2943d 100644 --- a/YMouseButtonControl.Services.Linux/ProcessMonitorService.cs +++ b/YMouseButtonControl.Linux/Services/ProcessMonitorService.cs @@ -1,8 +1,7 @@ using System.Diagnostics; -using YMouseButtonControl.Core.Processes; -using YMouseButtonControl.Core.Services.Abstractions.Models; +using YMouseButtonControl.Core.Services.Processes; -namespace YMouseButtonControl.Services.Linux; +namespace YMouseButtonControl.Linux.Services; public class ProcessMonitorService : IProcessMonitorService { diff --git a/YMouseButtonControl.Services.Linux/SkipProfileService.cs b/YMouseButtonControl.Linux/Services/SkipProfileService.cs similarity index 74% rename from YMouseButtonControl.Services.Linux/SkipProfileService.cs rename to YMouseButtonControl.Linux/Services/SkipProfileService.cs index 531d886..b87ccd3 100644 --- a/YMouseButtonControl.Services.Linux/SkipProfileService.cs +++ b/YMouseButtonControl.Linux/Services/SkipProfileService.cs @@ -1,17 +1,17 @@ using Serilog; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; -using YMouseButtonControl.Core.Processes; -using YMouseButtonControl.Core.Services.Abstractions.Models.EventArgs; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.EventArgs; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Interfaces; +using YMouseButtonControl.Core.Services.Processes; +using YMouseButtonControl.Core.ViewModels.Models; -namespace YMouseButtonControl.Services.Linux; +namespace YMouseButtonControl.Linux.Services; public class SkipProfileService(ICurrentWindowService currentWindowService) : ISkipProfileService { private readonly ILogger _myLog = Log.Logger.ForContext(); // Returns whether this profile should be skipped on mouse events - public bool ShouldSkipProfile(Profile p, NewMouseHookEventArgs e) + public bool ShouldSkipProfile(ProfileVm p, NewMouseHookEventArgs e) { // If the profile's checkbox is checked in the profiles list if (!p.Checked) diff --git a/YMouseButtonControl.Services.Linux/Services/StartupInstallerService.cs b/YMouseButtonControl.Linux/Services/StartupInstallerService.cs similarity index 93% rename from YMouseButtonControl.Services.Linux/Services/StartupInstallerService.cs rename to YMouseButtonControl.Linux/Services/StartupInstallerService.cs index f085323..87d6237 100644 --- a/YMouseButtonControl.Services.Linux/Services/StartupInstallerService.cs +++ b/YMouseButtonControl.Linux/Services/StartupInstallerService.cs @@ -1,7 +1,8 @@ using System.Reflection; using YMouseButtonControl.Core.Services; +using YMouseButtonControl.Core.Services.StartupInstaller; -namespace YMouseButtonControl.Services.Linux.Services; +namespace YMouseButtonControl.Linux.Services; public class StartupInstallerService : IStartupInstallerService { diff --git a/YMouseButtonControl.Services.Linux/YMouseButtonControl.Services.Linux.csproj b/YMouseButtonControl.Linux/YMouseButtonControl.Linux.csproj similarity index 100% rename from YMouseButtonControl.Services.Linux/YMouseButtonControl.Services.Linux.csproj rename to YMouseButtonControl.Linux/YMouseButtonControl.Linux.csproj diff --git a/YMouseButtonControl.Services.Linux/BackgroundTasksRunner.cs b/YMouseButtonControl.MacOS/Services/BackgroundTasksRunner.cs similarity index 79% rename from YMouseButtonControl.Services.Linux/BackgroundTasksRunner.cs rename to YMouseButtonControl.MacOS/Services/BackgroundTasksRunner.cs index 826744a..315fe8e 100644 --- a/YMouseButtonControl.Services.Linux/BackgroundTasksRunner.cs +++ b/YMouseButtonControl.MacOS/Services/BackgroundTasksRunner.cs @@ -1,8 +1,8 @@ -using YMouseButtonControl.Core.KeyboardAndMouse; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; using YMouseButtonControl.Core.Services.BackgroundTasks; +using YMouseButtonControl.Core.Services.KeyboardAndMouse; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations; -namespace YMouseButtonControl.Services.Linux; +namespace YMouseButtonControl.MacOS.Services; public class BackgroundTasksRunner : IBackgroundTasksRunner { diff --git a/YMouseButtonControl.Services.MacOS/CurrentWindowService.cs b/YMouseButtonControl.MacOS/Services/CurrentWindowService.cs similarity index 82% rename from YMouseButtonControl.Services.MacOS/CurrentWindowService.cs rename to YMouseButtonControl.MacOS/Services/CurrentWindowService.cs index 67be727..d0dfe8e 100644 --- a/YMouseButtonControl.Services.MacOS/CurrentWindowService.cs +++ b/YMouseButtonControl.MacOS/Services/CurrentWindowService.cs @@ -1,10 +1,10 @@ using System; using System.Runtime.InteropServices; using System.Text; -using YMouseButtonControl.Core.Processes; +using YMouseButtonControl.Core.Services.Processes; using CFIndex = long; -namespace YMouseButtonControl.Services.MacOS; +namespace YMouseButtonControl.MacOS.Services; // a lot of this code was copied from https://stackoverflow.com/a/44669560 and https://github.com/isnowrain/CoreFoundation/blob/master/Project/CFType.cs public class CurrentWindowService : ICurrentWindowService @@ -23,7 +23,7 @@ private string GetForegroundWindow() frontmostApplication, GetSelector("localizedName") ); - return GetStrFromCFString(localizedName); + return GetStrFromCfString(localizedName); } private const string AppKitFramework = "/System/Library/Frameworks/AppKit.framework/AppKit"; @@ -40,7 +40,7 @@ private string GetForegroundWindow() public static IntPtr GetSelector(string name) { - IntPtr cfstrSelector = CreateCFString(name); + IntPtr cfstrSelector = CreateCfString(name); IntPtr selector = NSSelectorFromString(cfstrSelector); CFRelease(cfstrSelector); return selector; @@ -50,16 +50,16 @@ public static IntPtr GetSelector(string name) static extern CFIndex CFStringGetLength(nint theString); [DllImport(CoreFoundation)] - static extern void CFStringGetCharacters(nint theString, CFRange range, nint buffer); + static extern void CFStringGetCharacters(nint theString, CfRange range, nint buffer); - private static unsafe string GetStrFromCFString(nint ptr) + private static unsafe string GetStrFromCfString(nint ptr) { var length = CFStringGetLength(ptr); var u = CFStringGetCharactersPtr(ptr); var buffer = IntPtr.Zero; if (u == IntPtr.Zero) { - var range = new CFRange(0, length); + var range = new CfRange(0, length); buffer = Marshal.AllocCoTaskMem((int)(length * 2)); CFStringGetCharacters(ptr, range, buffer); u = buffer; @@ -80,7 +80,7 @@ private static unsafe string GetStrFromCFString(nint ptr) [DllImport(AppKitFramework)] public static extern IntPtr NSSelectorFromString(IntPtr cfstr); - public static unsafe IntPtr CreateCFString(string aString) + public static unsafe IntPtr CreateCfString(string aString) { var bytes = Encoding.Unicode.GetBytes(aString); fixed (byte* b = bytes) @@ -89,7 +89,7 @@ public static unsafe IntPtr CreateCFString(string aString) IntPtr.Zero, (IntPtr)b, bytes.Length, - CFStringEncoding.UTF16, + CfStringEncoding.Utf16, false ); return cfStr; @@ -101,20 +101,20 @@ public static extern IntPtr CFStringCreateWithBytes( IntPtr allocator, IntPtr buffer, long bufferLength, - CFStringEncoding encoding, + CfStringEncoding encoding, bool isExternalRepresentation ); - public enum CFStringEncoding : uint + public enum CfStringEncoding : uint { - UTF16 = 0x0100, - UTF16BE = 0x10000100, - UTF16LE = 0x14000100, - ASCII = 0x0600, + Utf16 = 0x0100, + Utf16Be = 0x10000100, + Utf16Le = 0x14000100, + Ascii = 0x0600, } [StructLayout(LayoutKind.Sequential)] - struct CFRange(CFIndex length, CFIndex location) + struct CfRange(CFIndex length, CFIndex location) { public CFIndex Length = length; public CFIndex Location = location; diff --git a/YMouseButtonControl.Services.MacOS/MacOSProcessMonitorService.cs b/YMouseButtonControl.MacOS/Services/ProcessMonitorService.cs similarity index 58% rename from YMouseButtonControl.Services.MacOS/MacOSProcessMonitorService.cs rename to YMouseButtonControl.MacOS/Services/ProcessMonitorService.cs index 63bcecf..305a767 100644 --- a/YMouseButtonControl.Services.MacOS/MacOSProcessMonitorService.cs +++ b/YMouseButtonControl.MacOS/Services/ProcessMonitorService.cs @@ -1,12 +1,11 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using YMouseButtonControl.Core.Processes; -using YMouseButtonControl.Core.Services.Abstractions.Models; +using YMouseButtonControl.Core.Services.Processes; -namespace YMouseButtonControl.Services.MacOS; +namespace YMouseButtonControl.MacOS.Services; -public class MacOsProcessMonitorService : IProcessMonitorService +public class ProcessMonitorService : IProcessMonitorService { public IEnumerable GetProcesses() => Process diff --git a/YMouseButtonControl.Services.MacOS/SkipProfileService.cs b/YMouseButtonControl.MacOS/Services/SkipProfileService.cs similarity index 72% rename from YMouseButtonControl.Services.MacOS/SkipProfileService.cs rename to YMouseButtonControl.MacOS/Services/SkipProfileService.cs index f831d53..0edf7be 100644 --- a/YMouseButtonControl.Services.MacOS/SkipProfileService.cs +++ b/YMouseButtonControl.MacOS/Services/SkipProfileService.cs @@ -1,17 +1,17 @@ using Serilog; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; -using YMouseButtonControl.Core.Processes; -using YMouseButtonControl.Core.Services.Abstractions.Models.EventArgs; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.EventArgs; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Interfaces; +using YMouseButtonControl.Core.Services.Processes; +using YMouseButtonControl.Core.ViewModels.Models; -namespace YMouseButtonControl.Services.MacOS; +namespace YMouseButtonControl.MacOS.Services; public class SkipProfileService(ICurrentWindowService currentWindowService) : ISkipProfileService { private readonly ILogger _myLog = Log.Logger.ForContext(); // Returns whether this profile should be skipped on mouse events - public bool ShouldSkipProfile(Profile p, NewMouseHookEventArgs e) + public bool ShouldSkipProfile(ProfileVm p, NewMouseHookEventArgs e) { // If the profile's checkbox is checked in the profiles list if (!p.Checked) diff --git a/YMouseButtonControl.Services.MacOS/Services/StartupInstallerService.cs b/YMouseButtonControl.MacOS/Services/StartupInstallerService.cs similarity index 93% rename from YMouseButtonControl.Services.MacOS/Services/StartupInstallerService.cs rename to YMouseButtonControl.MacOS/Services/StartupInstallerService.cs index 9a3678f..51c8893 100644 --- a/YMouseButtonControl.Services.MacOS/Services/StartupInstallerService.cs +++ b/YMouseButtonControl.MacOS/Services/StartupInstallerService.cs @@ -1,9 +1,8 @@ using System; using System.IO; -using System.Reflection; -using YMouseButtonControl.Core.Services; +using YMouseButtonControl.Core.Services.StartupInstaller; -namespace YMouseButtonControl.Services.MacOS.Services; +namespace YMouseButtonControl.MacOS.Services; public class StartupInstallerService : IStartupInstallerService { diff --git a/YMouseButtonControl.Services.MacOS/YMouseButtonControl.Services.MacOS.csproj b/YMouseButtonControl.MacOS/YMouseButtonControl.MacOS.csproj similarity index 100% rename from YMouseButtonControl.Services.MacOS/YMouseButtonControl.Services.MacOS.csproj rename to YMouseButtonControl.MacOS/YMouseButtonControl.MacOS.csproj diff --git a/YMouseButtonControl.Windows.Tests/StartupInstallerTests.cs b/YMouseButtonControl.Windows.Tests/StartupInstallerTests.cs index eb1c778..857b77c 100644 --- a/YMouseButtonControl.Windows.Tests/StartupInstallerTests.cs +++ b/YMouseButtonControl.Windows.Tests/StartupInstallerTests.cs @@ -1,5 +1,6 @@ using System.Runtime.Versioning; -using YMouseButtonControl.Services.Windows.Services; +using YMouseButtonControl.Windows; +using YMouseButtonControl.Windows.Services; namespace YMouseButtonControl.Windows.Tests; diff --git a/YMouseButtonControl.Windows.Tests/YMouseButtonControl.Windows.Tests.csproj b/YMouseButtonControl.Windows.Tests/YMouseButtonControl.Windows.Tests.csproj index 8d292f4..4eb2aaa 100644 --- a/YMouseButtonControl.Windows.Tests/YMouseButtonControl.Windows.Tests.csproj +++ b/YMouseButtonControl.Windows.Tests/YMouseButtonControl.Windows.Tests.csproj @@ -10,11 +10,17 @@ - - - - - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + @@ -22,7 +28,7 @@ - + diff --git a/YMouseButtonControl.Services.Windows/NativeMethods.json b/YMouseButtonControl.Windows/NativeMethods.json similarity index 100% rename from YMouseButtonControl.Services.Windows/NativeMethods.json rename to YMouseButtonControl.Windows/NativeMethods.json diff --git a/YMouseButtonControl.Services.Windows/NativeMethods.txt b/YMouseButtonControl.Windows/NativeMethods.txt similarity index 100% rename from YMouseButtonControl.Services.Windows/NativeMethods.txt rename to YMouseButtonControl.Windows/NativeMethods.txt diff --git a/YMouseButtonControl.Services.MacOS/BackgroundTasksRunner.cs b/YMouseButtonControl.Windows/Services/BackgroundTasksRunner.cs similarity index 72% rename from YMouseButtonControl.Services.MacOS/BackgroundTasksRunner.cs rename to YMouseButtonControl.Windows/Services/BackgroundTasksRunner.cs index bddb0b3..335c4db 100644 --- a/YMouseButtonControl.Services.MacOS/BackgroundTasksRunner.cs +++ b/YMouseButtonControl.Windows/Services/BackgroundTasksRunner.cs @@ -1,8 +1,8 @@ -using YMouseButtonControl.Core.KeyboardAndMouse; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; -using YMouseButtonControl.Core.Services.BackgroundTasks; +using YMouseButtonControl.Core.Services.BackgroundTasks; +using YMouseButtonControl.Core.Services.KeyboardAndMouse; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations; -namespace YMouseButtonControl.Services.MacOS; +namespace YMouseButtonControl.Windows.Services; public class BackgroundTasksRunner : IBackgroundTasksRunner { @@ -16,13 +16,14 @@ KeyboardSimulatorWorker keyboardSimulatorWorker { _mouseListener = mouseListener; _keyboardSimulatorWorker = keyboardSimulatorWorker; + _mouseListener.Run(); _keyboardSimulatorWorker.Run(); } public void Dispose() { - _mouseListener.Dispose(); _keyboardSimulatorWorker.Dispose(); + _mouseListener.Dispose(); } } diff --git a/YMouseButtonControl.Services.Windows/CurrentWindowService.cs b/YMouseButtonControl.Windows/Services/CurrentWindowService.cs similarity index 94% rename from YMouseButtonControl.Services.Windows/CurrentWindowService.cs rename to YMouseButtonControl.Windows/Services/CurrentWindowService.cs index 1010492..9b3aafb 100644 --- a/YMouseButtonControl.Services.Windows/CurrentWindowService.cs +++ b/YMouseButtonControl.Windows/Services/CurrentWindowService.cs @@ -4,9 +4,9 @@ using Serilog; using Windows.Win32; using Windows.Win32.System.Threading; -using YMouseButtonControl.Core.Processes; +using YMouseButtonControl.Core.Services.Processes; -namespace YMouseButtonControl.Services.Windows; +namespace YMouseButtonControl.Windows.Services; [SupportedOSPlatform("windows5.1.2600")] public class CurrentWindowService : ICurrentWindowService diff --git a/YMouseButtonControl.Services.Windows/ProcessMonitorService.cs b/YMouseButtonControl.Windows/Services/ProcessMonitorService.cs similarity index 88% rename from YMouseButtonControl.Services.Windows/ProcessMonitorService.cs rename to YMouseButtonControl.Windows/Services/ProcessMonitorService.cs index 3bb465a..c2aba8f 100644 --- a/YMouseButtonControl.Services.Windows/ProcessMonitorService.cs +++ b/YMouseButtonControl.Windows/Services/ProcessMonitorService.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Concurrent; +using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; @@ -9,10 +8,9 @@ using System.Linq; using System.Runtime.Versioning; using System.Threading.Tasks; -using YMouseButtonControl.Core.Processes; -using YMouseButtonControl.Core.Services.Abstractions.Models; +using YMouseButtonControl.Core.Services.Processes; -namespace YMouseButtonControl.Services.Windows; +namespace YMouseButtonControl.Windows.Services; [SupportedOSPlatform("windows5.1.2600")] public class ProcessMonitorService : IProcessMonitorService diff --git a/YMouseButtonControl.Services.Windows/SkipProfileService.cs b/YMouseButtonControl.Windows/Services/SkipProfileService.cs similarity index 64% rename from YMouseButtonControl.Services.Windows/SkipProfileService.cs rename to YMouseButtonControl.Windows/Services/SkipProfileService.cs index b7c87eb..18f22f7 100644 --- a/YMouseButtonControl.Services.Windows/SkipProfileService.cs +++ b/YMouseButtonControl.Windows/Services/SkipProfileService.cs @@ -1,17 +1,17 @@ using System.Runtime.Versioning; using Serilog; -using YMouseButtonControl.Core.DataAccess.Models.Implementations; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; -using YMouseButtonControl.Core.Services.Abstractions.Models.EventArgs; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.EventArgs; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Interfaces; +using YMouseButtonControl.Core.ViewModels.Models; -namespace YMouseButtonControl.Services.Windows; +namespace YMouseButtonControl.Windows.Services; [SupportedOSPlatform("windows5.1.2600")] public class SkipProfileService : ISkipProfileService { private readonly ILogger _log = Log.Logger.ForContext(); - public bool ShouldSkipProfile(Profile p, NewMouseHookEventArgs e) + public bool ShouldSkipProfile(ProfileVm p, NewMouseHookEventArgs e) { // If the profile's checkbox is checked in the profiles list if (!p.Checked) diff --git a/YMouseButtonControl.Services.Windows/Services/StartupInstallerService.cs b/YMouseButtonControl.Windows/Services/StartupInstallerService.cs similarity index 94% rename from YMouseButtonControl.Services.Windows/Services/StartupInstallerService.cs rename to YMouseButtonControl.Windows/Services/StartupInstallerService.cs index d8e875a..b3d40bf 100644 --- a/YMouseButtonControl.Services.Windows/Services/StartupInstallerService.cs +++ b/YMouseButtonControl.Windows/Services/StartupInstallerService.cs @@ -3,9 +3,9 @@ using System.Runtime.Versioning; using System.Security.AccessControl; using Microsoft.Win32; -using YMouseButtonControl.Core.Services; +using YMouseButtonControl.Core.Services.StartupInstaller; -namespace YMouseButtonControl.Services.Windows.Services; +namespace YMouseButtonControl.Windows.Services; [SupportedOSPlatform("windows")] public class StartupInstallerService : IStartupInstallerService diff --git a/YMouseButtonControl.Services.Windows/YMouseButtonControl.Services.Windows.csproj b/YMouseButtonControl.Windows/YMouseButtonControl.Windows.csproj similarity index 98% rename from YMouseButtonControl.Services.Windows/YMouseButtonControl.Services.Windows.csproj rename to YMouseButtonControl.Windows/YMouseButtonControl.Windows.csproj index cd0cc8e..e44ead5 100644 --- a/YMouseButtonControl.Services.Windows/YMouseButtonControl.Services.Windows.csproj +++ b/YMouseButtonControl.Windows/YMouseButtonControl.Windows.csproj @@ -24,7 +24,7 @@ - + diff --git a/YMouseButtonControl.sln b/YMouseButtonControl.sln index d18a7b4..0f401ce 100644 --- a/YMouseButtonControl.sln +++ b/YMouseButtonControl.sln @@ -7,22 +7,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YMouseButtonControl", "YMou EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YMouseButtonControl.Core", "YMouseButtonControl.Core\YMouseButtonControl.Core.csproj", "{73FCD432-71C1-4993-8D2F-739E2C031188}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YMouseButtonControl.DataAccess.LiteDb", "YMouseButtonControl.DataAccess.LiteDb\YMouseButtonControl.DataAccess.LiteDb.csproj", "{6AAA8112-7911-4981-B9D0-A4CEE0597045}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YMouseButtonControl.Windows", "YMouseButtonControl.Windows\YMouseButtonControl.Windows.csproj", "{E9873196-0683-4609-9197-6CDF5FD6BCF1}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YMouseButtonControl.KeyboardAndMouse.SharpHook", "YMouseButtonControl.KeyboardAndMouse.SharpHook\YMouseButtonControl.KeyboardAndMouse.SharpHook.csproj", "{F4633549-C46B-4F65-B694-C879DE47B9BF}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YMouseButtonControl.Services.Windows", "YMouseButtonControl.Services.Windows\YMouseButtonControl.Services.Windows.csproj", "{E9873196-0683-4609-9197-6CDF5FD6BCF1}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YMouseButtonControl.Services.MacOS", "YMouseButtonControl.Services.MacOS\YMouseButtonControl.Services.MacOS.csproj", "{4FEFC613-E1F9-42E3-B375-5540BEE95D0C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YMouseButtonControl.MacOS", "YMouseButtonControl.MacOS\YMouseButtonControl.MacOS.csproj", "{4FEFC613-E1F9-42E3-B375-5540BEE95D0C}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YMouseButtonControl.Core.Tests", "YMouseButtonControl.Core.Tests\YMouseButtonControl.Core.Tests.csproj", "{3568CE4C-607E-4DB7-B724-CCA418B7D32A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YMouseButtonControl.Services.Linux", "YMouseButtonControl.Services.Linux\YMouseButtonControl.Services.Linux.csproj", "{EE958A9F-3768-44CE-A08E-F692CB403BB8}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YMouseButtonControl.Linux", "YMouseButtonControl.Linux\YMouseButtonControl.Linux.csproj", "{EE958A9F-3768-44CE-A08E-F692CB403BB8}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YMouseButtonControl.Windows.Tests", "YMouseButtonControl.Windows.Tests\YMouseButtonControl.Windows.Tests.csproj", "{1BDE4035-2584-48AC-A6CE-56136F589B52}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YMouseButtonControl.Linux.Tests", "YMouseButtonControl.Linux.Tests\YMouseButtonControl.Linux.Tests.csproj", "{41338DC0-4BB9-4776-A976-8F840015DAA3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YMouseButtonControl.DataAccess", "YMouseButtonControl.DataAccess\YMouseButtonControl.DataAccess.csproj", "{CB4F3910-E662-4554-8082-355328AABF05}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -37,14 +35,6 @@ Global {73FCD432-71C1-4993-8D2F-739E2C031188}.Debug|Any CPU.Build.0 = Debug|Any CPU {73FCD432-71C1-4993-8D2F-739E2C031188}.Release|Any CPU.ActiveCfg = Release|Any CPU {73FCD432-71C1-4993-8D2F-739E2C031188}.Release|Any CPU.Build.0 = Release|Any CPU - {6AAA8112-7911-4981-B9D0-A4CEE0597045}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6AAA8112-7911-4981-B9D0-A4CEE0597045}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6AAA8112-7911-4981-B9D0-A4CEE0597045}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6AAA8112-7911-4981-B9D0-A4CEE0597045}.Release|Any CPU.Build.0 = Release|Any CPU - {F4633549-C46B-4F65-B694-C879DE47B9BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F4633549-C46B-4F65-B694-C879DE47B9BF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F4633549-C46B-4F65-B694-C879DE47B9BF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F4633549-C46B-4F65-B694-C879DE47B9BF}.Release|Any CPU.Build.0 = Release|Any CPU {E9873196-0683-4609-9197-6CDF5FD6BCF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E9873196-0683-4609-9197-6CDF5FD6BCF1}.Debug|Any CPU.Build.0 = Debug|Any CPU {E9873196-0683-4609-9197-6CDF5FD6BCF1}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -69,6 +59,10 @@ Global {41338DC0-4BB9-4776-A976-8F840015DAA3}.Debug|Any CPU.Build.0 = Debug|Any CPU {41338DC0-4BB9-4776-A976-8F840015DAA3}.Release|Any CPU.ActiveCfg = Release|Any CPU {41338DC0-4BB9-4776-A976-8F840015DAA3}.Release|Any CPU.Build.0 = Release|Any CPU + {CB4F3910-E662-4554-8082-355328AABF05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CB4F3910-E662-4554-8082-355328AABF05}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB4F3910-E662-4554-8082-355328AABF05}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CB4F3910-E662-4554-8082-355328AABF05}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/YMouseButtonControl/App.axaml b/YMouseButtonControl/App.axaml index 3a3a2f5..c2f2905 100644 --- a/YMouseButtonControl/App.axaml +++ b/YMouseButtonControl/App.axaml @@ -1,6 +1,6 @@ @@ -9,7 +9,7 @@ - + diff --git a/YMouseButtonControl/App.axaml.cs b/YMouseButtonControl/App.axaml.cs index 3c63f06..b667fba 100644 --- a/YMouseButtonControl/App.axaml.cs +++ b/YMouseButtonControl/App.axaml.cs @@ -4,21 +4,21 @@ using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using ReactiveUI; using Splat; using Splat.Microsoft.Extensions.DependencyInjection; -using YMouseButtonControl.Configuration; -using YMouseButtonControl.Core; -using YMouseButtonControl.Core.Profiles.Implementations; -using YMouseButtonControl.Core.Profiles.Interfaces; +using YMouseButtonControl.Core.Mappings; using YMouseButtonControl.Core.Services.BackgroundTasks; -using YMouseButtonControl.Core.ViewModels.Interfaces; +using YMouseButtonControl.Core.Services.Settings; +using YMouseButtonControl.Core.ViewModels.AppViewModel; using YMouseButtonControl.Core.ViewModels.MainWindow; using YMouseButtonControl.Core.Views; +using YMouseButtonControl.DataAccess.Context; using YMouseButtonControl.DependencyInjection; -using YMouseButtonControl.Views; namespace YMouseButtonControl; @@ -34,16 +34,28 @@ public override void Initialize() private void Init() { - var dataAccessConfig = new DataAccessConfiguration { UseInMemoryDatabase = false }; + var configuration = new ConfigurationBuilder() + .SetBasePath(AppContext.BaseDirectory) + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) + .Build(); var host = Host.CreateDefaultBuilder() .ConfigureServices(services => { services.UseMicrosoftDependencyResolver(); + services.AddDbContext(o => + { + o.UseSqlite( + configuration.GetConnectionString("YMouseButtonControlContext"), + sqliteOptionsAction: so => + so.MigrationsAssembly("YMouseButtonControl.DataAccess") + ); + }); var resolver = Locator.CurrentMutable; resolver.InitializeSplat(); resolver.InitializeReactiveUI(); - Bootstrapper.Register(services, dataAccessConfig); + services.AddAutoMapper(typeof(MappingProfile)); + Bootstrapper.Register(services); services.AddSingleton< IActivationForViewFetcher, @@ -54,6 +66,10 @@ private void Init() .Build(); Container = host.Services; Container.UseMicrosoftDependencyResolver(); +#if (!DEBUG) + // ensure db is created + Container.GetRequiredService().Database.Migrate(); +#endif RxApp.MainThreadScheduler = AvaloniaScheduler.Instance; } @@ -66,13 +82,12 @@ public override void OnFrameworkInitializationCompleted() Container?.GetRequiredService() ?? throw new Exception($"Error retrieving {nameof(ISettingsService)}"); var startMinimized = - settingsService.GetSetting("StartMinimized") + settingsService.GetBoolSetting("StartMinimized") ?? throw new Exception($"Error retrieving setting StartMinimized"); - var startMinimizedValue = bool.Parse(startMinimized.Value ?? "false"); if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - if (!startMinimizedValue) + if (!startMinimized.Value) { var mainWindow = (Window)Container.GetRequiredService(); mainWindow.DataContext = Container.GetRequiredService(); diff --git a/YMouseButtonControl/Converters/SettingValueConverter.cs b/YMouseButtonControl/Converters/SettingValueConverter.cs deleted file mode 100644 index 086bea7..0000000 --- a/YMouseButtonControl/Converters/SettingValueConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -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/Bootstrapper.cs b/YMouseButtonControl/DependencyInjection/Bootstrapper.cs index 13b46b7..df657eb 100644 --- a/YMouseButtonControl/DependencyInjection/Bootstrapper.cs +++ b/YMouseButtonControl/DependencyInjection/Bootstrapper.cs @@ -1,17 +1,12 @@ using Microsoft.Extensions.DependencyInjection; -using YMouseButtonControl.Configuration; namespace YMouseButtonControl.DependencyInjection; public static class Bootstrapper { - public static void Register( - IServiceCollection services, - DataAccessConfiguration dataAccessConfig - ) + public static void Register(IServiceCollection services) { ServicesBootstrapper.RegisterServices(services); - ConfigurationBootstrapper.RegisterConfiguration(services, dataAccessConfig); DataAccessBootstrapper.RegisterDataAccess(services); KeyboardAndMouseBootstrapper.RegisterKeyboardAndMouse(services); FeaturesBootstrapper.RegisterFeatures(services); diff --git a/YMouseButtonControl/DependencyInjection/ConfigurationBootstrapper.cs b/YMouseButtonControl/DependencyInjection/ConfigurationBootstrapper.cs deleted file mode 100644 index 46931c6..0000000 --- a/YMouseButtonControl/DependencyInjection/ConfigurationBootstrapper.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.IO; -using System.Reflection; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using YMouseButtonControl.Configuration; -using YMouseButtonControl.Core.DataAccess.Configuration; - -namespace YMouseButtonControl.DependencyInjection; - -public static class ConfigurationBootstrapper -{ - public static void RegisterConfiguration( - IServiceCollection services, - DataAccessConfiguration dataAccessConfig - ) - { - var configuration = BuildConfiguration(); - - RegisterDatabaseConfiguration(services, configuration, dataAccessConfig); - } - - private static IConfiguration BuildConfiguration() => - new ConfigurationBuilder().AddJsonFile("appsettings.json").Build(); - - private static void RegisterDatabaseConfiguration( - IServiceCollection services, - IConfiguration configuration, - DataAccessConfiguration dataAccessConfig - ) - { - services.AddTransient(_ => new DatabaseConfiguration - { - ConnectionString = GetDatabaseConnectionString(configuration), - UseInMemoryDatabase = dataAccessConfig.UseInMemoryDatabase, - }); - } - - private static string GetDatabaseConnectionString(IConfiguration configuration) - { - var databaseName = - configuration["DataAccess:DatabaseName"] ?? throw new Exception("DatabaseName empty"); - var connectionString = - configuration["DataAccess:ConnectionString"] ?? throw new Exception("Connection empty"); - - var dbDirectory = - Path.GetDirectoryName(AppContext.BaseDirectory) - ?? throw new InvalidOperationException(); - if (!Directory.Exists(dbDirectory)) - { - Directory.CreateDirectory(dbDirectory); - } - - return string.Format(connectionString, Path.Combine(dbDirectory, databaseName)); - } -} diff --git a/YMouseButtonControl/DependencyInjection/DataAccessBootstrapper.cs b/YMouseButtonControl/DependencyInjection/DataAccessBootstrapper.cs index 1086b8c..431c8d1 100644 --- a/YMouseButtonControl/DependencyInjection/DataAccessBootstrapper.cs +++ b/YMouseButtonControl/DependencyInjection/DataAccessBootstrapper.cs @@ -1,6 +1,6 @@ using Microsoft.Extensions.DependencyInjection; -using YMouseButtonControl.Core.DataAccess.UnitOfWork; -using YMouseButtonControl.DataAccess.LiteDb; +using YMouseButtonControl.Core.Repositories; +using IUnitOfWork = YMouseButtonControl.Core.Repositories.IUnitOfWork; namespace YMouseButtonControl.DependencyInjection; @@ -8,6 +8,8 @@ public static class DataAccessBootstrapper { public static void RegisterDataAccess(IServiceCollection services) { - services.AddSingleton(); + services + .AddScoped(typeof(IGenericRepository<,>), typeof(GenericRepository<,>)) + .AddScoped(); } } diff --git a/YMouseButtonControl/DependencyInjection/FeaturesBootstrapper.cs b/YMouseButtonControl/DependencyInjection/FeaturesBootstrapper.cs index 0af54fc..1d85be5 100644 --- a/YMouseButtonControl/DependencyInjection/FeaturesBootstrapper.cs +++ b/YMouseButtonControl/DependencyInjection/FeaturesBootstrapper.cs @@ -8,7 +8,6 @@ public static class FeaturesBootstrapper { public static void RegisterFeatures(IServiceCollection services) { - services.AddTransient(); - services.AddTransient(); + services.AddTransient().AddTransient(); } } diff --git a/YMouseButtonControl/DependencyInjection/KeyboardAndMouseBootstrapper.cs b/YMouseButtonControl/DependencyInjection/KeyboardAndMouseBootstrapper.cs index 719e491..20e818d 100644 --- a/YMouseButtonControl/DependencyInjection/KeyboardAndMouseBootstrapper.cs +++ b/YMouseButtonControl/DependencyInjection/KeyboardAndMouseBootstrapper.cs @@ -2,11 +2,12 @@ using Microsoft.Extensions.DependencyInjection; using SharpHook; using SharpHook.Reactive; -using YMouseButtonControl.Core.KeyboardAndMouse; -using YMouseButtonControl.Core.KeyboardAndMouse.Interfaces; -using YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations; -using YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations.SimulatedKeystrokesTypes; -using YMouseButtonControl.KeyboardAndMouse.SharpHook.Implementations.SimulatedMousePressTypes; +using YMouseButtonControl.Core.Services.KeyboardAndMouse; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations.SimulatedKeystrokesTypes; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Implementations.SimulatedMousePressTypes; +using YMouseButtonControl.Core.Services.KeyboardAndMouse.Interfaces; +using YMouseButtonControl.Linux.Services; namespace YMouseButtonControl.DependencyInjection; @@ -22,15 +23,15 @@ private static void RegisterOsSpecificKeyboardAndMouseServices(IServiceCollectio { if (OperatingSystem.IsWindowsVersionAtLeast(5, 1, 2600)) { - services.AddSingleton(); + services.AddScoped(); } else if (OperatingSystem.IsMacOS()) { - services.AddSingleton(); + services.AddScoped(); } else if (OperatingSystem.IsLinux()) { - services.AddSingleton(); + services.AddScoped(); } else { @@ -40,20 +41,18 @@ private static void RegisterOsSpecificKeyboardAndMouseServices(IServiceCollectio private static void RegisterCommonKeyboardAndMouseServices(IServiceCollection services) { - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton< - IDuringMousePressAndReleaseService, - DuringMousePressAndReleaseService - >(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + services + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped(); } } diff --git a/YMouseButtonControl/DependencyInjection/ServicesBootstrapper.cs b/YMouseButtonControl/DependencyInjection/ServicesBootstrapper.cs index db70f6f..e703c89 100644 --- a/YMouseButtonControl/DependencyInjection/ServicesBootstrapper.cs +++ b/YMouseButtonControl/DependencyInjection/ServicesBootstrapper.cs @@ -1,13 +1,11 @@ using System; using System.Runtime.Versioning; using Microsoft.Extensions.DependencyInjection; -using YMouseButtonControl.Core.Processes; -using YMouseButtonControl.Core.Profiles.Implementations; -using YMouseButtonControl.Core.Profiles.Interfaces; -using YMouseButtonControl.Core.Services; using YMouseButtonControl.Core.Services.BackgroundTasks; -using YMouseButtonControl.Services.MacOS; -using YMouseButtonControl.Services.Windows; +using YMouseButtonControl.Core.Services.Processes; +using YMouseButtonControl.Core.Services.Profiles; +using YMouseButtonControl.Core.Services.Settings; +using YMouseButtonControl.Core.Services.StartupInstaller; namespace YMouseButtonControl.DependencyInjection; @@ -21,8 +19,9 @@ public static void RegisterServices(IServiceCollection services) private static void RegisterCommonServices(IServiceCollection services) { - services.AddSingleton(); - services.AddSingleton(); + services + .AddScoped() + .AddScoped(); } private static void RegisterPlatformSpecificServices(IServiceCollection services) @@ -47,35 +46,29 @@ private static void RegisterPlatformSpecificServices(IServiceCollection services private static void RegisterLinuxServices(IServiceCollection services) { - services.AddSingleton< - IStartupInstallerService, - Services.Linux.Services.StartupInstallerService - >(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + services + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped(); } [SupportedOSPlatform("windows5.1.2600")] private static void RegisterWindowsServices(IServiceCollection services) { - services.AddSingleton< - IStartupInstallerService, - Services.Windows.Services.StartupInstallerService - >(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + services + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped(); } private static void RegisterMacOsServices(IServiceCollection services) { - services.AddSingleton< - IStartupInstallerService, - Services.MacOS.Services.StartupInstallerService - >(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + services + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped(); } } diff --git a/YMouseButtonControl/DependencyInjection/ViewBootstrapper.cs b/YMouseButtonControl/DependencyInjection/ViewBootstrapper.cs index 71d1a70..725b314 100644 --- a/YMouseButtonControl/DependencyInjection/ViewBootstrapper.cs +++ b/YMouseButtonControl/DependencyInjection/ViewBootstrapper.cs @@ -8,7 +8,6 @@ public static class ViewBootstrapper { public static void RegisterViews(IServiceCollection services) { - services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton().AddSingleton(); } } diff --git a/YMouseButtonControl/DependencyInjection/ViewModelsBootstrapper.cs b/YMouseButtonControl/DependencyInjection/ViewModelsBootstrapper.cs index 65c436c..99346c4 100644 --- a/YMouseButtonControl/DependencyInjection/ViewModelsBootstrapper.cs +++ b/YMouseButtonControl/DependencyInjection/ViewModelsBootstrapper.cs @@ -1,11 +1,9 @@ using Microsoft.Extensions.DependencyInjection; -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.AppViewModel; +using YMouseButtonControl.Core.ViewModels.LayerViewModel; using YMouseButtonControl.Core.ViewModels.MainWindow; +using YMouseButtonControl.Core.ViewModels.ProfilesInformationViewModel; using YMouseButtonControl.Core.ViewModels.ProfilesList; -using YMouseButtonControl.Core.ViewModels.Services; namespace YMouseButtonControl.DependencyInjection; @@ -18,16 +16,17 @@ public static void RegisterViewModels(IServiceCollection services) private static void RegisterCommonViewModels(IServiceCollection services) { - services.AddTransient(); - services.AddTransient(); - services.AddSingleton(); - services.AddSingleton< - IShowSimulatedKeystrokesDialogService, - ShowSimulatedKeystrokesDialogService - >(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + services + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped< + IShowSimulatedKeystrokesDialogService, + ShowSimulatedKeystrokesDialogService + >() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped(); } } diff --git a/YMouseButtonControl/Views/Dialogs/GlobalSettingsDialog.axaml b/YMouseButtonControl/Views/Dialogs/GlobalSettingsDialog.axaml index f8e893c..76e1252 100644 --- a/YMouseButtonControl/Views/Dialogs/GlobalSettingsDialog.axaml +++ b/YMouseButtonControl/Views/Dialogs/GlobalSettingsDialog.axaml @@ -2,8 +2,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 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" + xmlns:mainWindow="clr-namespace:YMouseButtonControl.Core.ViewModels.MainWindow;assembly=YMouseButtonControl.Core" WindowStartupLocation="CenterOwner" Width="800" Height="600" @@ -11,16 +10,12 @@ x:Class="YMouseButtonControl.Views.Dialogs.GlobalSettingsDialog" Title="Global Settings"> - + - - - - + IsChecked="{Binding StartMinimized.Value}" /> diff --git a/YMouseButtonControl/Views/Dialogs/ProcessSelectorDialog.axaml b/YMouseButtonControl/Views/Dialogs/ProcessSelectorDialog.axaml index 8f46537..1862316 100644 --- a/YMouseButtonControl/Views/Dialogs/ProcessSelectorDialog.axaml +++ b/YMouseButtonControl/Views/Dialogs/ProcessSelectorDialog.axaml @@ -3,7 +3,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:converters="clr-namespace:YMouseButtonControl.Converters" - xmlns:dialogs="clr-namespace:YMouseButtonControl.Core.ViewModels.Implementations.Dialogs;assembly=YMouseButtonControl.Core" + xmlns:profilesList="clr-namespace:YMouseButtonControl.Core.ViewModels.ProfilesList;assembly=YMouseButtonControl.Core" mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="600" @@ -15,7 +15,7 @@ Title="Choose Application"> - + diff --git a/YMouseButtonControl/Views/Dialogs/ProcessSelectorDialog.axaml.cs b/YMouseButtonControl/Views/Dialogs/ProcessSelectorDialog.axaml.cs index cc790ef..2f2150f 100644 --- a/YMouseButtonControl/Views/Dialogs/ProcessSelectorDialog.axaml.cs +++ b/YMouseButtonControl/Views/Dialogs/ProcessSelectorDialog.axaml.cs @@ -4,7 +4,7 @@ using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; using ReactiveUI; -using YMouseButtonControl.Core.ViewModels.Implementations.Dialogs; +using YMouseButtonControl.Core.ViewModels.ProfilesList; namespace YMouseButtonControl.Views.Dialogs; diff --git a/YMouseButtonControl/Views/Dialogs/SimulatedKeystrokesDialog.axaml b/YMouseButtonControl/Views/Dialogs/SimulatedKeystrokesDialog.axaml index 23086e8..20a1d82 100644 --- a/YMouseButtonControl/Views/Dialogs/SimulatedKeystrokesDialog.axaml +++ b/YMouseButtonControl/Views/Dialogs/SimulatedKeystrokesDialog.axaml @@ -3,7 +3,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:converters="clr-namespace:YMouseButtonControl.Converters" - xmlns:dialogs="clr-namespace:YMouseButtonControl.Core.ViewModels.Implementations.Dialogs;assembly=YMouseButtonControl.Core" + xmlns:layerViewModel="clr-namespace:YMouseButtonControl.Core.ViewModels.LayerViewModel;assembly=YMouseButtonControl.Core" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" WindowStartupLocation="CenterOwner" Width="800" @@ -11,7 +11,7 @@ x:Class="YMouseButtonControl.Views.Dialogs.SimulatedKeystrokesDialog" Title="{Binding Title}"> - + diff --git a/YMouseButtonControl/Views/Dialogs/SimulatedKeystrokesDialog.axaml.cs b/YMouseButtonControl/Views/Dialogs/SimulatedKeystrokesDialog.axaml.cs index 03c497f..892d877 100644 --- a/YMouseButtonControl/Views/Dialogs/SimulatedKeystrokesDialog.axaml.cs +++ b/YMouseButtonControl/Views/Dialogs/SimulatedKeystrokesDialog.axaml.cs @@ -5,7 +5,7 @@ using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; using ReactiveUI; -using YMouseButtonControl.Core.ViewModels.Implementations.Dialogs; +using YMouseButtonControl.Core.ViewModels.LayerViewModel; namespace YMouseButtonControl.Views.Dialogs; diff --git a/YMouseButtonControl/Views/LayerView.axaml b/YMouseButtonControl/Views/LayerView.axaml index 2e49845..a9ddf5e 100644 --- a/YMouseButtonControl/Views/LayerView.axaml +++ b/YMouseButtonControl/Views/LayerView.axaml @@ -2,14 +2,14 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:implementations="clr-namespace:YMouseButtonControl.Core.ViewModels.Implementations;assembly=YMouseButtonControl.Core" + xmlns:layerViewModel="clr-namespace:YMouseButtonControl.Core.ViewModels.LayerViewModel;assembly=YMouseButtonControl.Core" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="YMouseButtonControl.Views.LayerView"> - + diff --git a/YMouseButtonControl/Views/LayerView.axaml.cs b/YMouseButtonControl/Views/LayerView.axaml.cs index 7c49876..a68bef8 100644 --- a/YMouseButtonControl/Views/LayerView.axaml.cs +++ b/YMouseButtonControl/Views/LayerView.axaml.cs @@ -1,8 +1,7 @@ using System.Threading.Tasks; using Avalonia.ReactiveUI; using ReactiveUI; -using YMouseButtonControl.Core.ViewModels.Implementations; -using YMouseButtonControl.Core.ViewModels.Implementations.Dialogs; +using YMouseButtonControl.Core.ViewModels.LayerViewModel; using YMouseButtonControl.Core.ViewModels.Models; using YMouseButtonControl.Views.Dialogs; @@ -29,15 +28,12 @@ public LayerView() } private static async Task ShowSimulateKeystrokesPicker( - IInteractionContext< - SimulatedKeystrokesDialogViewModel?, - SimulatedKeystrokesDialogModel? - > context + IInteractionContext context ) { var dialog = new SimulatedKeystrokesDialog { DataContext = context.Input }; - var result = await dialog.ShowDialog( + var result = await dialog.ShowDialog( MainWindowProvider.GetMainWindow() ); context.SetOutput(result); diff --git a/YMouseButtonControl/Views/MainWindow.axaml b/YMouseButtonControl/Views/MainWindow.axaml index 6983e18..b405cad 100644 --- a/YMouseButtonControl/Views/MainWindow.axaml +++ b/YMouseButtonControl/Views/MainWindow.axaml @@ -3,7 +3,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:views="clr-namespace:YMouseButtonControl.Views" - xmlns:implementations="clr-namespace:YMouseButtonControl.Core.ViewModels.Implementations;assembly=YMouseButtonControl.Core" xmlns:mainWindow="clr-namespace:YMouseButtonControl.Core.ViewModels.MainWindow;assembly=YMouseButtonControl.Core" mc:Ignorable="d" d:DesignWidth="800" @@ -40,7 +39,7 @@ - +