From ec490155fd8786527dfbba7d9af53041b791fb6d Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Sat, 18 Mar 2017 23:36:51 +0100 Subject: [PATCH] Disabled The Division module (broken) Disabled LightFX module (unfinished) Added keybind event triggers Fixed condition dropdown width Adjusted layer properties window height Improved GTA V DLL placement --- Artemis/Artemis/App.xaml.cs | 4 +- Artemis/Artemis/Artemis.csproj | 2 +- Artemis/Artemis/ArtemisBootstrapper.cs | 5 +- Artemis/Artemis/DAL/ProfileProvider.cs | 3 +- .../Logitech/LogitechKeyboard.cs | 16 +- Artemis/Artemis/Managers/KeybindManager.cs | 19 +- .../Artemis/Modules/Games/GtaV/GtaVModel.cs | 7 +- .../Modules/Games/LightFx/LightFxModel.cs | 110 +++---- .../Modules/Games/LightFx/LightFxViewModel.cs | 34 +-- .../Games/TheDivision/TheDivisionModel.cs | 281 +++++++++--------- .../Games/TheDivision/TheDivisionViewModel.cs | 34 +-- .../Layers/Animations/PulseAnimation.cs | 45 ++- .../Layers/Conditions/EventCondition.cs | 14 +- .../Layers/Models/EventPropertiesModel.cs | 60 ++-- .../Models/KeyboardEventPropertiesModel.cs | 12 +- .../Layers/Models/LayerKeybindModel.cs | 86 ++++-- .../Layers/Types/KeyPress/KeyPressType.cs | 3 +- .../Profiles/Lua/Modules/LuaEventsModule.cs | 6 +- .../Utilities/DataReaders/DllManager.cs | 88 +----- .../KeyboardHook.cs => InputHook.cs} | 4 +- .../Profiles/LayerKeybindViewModel.cs | 73 +++-- Artemis/Artemis/Views/LayerEditorView.xaml | 4 +- .../Views/Profiles/LayerKeybindView.xaml | 2 +- 23 files changed, 475 insertions(+), 437 deletions(-) rename Artemis/Artemis/Utilities/{Keyboard/KeyboardHook.cs => InputHook.cs} (94%) diff --git a/Artemis/Artemis/App.xaml.cs b/Artemis/Artemis/App.xaml.cs index 609a451b9..f7f13e188 100644 --- a/Artemis/Artemis/App.xaml.cs +++ b/Artemis/Artemis/App.xaml.cs @@ -1,7 +1,7 @@ using System; using System.Windows; using System.Windows.Threading; -using Artemis.Utilities.Keyboard; +using Artemis.Utilities; using NLog; using WpfExceptionViewer; @@ -28,7 +28,7 @@ namespace Artemis private void Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) { // Get rid of the keyboard hook in case of a crash, otherwise input freezes up system wide until Artemis is gone - KeyboardHook.Stop(); + InputHook.Stop(); if (DoHandle) { diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index d7ddc8851..5d58be4ea 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -663,7 +663,7 @@ - + diff --git a/Artemis/Artemis/ArtemisBootstrapper.cs b/Artemis/Artemis/ArtemisBootstrapper.cs index 6cfb075d6..cc6fd3565 100644 --- a/Artemis/Artemis/ArtemisBootstrapper.cs +++ b/Artemis/Artemis/ArtemisBootstrapper.cs @@ -12,7 +12,6 @@ using Artemis.Settings; using Artemis.Utilities; using Artemis.Utilities.Converters; using Artemis.Utilities.DataReaders; -using Artemis.Utilities.Keyboard; using Artemis.ViewModels; using Caliburn.Micro; using Newtonsoft.Json; @@ -35,7 +34,7 @@ namespace Artemis Initialize(); BindSpecialValues(); - KeyboardHook.Start(); + InputHook.Start(); AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException; } @@ -43,7 +42,7 @@ namespace Artemis private void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs) { // Get rid of the keyboard hook in case of a crash, otherwise input freezes up system wide until Artemis is gone - KeyboardHook.Stop(); + InputHook.Stop(); } private void BindSpecialValues() diff --git a/Artemis/Artemis/DAL/ProfileProvider.cs b/Artemis/Artemis/DAL/ProfileProvider.cs index b1fc66710..356c53ec0 100644 --- a/Artemis/Artemis/DAL/ProfileProvider.cs +++ b/Artemis/Artemis/DAL/ProfileProvider.cs @@ -21,8 +21,7 @@ namespace Artemis.DAL { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - public static readonly string ProfileFolder = - Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Artemis\profiles"; + public static readonly string ProfileFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Artemis\profiles"; private static bool _installedDefaults; diff --git a/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs b/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs index d31ec3ee0..d7eaa7bfc 100644 --- a/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs +++ b/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs @@ -10,6 +10,9 @@ namespace Artemis.DeviceProviders.Logitech { public override bool CanEnable() { + // Just to be sure, restore the Logitech DLL registry key + DllManager.RestoreLogitechDll(); + // Check to see if VC++ 2012 x64 is installed. if (Registry.LocalMachine.OpenSubKey( @"SOFTWARE\Classes\Installer\Dependencies\{ca67548a-5ebe-413a-b50c-4b9ceb6d66c6}") == null) @@ -22,17 +25,6 @@ namespace Artemis.DeviceProviders.Logitech return false; } - if (DllManager.DllPlaced()) - { - CantEnableText = - "Artemis couldn't enable your Logitech keyboard, because the required files are not in place.\n\n" + - "This happens when you run The Division or GTA and shut down Artemis before shutting down The Division\n" + - "Artemis tries to fix this automatically on startup but because the files may have been in use it failed.\n\n" + - "To try again, restart Artemis or check out the FAQ."; - - return false; - } - int majorNum = 0, minorNum = 0, buildNum = 0; LogitechGSDK.LogiLedInit(); @@ -73,4 +65,4 @@ namespace Artemis.DeviceProviders.Logitech LogitechGSDK.LogiLedSetLightingFromBitmap(OrionUtilities.BitmapToByteArray(bitmap)); } } -} \ No newline at end of file +} diff --git a/Artemis/Artemis/Managers/KeybindManager.cs b/Artemis/Artemis/Managers/KeybindManager.cs index ff4e8a6ba..406cd63e9 100644 --- a/Artemis/Artemis/Managers/KeybindManager.cs +++ b/Artemis/Artemis/Managers/KeybindManager.cs @@ -1,10 +1,9 @@ using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Windows.Forms; using System.Windows.Input; using Artemis.Models; -using Artemis.Utilities.Keyboard; +using Artemis.Utilities; using MahApps.Metro.Controls; using KeyEventArgs = System.Windows.Forms.KeyEventArgs; using MouseEventArgs = System.Windows.Forms.MouseEventArgs; @@ -17,12 +16,12 @@ namespace Artemis.Managers static KeybindManager() { - KeyboardHook.KeyDownCallback += args => ProcessKey(args, PressType.Down); - KeyboardHook.KeyUpCallback += args => ProcessKey(args, PressType.Up); - KeyboardHook.MouseDownCallback += args => ProcessMouse(args, PressType.Down); - KeyboardHook.MouseUpCallback += args => ProcessMouse(args, PressType.Up); + InputHook.KeyDownCallback += args => ProcessKey(args, PressType.Down); + InputHook.KeyUpCallback += args => ProcessKey(args, PressType.Up); + InputHook.MouseDownCallback += args => ProcessMouse(args, PressType.Down); + InputHook.MouseUpCallback += args => ProcessMouse(args, PressType.Up); } - + private static void ProcessKey(KeyEventArgs keyEventArgs, PressType pressType) { // Don't trigger if the key itself is a modifier @@ -38,7 +37,7 @@ namespace Artemis.Managers var hotKey = new HotKey(KeyInterop.KeyFromVirtualKey(keyEventArgs.KeyValue), modifiers); foreach (var keybindModel in KeybindModels) - keybindModel.InvokeIfMatched(hotKey, pressType); + keybindModel.InvokeIfMatched(hotKey, pressType); } private static void ProcessMouse(MouseEventArgs mouseEventArgs, PressType pressType) @@ -79,15 +78,19 @@ namespace Artemis.Managers if (alt) modifiers = ModifierKeys.Alt; if (control) + { if (modifiers == ModifierKeys.None) modifiers = ModifierKeys.Control; else modifiers |= ModifierKeys.Control; + } if (shift) + { if (modifiers == ModifierKeys.None) modifiers = ModifierKeys.Shift; else modifiers |= ModifierKeys.Shift; + } return modifiers; } diff --git a/Artemis/Artemis/Modules/Games/GtaV/GtaVModel.cs b/Artemis/Artemis/Modules/Games/GtaV/GtaVModel.cs index c41f54b4f..38f854a65 100644 --- a/Artemis/Artemis/Modules/Games/GtaV/GtaVModel.cs +++ b/Artemis/Artemis/Modules/Games/GtaV/GtaVModel.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System.Linq; +using System.Threading; using System.Threading.Tasks; using System.Windows.Media; using Artemis.DAL; @@ -13,8 +14,7 @@ namespace Artemis.Modules.Games.GtaV { private readonly PipeServer _pipeServer; - public GtaVModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer) - : base(deviceManager, luaManager) + public GtaVModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer) : base(deviceManager, luaManager) { _pipeServer = pipeServer; @@ -29,6 +29,7 @@ namespace Artemis.Modules.Games.GtaV public override void Enable() { + var process = System.Diagnostics.Process.GetProcessesByName("GTA5").First(); DllManager.PlaceLogitechDll(); _pipeServer.PipeMessage += PipeServerOnPipeMessage; base.Enable(); diff --git a/Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs b/Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs index 0ed11700f..db460523e 100644 --- a/Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs +++ b/Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs @@ -1,55 +1,55 @@ -using System; -using System.IO; -using Artemis.DAL; -using Artemis.Managers; -using Artemis.Modules.Abstract; -using Artemis.Utilities.DataReaders; -using Newtonsoft.Json; - -namespace Artemis.Modules.Games.LightFx -{ - public class LightFxModel : ModuleModel - { - public LightFxModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer) - : base(deviceManager, luaManager) - { - Settings = SettingsProvider.Load(); - DataModel = new LightFxDataModel(); - ProcessNames.Add("LoL"); - - // This model can enable itself by changing its process name to the currently running Light FX game. - pipeServer.PipeMessage += PipeServerOnPipeMessage; - } - - public override string Name => "LightFX"; - public override bool IsOverlay => false; - public override bool IsBoundToProcess => true; - - private void PipeServerOnPipeMessage(string msg) - { - // Ensure it's Light FX JSON - if (!msg.Contains("lightFxState")) - return; - - // Deserialize and data - try - { - JsonConvert.PopulateObject(msg, DataModel); - } - catch (Exception ex) - { - Logger?.Error(ex, "Failed to deserialize LightFX JSON"); - throw; - } - - // Setup process name - var processName = Path.GetFileNameWithoutExtension(((LightFxDataModel) DataModel).LightFxState.game); - if (!ProcessNames.Contains(processName)) - ProcessNames.Add(processName); - } - - public override void Update() - { - } - } -} \ No newline at end of file +//using System; +//using System.IO; +//using Artemis.DAL; +//using Artemis.Managers; +//using Artemis.Modules.Abstract; +//using Artemis.Utilities.DataReaders; +//using Newtonsoft.Json; +// +//namespace Artemis.Modules.Games.LightFx +//{ +// public class LightFxModel : ModuleModel +// { +// public LightFxModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer) +// : base(deviceManager, luaManager) +// { +// Settings = SettingsProvider.Load(); +// DataModel = new LightFxDataModel(); +// ProcessNames.Add("LoL"); +// +// // This model can enable itself by changing its process name to the currently running Light FX game. +// pipeServer.PipeMessage += PipeServerOnPipeMessage; +// } +// +// public override string Name => "LightFX"; +// public override bool IsOverlay => false; +// public override bool IsBoundToProcess => true; +// +// private void PipeServerOnPipeMessage(string msg) +// { +// // Ensure it's Light FX JSON +// if (!msg.Contains("lightFxState")) +// return; +// +// // Deserialize and data +// try +// { +// JsonConvert.PopulateObject(msg, DataModel); +// } +// catch (Exception ex) +// { +// Logger?.Error(ex, "Failed to deserialize LightFX JSON"); +// throw; +// } +// +// // Setup process name +// var processName = Path.GetFileNameWithoutExtension(((LightFxDataModel) DataModel).LightFxState.game); +// if (!ProcessNames.Contains(processName)) +// ProcessNames.Add(processName); +// } +// +// public override void Update() +// { +// } +// } +//} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/LightFx/LightFxViewModel.cs b/Artemis/Artemis/Modules/Games/LightFx/LightFxViewModel.cs index 42cffd552..2583dc492 100644 --- a/Artemis/Artemis/Modules/Games/LightFx/LightFxViewModel.cs +++ b/Artemis/Artemis/Modules/Games/LightFx/LightFxViewModel.cs @@ -1,17 +1,17 @@ -using Artemis.Managers; -using Artemis.Modules.Abstract; -using Ninject; - -namespace Artemis.Modules.Games.LightFx -{ - public sealed class LightFxViewModel : ModuleViewModel - { - public LightFxViewModel(MainManager mainManager, [Named(nameof(LightFxModel))] ModuleModel moduleModel, - IKernel kernel) : base(mainManager, moduleModel, kernel) - { - DisplayName = "Light FX"; - } - - public override bool UsesProfileEditor => true; - } -} \ No newline at end of file +//using Artemis.Managers; +//using Artemis.Modules.Abstract; +//using Ninject; +// +//namespace Artemis.Modules.Games.LightFx +//{ +// public sealed class LightFxViewModel : ModuleViewModel +// { +// public LightFxViewModel(MainManager mainManager, [Named(nameof(LightFxModel))] ModuleModel moduleModel, +// IKernel kernel) : base(mainManager, moduleModel, kernel) +// { +// DisplayName = "Light FX"; +// } +// +// public override bool UsesProfileEditor => true; +// } +//} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs index d2a80a83d..d88d29715 100644 --- a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs +++ b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs @@ -1,138 +1,143 @@ -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Artemis.DAL; -using Artemis.Managers; -using Artemis.Modules.Abstract; -using Artemis.Utilities; -using Artemis.Utilities.DataReaders; - -namespace Artemis.Modules.Games.TheDivision -{ - public class TheDivisionModel : ModuleModel - { - private readonly PipeServer _pipeServer; - private StickyValue _stickyAmmo; - private StickyValue _stickyHp; - - public TheDivisionModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer) - : base(deviceManager, luaManager) - { - _pipeServer = pipeServer; - - Settings = SettingsProvider.Load(); - DataModel = new TheDivisionDataModel(); - ProcessNames.Add("TheDivision"); - } - - public override string Name => "TheDivision"; - public override bool IsOverlay => false; - public override bool IsBoundToProcess => true; - - public override void Dispose() - { - base.Dispose(); - - // Delay restoring the DLL to allow The Division to release it - Task.Factory.StartNew(() => - { - Thread.Sleep(2000); - DllManager.RestoreLogitechDll(); - }); - - _stickyAmmo?.Dispose(); - _stickyHp?.Dispose(); - _pipeServer.PipeMessage -= PipeServerOnPipeMessage; - } - - public override void Enable() - { - _stickyAmmo = new StickyValue(200); - _stickyHp = new StickyValue(200); - - DllManager.PlaceLogitechDll(); - - _pipeServer.PipeMessage += PipeServerOnPipeMessage; - - base.Enable(); - } - - private void PipeServerOnPipeMessage(string reply) - { - if (!IsInitialized) - return; - - // Convert the given string to a list of ints - var stringParts = reply.Split(' '); - if (stringParts[0] != "1") - return; - - // Parse into a list of ints and interpertrate - var parts = new int[stringParts.Length]; - for (var i = 0; i < stringParts.Length; i++) - parts[i] = int.Parse(stringParts[i]); - - InterpertrateDivisionKey(parts); - } - - // Parses Division key data to game data - private void InterpertrateDivisionKey(IReadOnlyList parts) - { - var gameDataModel = (TheDivisionDataModel) DataModel; - var keyCode = parts[1]; - var rPer = parts[2]; - var gPer = parts[3]; - var bPer = parts[4]; - - // F1 to F4 indicate the player and his party. Blinks red on damage taken - if (keyCode >= 59 && keyCode <= 62) - { - var playerId = keyCode - 58; - - PlayerState newState; - if (gPer > 10) - newState = PlayerState.Online; - else if (rPer > 10) - newState = PlayerState.Hit; - else - newState = PlayerState.Offline; - - if (playerId == 1) - gameDataModel.LowHp = newState == PlayerState.Hit; - else if (playerId == 2) - gameDataModel.PartyMember1 = newState; - else if (playerId == 3) - gameDataModel.PartyMember2 = newState; - else if (playerId == 4) - gameDataModel.PartyMember3 = newState; - } - // R blinks white when low on ammo - else if (keyCode == 19) - { - _stickyAmmo.Value = rPer == 100 && gPer > 1 && bPer > 1; - gameDataModel.LowAmmo = _stickyAmmo.Value; - } - // G turns white when holding a grenade, turns off when out of grenades - else if (keyCode == 34) - { - if (rPer == 100 && gPer < 10 && bPer < 10) - gameDataModel.GrenadeState = GrenadeState.HasGrenade; - else if (rPer == 100 && gPer > 10 && bPer > 10) - gameDataModel.GrenadeState = GrenadeState.GrenadeEquipped; - else - gameDataModel.GrenadeState = GrenadeState.HasNoGrenade; - } - // V blinks on low HP - else if (keyCode == 47) - { - _stickyHp.Value = rPer == 100 && gPer > 1 && bPer > 1; - gameDataModel.LowHp = _stickyHp.Value; - } - } - - public override void Update() - { - // DataModel updating is done whenever a pipe message is received - } - } -} \ No newline at end of file +//using System.Collections.Generic; +//using System.Linq; +//using System.Threading; +//using System.Threading.Tasks; +//using Artemis.DAL; +//using Artemis.DeviceProviders.Logitech.Utilities; +//using Artemis.Managers; +//using Artemis.Modules.Abstract; +//using Artemis.Utilities; +//using Artemis.Utilities.DataReaders; +// +//namespace Artemis.Modules.Games.TheDivision +//{ +// public class TheDivisionModel : ModuleModel +// { +// private readonly PipeServer _pipeServer; +// private StickyValue _stickyAmmo; +// private StickyValue _stickyHp; +// +// public TheDivisionModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer) +// : base(deviceManager, luaManager) +// { +// _pipeServer = pipeServer; +// +// Settings = SettingsProvider.Load(); +// DataModel = new TheDivisionDataModel(); +// ProcessNames.Add("TheDivision"); +// } +// +// public override string Name => "TheDivision"; +// public override bool IsOverlay => false; +// public override bool IsBoundToProcess => true; +// +// public override void Dispose() +// { +// base.Dispose(); +// +// // Delay restoring the DLL to allow The Division to release it +// Task.Factory.StartNew(() => +// { +// Thread.Sleep(2000); +// DllManager.RestoreLogitechDll(); +// }); +// +// _stickyAmmo?.Dispose(); +// _stickyHp?.Dispose(); +// _pipeServer.PipeMessage -= PipeServerOnPipeMessage; +// } +// +// public override void Enable() +// { +// _stickyAmmo = new StickyValue(200); +// _stickyHp = new StickyValue(200); +// +// var process = System.Diagnostics.Process.GetProcessesByName("TheDivision").First(); +// DllManager.PlaceLogitechDll(); +// +// _pipeServer.PipeMessage += PipeServerOnPipeMessage; +// +// base.Enable(); +// } +// +// private void PipeServerOnPipeMessage(string reply) +// { +// if (!IsInitialized) +// return; +// +// // Convert the given string to a list of ints +// var stringParts = reply.Split(' '); +// if (stringParts[0] != "1") +// return; +// +// // Parse into a list of ints and interpertrate +// var parts = new int[stringParts.Length]; +// for (var i = 0; i < stringParts.Length; i++) +// parts[i] = int.Parse(stringParts[i]); +// +// InterpertrateDivisionKey(parts); +// } +// +// // Parses Division key data to game data +// private void InterpertrateDivisionKey(IReadOnlyList parts) +// { +// var gameDataModel = (TheDivisionDataModel) DataModel; +// var keyCode = parts[1]; +// var rPer = parts[2]; +// var gPer = parts[3]; +// var bPer = parts[4]; +// +// var keyEnum = (KeyboardNames) keyCode; +// +// // F1 to F4 indicate the player and his party. Blinks red on damage taken +// if (keyCode >= 59 && keyCode <= 62) +// { +// var playerId = keyCode - 58; +// +// PlayerState newState; +// if (gPer > 10) +// newState = PlayerState.Online; +// else if (rPer > 10) +// newState = PlayerState.Hit; +// else +// newState = PlayerState.Offline; +// +// if (playerId == 1) +// gameDataModel.LowHp = newState == PlayerState.Hit; +// else if (playerId == 2) +// gameDataModel.PartyMember1 = newState; +// else if (playerId == 3) +// gameDataModel.PartyMember2 = newState; +// else if (playerId == 4) +// gameDataModel.PartyMember3 = newState; +// } +// // R blinks white when low on ammo +// else if (keyCode == 19) +// { +// _stickyAmmo.Value = rPer == 100 && gPer > 1 && bPer > 1; +// gameDataModel.LowAmmo = _stickyAmmo.Value; +// } +// // G turns white when holding a grenade, turns off when out of grenades +// else if (keyCode == 34) +// { +// if (rPer == 100 && gPer < 10 && bPer < 10) +// gameDataModel.GrenadeState = GrenadeState.HasGrenade; +// else if (rPer == 100 && gPer > 10 && bPer > 10) +// gameDataModel.GrenadeState = GrenadeState.GrenadeEquipped; +// else +// gameDataModel.GrenadeState = GrenadeState.HasNoGrenade; +// } +// // V blinks on low HP +// else if (keyCode == 47) +// { +// _stickyHp.Value = rPer == 100 && gPer > 1 && bPer > 1; +// gameDataModel.LowHp = _stickyHp.Value; +// } +// } +// +// public override void Update() +// { +// // DataModel updating is done whenever a pipe message is received +// } +// } +//} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionViewModel.cs b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionViewModel.cs index 1239cf98b..fa667a647 100644 --- a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionViewModel.cs +++ b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionViewModel.cs @@ -1,17 +1,17 @@ -using Artemis.Managers; -using Artemis.Modules.Abstract; -using Ninject; - -namespace Artemis.Modules.Games.TheDivision -{ - public sealed class TheDivisionViewModel : ModuleViewModel - { - public TheDivisionViewModel(MainManager mainManager, [Named(nameof(TheDivisionModel))] ModuleModel moduleModel, - IKernel kernel) : base(mainManager, moduleModel, kernel) - { - DisplayName = "The Division"; - } - - public override bool UsesProfileEditor => true; - } -} \ No newline at end of file +//using Artemis.Managers; +//using Artemis.Modules.Abstract; +//using Ninject; +// +//namespace Artemis.Modules.Games.TheDivision +//{ +// public sealed class TheDivisionViewModel : ModuleViewModel +// { +// public TheDivisionViewModel(MainManager mainManager, [Named(nameof(TheDivisionModel))] ModuleModel moduleModel, +// IKernel kernel) : base(mainManager, moduleModel, kernel) +// { +// DisplayName = "The Division"; +// } +// +// public override bool UsesProfileEditor => true; +// } +//} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs b/Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs index 52fbf1d88..bf78ce542 100644 --- a/Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs +++ b/Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs @@ -2,34 +2,48 @@ using System.Windows.Media; using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; +using Betwixt; namespace Artemis.Profiles.Layers.Animations { public class PulseAnimation : ILayerAnimation { + private bool _increase = true; + + private Tweener _opacityTweener = new Tweener(0, 1000, 1000, Ease.Quad.InOut, LerpFuncFloat); public string Name => "Pulse"; public void Update(LayerModel layerModel, bool updateAnimations) { // TODO: Generic implementation // Reset animation progress if layer wasn't drawn for 100ms - if ((new TimeSpan(0, 0, 0, 0, 100) < DateTime.Now - layerModel.LastRender) && updateAnimations) - layerModel.AnimationProgress = 0; + if (new TimeSpan(0, 0, 0, 0, 100) < DateTime.Now - layerModel.LastRender && updateAnimations || MustExpire(layerModel)) + { + _opacityTweener = new Tweener(0, 1000, 1000, Ease.Quad.InOut, LerpFuncFloat); + _increase = true; + } - var progress = layerModel.AnimationProgress; + // Update animation progress + if (!updateAnimations) + return; - if (MustExpire(layerModel)) - progress = 0; - progress = progress + layerModel.Properties.AnimationSpeed/2; + if (!_opacityTweener.Running && _increase) + { + _opacityTweener = new Tweener(1000, 0, 1000, Ease.Quad.InOut, LerpFuncFloat); + _increase = false; + } - // If not previewing, store the animation progress in the actual model for the next frame - if (updateAnimations) - layerModel.AnimationProgress = progress; + _opacityTweener.Update(40); + + if (_increase) + layerModel.AnimationProgress = _opacityTweener.Value / 1000; + else + layerModel.AnimationProgress = 1 + (1 - _opacityTweener.Value / 1000); } public void Draw(LayerModel layerModel, DrawingContext c, int drawScale) { - if (layerModel.Brush == null) + if (layerModel.Brush == null || _opacityTweener == null) return; // Set up variables for this frame @@ -41,7 +55,7 @@ namespace Artemis.Profiles.Layers.Animations // Can't meddle with the original brush because it's frozen. var brush = layerModel.Brush.Clone(); - brush.Opacity = (Math.Sin(layerModel.AnimationProgress*Math.PI) + 1)*(layerModel.Opacity/2); + brush.Opacity = _opacityTweener.Value / 1000; layerModel.Brush = brush; c.PushClip(new RectangleGeometry(clip)); @@ -49,6 +63,11 @@ namespace Artemis.Profiles.Layers.Animations c.Pop(); } - public bool MustExpire(LayerModel layer) => layer.AnimationProgress > 2; + public bool MustExpire(LayerModel layer) => layer.AnimationProgress >= 2; + + private static float LerpFuncFloat(float start, float end, float percent) + { + return start + (end - start) * percent; + } } -} \ No newline at end of file +} diff --git a/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs b/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs index 45f15dcbc..de5962b44 100644 --- a/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs +++ b/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs @@ -12,6 +12,15 @@ namespace Artemis.Profiles.Layers.Conditions lock (layerModel.Properties.Conditions) { var checkConditions = layerModel.Properties.Conditions.Where(c => c.Field != null).ToList(); + + // Don't trigger constantly when there are no conditions + if (!checkConditions.Any()) + { + layerModel.EventProperties.Update(layerModel, false); + return layerModel.EventProperties.MustDraw; + } + + // Determine whether conditions are met var conditionsMet = false; switch (layerModel.Properties.ConditionType) { @@ -26,11 +35,14 @@ namespace Artemis.Profiles.Layers.Conditions break; } + // Update the event properties layerModel.EventProperties.Update(layerModel, conditionsMet); - + + // If conditions are met trigger the event, this won't do anything if the event isn't ready to be triggered yet if (conditionsMet) layerModel.EventProperties.TriggerEvent(layerModel); + // Return the event's MustDraw return layerModel.EventProperties.MustDraw; } } diff --git a/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs index d145bf7ae..07c36de83 100644 --- a/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs @@ -1,4 +1,5 @@ using System; +using System.Timers; using Newtonsoft.Json; namespace Artemis.Profiles.Layers.Models @@ -10,7 +11,7 @@ namespace Artemis.Profiles.Layers.Models public TimeSpan TriggerDelay { get; set; } [JsonIgnore] - public bool CanTrigger { get; set; } + public bool CanTrigger { get; set; } = true; [JsonIgnore] public DateTime EventTriggerTime { get; set; } @@ -18,30 +19,46 @@ namespace Artemis.Profiles.Layers.Models [JsonIgnore] public bool MustDraw { get; set; } - public DateTime EventCanTriggerTime { get; set; } - /// - /// Resets the event's properties and triggers it + /// If possible, triggers the event /// public virtual void TriggerEvent(LayerModel layer) { if (!CanTrigger) return; + // Don't allow any more triggering regardless of what happens next + CanTrigger = false; + + // If there is a trigger delay, stop here and await that delay if (TriggerDelay > TimeSpan.Zero) { - if (EventCanTriggerTime == DateTime.MinValue) - EventCanTriggerTime = DateTime.Now; + var timer = new Timer(TriggerDelay.TotalMilliseconds) {AutoReset = false}; + timer.Elapsed += (sender, args) => + { + HardTrigger(layer); + timer.Dispose(); + }; + timer.Start(); - if (DateTime.Now - EventCanTriggerTime < TriggerDelay) - return; - - EventCanTriggerTime = DateTime.MinValue; + return; } - CanTrigger = false; + // Trigger the event + HardTrigger(layer); + } + + /// + /// Instantly trigger the event regardless of current state + /// + /// + public void HardTrigger(LayerModel layer) + { MustDraw = true; + CanTrigger = false; EventTriggerTime = DateTime.Now; + + // Reset the animation in case it didn't finish before layer.AnimationProgress = 0.0; } @@ -60,7 +77,7 @@ namespace Artemis.Profiles.Layers.Models return DateTime.Now - EventTriggerTime > Length; } if (ExpirationType == ExpirationType.Animation) - return (layer.LayerAnimation == null) || layer.LayerAnimation.MustExpire(layer); + return layer.LayerAnimation == null || layer.LayerAnimation.MustExpire(layer); return true; } @@ -68,24 +85,17 @@ namespace Artemis.Profiles.Layers.Models // Called every frame, if parent conditions met. public void Update(LayerModel layerModel, bool conditionsMet) { - if (EventCanTriggerTime > DateTime.MinValue && (DateTime.Now - EventCanTriggerTime > TriggerDelay)) - { - CanTrigger = true; - TriggerEvent(layerModel); + // If the event isn't finished yet just keep going + if (MustDraw && !MustStop(layerModel)) return; - } - if (MustDraw && MustStop(layerModel)) - MustDraw = false; + // Otherwise make sure MustDraw is false + MustDraw = false; + // If the conditions aren't met and the event has finished it can be triggered again if (!conditionsMet) CanTrigger = true; } - - protected bool DelayExpired() - { - return EventCanTriggerTime > DateTime.MinValue && DateTime.Now - EventCanTriggerTime >= TriggerDelay; - } } public enum ExpirationType @@ -93,4 +103,4 @@ namespace Artemis.Profiles.Layers.Models Time, Animation } -} \ No newline at end of file +} diff --git a/Artemis/Artemis/Profiles/Layers/Models/KeyboardEventPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Models/KeyboardEventPropertiesModel.cs index 76c9cfb08..e0d9a453a 100644 --- a/Artemis/Artemis/Profiles/Layers/Models/KeyboardEventPropertiesModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Models/KeyboardEventPropertiesModel.cs @@ -7,7 +7,7 @@ namespace Artemis.Profiles.Layers.Models { public override void TriggerEvent(LayerModel layer) { - if (CanTrigger && DelayExpired()) + if (CanTrigger) { if (layer.GifImage != null) layer.GifImage.CurrentFrame = 0; @@ -18,12 +18,10 @@ namespace Artemis.Profiles.Layers.Models public override bool MustStop(LayerModel layer) { - if (ExpirationType != ExpirationType.Animation) - return base.MustStop(layer); - - if (layer.LayerType is KeyboardGifType) + if (layer.LayerType is KeyboardGifType && ExpirationType == ExpirationType.Animation) return layer.GifImage?.CurrentFrame >= layer.GifImage?.FrameCount - 1; - return (layer.LayerAnimation == null) || layer.LayerAnimation.MustExpire(layer); + + return base.MustStop(layer); } } -} \ No newline at end of file +} diff --git a/Artemis/Artemis/Profiles/Layers/Models/LayerKeybindModel.cs b/Artemis/Artemis/Profiles/Layers/Models/LayerKeybindModel.cs index 1a693976b..fe69d9430 100644 --- a/Artemis/Artemis/Profiles/Layers/Models/LayerKeybindModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Models/LayerKeybindModel.cs @@ -2,6 +2,7 @@ using System.Windows.Forms; using Artemis.Managers; using Artemis.Models; +using Artemis.Profiles.Layers.Conditions; using MahApps.Metro.Controls; namespace Artemis.Profiles.Layers.Models @@ -33,39 +34,30 @@ namespace Artemis.Profiles.Layers.Models { Unregister(); - // Bind EnableHeldDown or DisableHeldDOwn - if (ToggleType == ToggleType.EnableHeldDown || ToggleType == ToggleType.DisableHeldDown) + if (layerModel.IsEvent) + RegisterEvent(layerModel, index); + else if (ToggleType == ToggleType.EnableHeldDown || ToggleType == ToggleType.DisableHeldDown) + RegisterToggle(layerModel, index); + else + RegisterRegular(layerModel, index); + } + + private void RegisterEvent(LayerModel layerModel, int index) + { + Action action = () => { - Action downAction = null; - Action upAction = null; - switch (ToggleType) - { - case ToggleType.EnableHeldDown: - downAction = () => layerModel.RenderAllowed = true; - upAction = () => layerModel.RenderAllowed = false; - break; - case ToggleType.DisableHeldDown: - downAction = () => layerModel.RenderAllowed = false; - upAction = () => layerModel.RenderAllowed = true; - break; - } - - // Either bind HotKey or mouse buttons depending on what isn't null - if (HotKey != null) - { - _downKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-down", HotKey, PressType.Down, downAction); - _upKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-up", HotKey, PressType.Up, upAction); - } - else if (MouseButtons != null) - { - _downKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-down", MouseButtons.Value, PressType.Down, downAction); - _upKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-up", MouseButtons.Value, PressType.Up, upAction); - } - KeybindManager.AddOrUpdate(_downKeybind); - KeybindManager.AddOrUpdate(_upKeybind); - return; - } + layerModel.EventProperties.TriggerEvent(layerModel); + }; + // Either bind HotKey or mouse buttons depending on what isn't null + if (HotKey != null) + _downKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-down", HotKey, PressType.Down, action); + else if (MouseButtons != null) + _downKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-down", MouseButtons.Value, PressType.Down, action); + KeybindManager.AddOrUpdate(_downKeybind); + } + private void RegisterRegular(LayerModel layerModel, int index) + { // Bind Enable, Disable or Toggle Action action = null; switch (ToggleType) @@ -88,6 +80,38 @@ namespace Artemis.Profiles.Layers.Models _downKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-down", MouseButtons.Value, PressType.Down, action); KeybindManager.AddOrUpdate(_downKeybind); } + + private void RegisterToggle(LayerModel layerModel, int index) + { + Action downAction = null; + Action upAction = null; + switch (ToggleType) + { + case ToggleType.EnableHeldDown: + downAction = () => layerModel.RenderAllowed = true; + upAction = () => layerModel.RenderAllowed = false; + break; + case ToggleType.DisableHeldDown: + downAction = () => layerModel.RenderAllowed = false; + upAction = () => layerModel.RenderAllowed = true; + break; + } + + // Either bind HotKey or mouse buttons depending on what isn't null + if (HotKey != null) + { + _downKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-down", HotKey, PressType.Down, downAction); + _upKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-up", HotKey, PressType.Up, upAction); + } + else if (MouseButtons != null) + { + _downKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-down", MouseButtons.Value, PressType.Down, downAction); + _upKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-up", MouseButtons.Value, PressType.Up, upAction); + } + KeybindManager.AddOrUpdate(_downKeybind); + KeybindManager.AddOrUpdate(_upKeybind); + return; + } } public enum ToggleType diff --git a/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs index eebd4d68f..cb7d09f1d 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs @@ -12,7 +12,6 @@ using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; using Artemis.Properties; using Artemis.Utilities; -using Artemis.Utilities.Keyboard; using Artemis.ViewModels; using Artemis.ViewModels.Profiles; @@ -30,7 +29,7 @@ namespace Artemis.Profiles.Layers.Types.KeyPress _deviceManager = deviceManager; _keyPressLayers = new List(); - KeyboardHook.KeyDownCallback += KeyboardHookOnKeyDownCallback; + InputHook.KeyDownCallback += KeyboardHookOnKeyDownCallback; } public RadialGradientBrush TempBrush { get; set; } diff --git a/Artemis/Artemis/Profiles/Lua/Modules/LuaEventsModule.cs b/Artemis/Artemis/Profiles/Lua/Modules/LuaEventsModule.cs index d2c313886..02abc90dd 100644 --- a/Artemis/Artemis/Profiles/Lua/Modules/LuaEventsModule.cs +++ b/Artemis/Artemis/Profiles/Lua/Modules/LuaEventsModule.cs @@ -5,7 +5,7 @@ using Artemis.Events; using Artemis.Managers; using Artemis.Profiles.Lua.Modules.Events; using Artemis.Profiles.Lua.Wrappers; -using Artemis.Utilities.Keyboard; +using Artemis.Utilities; using MoonSharp.Interpreter; using NLog; @@ -23,7 +23,7 @@ namespace Artemis.Profiles.Lua.Modules _profileModel = luaManager.ProfileModel; _profileModel.OnDeviceUpdatedEvent += OnDeviceUpdatedEvent; _profileModel.OnDeviceDrawnEvent += OnDeviceDrawnEvent; - KeyboardHook.KeyDownCallback += KeyboardHookOnKeyDownCallback; + InputHook.KeyDownCallback += KeyboardHookOnKeyDownCallback; } public override string ModuleName => "Events"; @@ -118,7 +118,7 @@ namespace Artemis.Profiles.Lua.Modules { _profileModel.OnDeviceUpdatedEvent -= OnDeviceUpdatedEvent; _profileModel.OnDeviceDrawnEvent -= OnDeviceDrawnEvent; - KeyboardHook.KeyDownCallback -= KeyboardHookOnKeyDownCallback; + InputHook.KeyDownCallback -= KeyboardHookOnKeyDownCallback; } #endregion diff --git a/Artemis/Artemis/Utilities/DataReaders/DllManager.cs b/Artemis/Artemis/Utilities/DataReaders/DllManager.cs index d733fcd3a..e1f1802a9 100644 --- a/Artemis/Artemis/Utilities/DataReaders/DllManager.cs +++ b/Artemis/Artemis/Utilities/DataReaders/DllManager.cs @@ -29,59 +29,22 @@ namespace Artemis.Utilities.DataReaders #region Logitech - private const string LogitechPath = @"C:\Program Files\Logitech Gaming Software\SDK\LED\x64\"; - - public static bool RestoreLogitechDll() - { - if (!DllPlaced()) - return false; - - try - { - // Get rid of our own DLL - File.Delete(LogitechPath + @"\LogitechLed.dll"); - - // Restore the backup - if (File.Exists(LogitechPath + @"\LogitechLed.dll.bak")) - File.Copy(LogitechPath + @"\LogitechLed.dll.bak", LogitechPath + @"\LogitechLed.dll"); - - File.Delete(LogitechPath + @"\artemis.txt"); - - return true; - } - catch (Exception) - { - return false; - } - } + private static readonly string LogitechPath = @"C:\Program Files\Logitech Gaming Software\SDK\LED\x64\"; + private static readonly string DllPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Artemis\dll"; public static void PlaceLogitechDll() { - if (DllPlaced()) - return; - try - { - // Create directory structure, just in case - Directory.CreateDirectory(LogitechPath + @""); - - // Backup the existing DLL - if (File.Exists(LogitechPath + @"\LogitechLed.dll")) - { - if (!File.Exists(LogitechPath + @"\LogitechLed.dll.bak")) - File.Move(LogitechPath + @"\LogitechLed.dll", LogitechPath + @"\LogitechLed.dll.bak"); - } - - // Copy our own DLL in place - File.WriteAllBytes(LogitechPath + @"\LogitechLED.dll", Resources.LogitechLED); - - // A token to show the file is placed - File.Create(LogitechPath + @"\artemis.txt"); - - // If the user doesn't have a Logitech device, the CLSID will be missing - // and we should create it ourselves. - if (!RegistryKeyPlaced()) - PlaceRegistryKey(); + { + // Change the registry key to point to the fake DLL + var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary", true); + key?.SetValue(null, DllPath + @"\LogitechLed.dll"); + + // Make sure the fake DLL is in place + if (!Directory.Exists(DllPath)) + Directory.CreateDirectory(DllPath); + if (!File.Exists(DllPath + @"\LogitechLed.dll")) + File.WriteAllBytes(DllPath + @"\LogitechLED.dll", Resources.LogitechLED); } catch (Exception e) { @@ -89,32 +52,13 @@ namespace Artemis.Utilities.DataReaders } } - public static bool DllPlaced() + public static void RestoreLogitechDll() { - if (!Directory.Exists(LogitechPath + @"")) - return false; - if (!RegistryKeyPlaced()) - return false; - - return File.Exists(LogitechPath + @"\artemis.txt"); - } - - private static bool RegistryKeyPlaced() - { - var key = Registry - .LocalMachine.OpenSubKey( - @"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary"); - return key != null; - } - - private static void PlaceRegistryKey() - { - var key = Registry - .LocalMachine.OpenSubKey( - @"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary", true); + // Change the registry key to point to the real DLL + var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary", true); key?.SetValue(null, LogitechPath + @"\LogitechLed.dll"); } #endregion } -} \ No newline at end of file +} diff --git a/Artemis/Artemis/Utilities/Keyboard/KeyboardHook.cs b/Artemis/Artemis/Utilities/InputHook.cs similarity index 94% rename from Artemis/Artemis/Utilities/Keyboard/KeyboardHook.cs rename to Artemis/Artemis/Utilities/InputHook.cs index d27ac4e05..b1ba31c3b 100644 --- a/Artemis/Artemis/Utilities/Keyboard/KeyboardHook.cs +++ b/Artemis/Artemis/Utilities/InputHook.cs @@ -4,9 +4,9 @@ using System.Windows.Forms; using Gma.System.MouseKeyHook; using NLog; -namespace Artemis.Utilities.Keyboard +namespace Artemis.Utilities { - public static class KeyboardHook + public static class InputHook { public delegate void KeyCallbackHandler(KeyEventArgs e); diff --git a/Artemis/Artemis/ViewModels/Profiles/LayerKeybindViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/LayerKeybindViewModel.cs index 3203850dd..3f81ac17e 100644 --- a/Artemis/Artemis/ViewModels/Profiles/LayerKeybindViewModel.cs +++ b/Artemis/Artemis/ViewModels/Profiles/LayerKeybindViewModel.cs @@ -9,6 +9,7 @@ namespace Artemis.ViewModels.Profiles public sealed class LayerKeybindViewModel : Screen { private readonly LayerEditorViewModel _editorViewModel; + private bool _canToggleType; private HotKey _hotKey; private MouseButtons _mouseButtons; @@ -20,30 +21,20 @@ namespace Artemis.ViewModels.Profiles LayerKeybindModel = layerKeybindModel; PropertyChanged += MapViewToModel; + editorViewModel.PropertyChanged += EditorViewModelOnPropertyChanged; MapModelToView(); } - private void MapViewToModel(object sender, PropertyChangedEventArgs e) + public bool CanToggleType { - if (e.PropertyName == "MouseButtonsVisible" || e.PropertyName == "HotkeyVisible") - return; - - if (MouseButtonsVisible) - SetMouseBind(); - else - SetKeyBind(); - } - - private void MapModelToView() - { - PropertyChanged -= MapViewToModel; - - if (LayerKeybindModel.MouseButtons != null) - MouseButtons = LayerKeybindModel.MouseButtons.Value; - HotKey = LayerKeybindModel.HotKey; - ToggleType = LayerKeybindModel.ToggleType; - - PropertyChanged += MapViewToModel; + get { return _canToggleType; } + set + { + if (value == _canToggleType) + return; + _canToggleType = value; + NotifyOfPropertyChange(() => CanToggleType); + } } public LayerKeybindModel LayerKeybindModel { get; set; } @@ -88,6 +79,48 @@ namespace Artemis.ViewModels.Profiles } } + /// + /// Responds to the EventPropertiesViewModel being changed + /// + /// + /// + private void EditorViewModelOnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName != "EventPropertiesViewModel") + return; + + if (_editorViewModel.ProposedLayer.IsEvent) + { + CanToggleType = false; + ToggleType = ToggleType.Enable; + } + else + CanToggleType = true; + } + + private void MapViewToModel(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == "MouseButtonsVisible" || e.PropertyName == "HotkeyVisible") + return; + + if (MouseButtonsVisible) + SetMouseBind(); + else + SetKeyBind(); + } + + private void MapModelToView() + { + PropertyChanged -= MapViewToModel; + + if (LayerKeybindModel.MouseButtons != null) + MouseButtons = LayerKeybindModel.MouseButtons.Value; + HotKey = LayerKeybindModel.HotKey; + ToggleType = LayerKeybindModel.ToggleType; + + PropertyChanged += MapViewToModel; + } + public void ToggleBindType() { if (MouseButtonsVisible) diff --git a/Artemis/Artemis/Views/LayerEditorView.xaml b/Artemis/Artemis/Views/LayerEditorView.xaml index 5c25c13cb..4895a6fa6 100644 --- a/Artemis/Artemis/Views/LayerEditorView.xaml +++ b/Artemis/Artemis/Views/LayerEditorView.xaml @@ -6,7 +6,7 @@ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls" xmlns:sys="clr-namespace:System;assembly=mscorlib" mc:Ignorable="d" - Title="Artemis | Edit Layer" Height="600" Width="1100" + Title="Artemis | Edit Layer" Height="640" Width="1100" xmlns:cal="http://www.caliburnproject.org" xmlns:converters="clr-namespace:Artemis.Utilities.Converters" xmlns:models="clr-namespace:Artemis.Profiles.Layers.Models" @@ -96,7 +96,7 @@ - + diff --git a/Artemis/Artemis/Views/Profiles/LayerKeybindView.xaml b/Artemis/Artemis/Views/Profiles/LayerKeybindView.xaml index 4e213873e..742a7913d 100644 --- a/Artemis/Artemis/Views/Profiles/LayerKeybindView.xaml +++ b/Artemis/Artemis/Views/Profiles/LayerKeybindView.xaml @@ -32,7 +32,7 @@ - +