diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index 33a68535c..05ae14294 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -279,6 +279,7 @@ + @@ -296,7 +297,7 @@ - + @@ -309,6 +310,7 @@ + @@ -461,6 +463,7 @@ + @@ -498,6 +501,9 @@ Witcher3View.xaml + + HeadsetPropertiesView.xaml + KeyboardPropertiesView.xaml @@ -680,6 +686,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs index 1e2b9d57a..22bac4888 100644 --- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs +++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs @@ -1,36 +1,56 @@ -using System.Threading; +using System.Linq; +using System.Threading; +using System.Windows; using System.Windows.Media; +using Artemis.Utilities; using CUE.NET; using CUE.NET.Devices.Generic.Enums; -using CUE.NET.Devices.Mouse; using CUE.NET.Exceptions; namespace Artemis.DeviceProviders.Corsair { internal class CorsairMice : DeviceProvider { - private readonly CorsairRGB _corsairRgb; - private CorsairMouse _mouse; - - public CorsairMice(CorsairRGB corsairRgb) + public CorsairMice() { - _corsairRgb = corsairRgb; - UpdateCanUse(); + Type = DeviceType.Mouse; } - private void UpdateCanUse() + public override bool TryEnable() { - if (!CanInitializeSdk()) - { - CanUse = false; + CanUse = CanInitializeSdk(); + return CanUse; + } + + public override void Disable() + { + if (CueSDK.ProtocolDetails != null) + CueSDK.Reinitialize(); + } + + public override void UpdateDevice(Brush brush) + { + if (!CanUse || brush == null) return; + + var leds = CueSDK.MouseSDK.Leds.Count(); + var rect = new Rect(new Size(leds*5, leds*5)); + var img = brush.Dispatcher.Invoke(() => + { + var visual = new DrawingVisual(); + using (var c = visual.RenderOpen()) + c.DrawRectangle(brush, null, rect); + return ImageUtilities.DrawinVisualToBitmap(visual, rect); + }); + + var ledIndex = 0; + // Color each LED according to one of the pixels + foreach (var corsairLed in CueSDK.MouseSDK.Leds) + { + corsairLed.Color = img.GetPixel(ledIndex*5, ledIndex*5); + ledIndex++; } - - if (CueSDK.ProtocolDetails == null) - CueSDK.Initialize(true); - - _mouse = CueSDK.MouseSDK; - + CueSDK.MouseSDK.Update(true); } private static bool CanInitializeSdk() @@ -43,15 +63,17 @@ namespace Artemis.DeviceProviders.Corsair { if (CueSDK.ProtocolDetails == null) CueSDK.Initialize(); + else + return true; } catch (CUEException e) { - if (e.Error == CorsairError.ServerNotFound) - { - tries++; - Thread.Sleep(1000); - continue; - } + if (e.Error != CorsairError.ServerNotFound) + return true; + + tries++; + Thread.Sleep(1000); + continue; } catch (WrapperException) { @@ -64,11 +86,5 @@ namespace Artemis.DeviceProviders.Corsair return false; } - - public override void UpdateDevice(Brush brush) - { - if (!CanUse) - return; - } } } \ No newline at end of file diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairRGB.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairRGB.cs index cb2ff1e65..e23e0d8cb 100644 --- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairRGB.cs +++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairRGB.cs @@ -61,45 +61,39 @@ namespace Artemis.DeviceProviders.Corsair /// public override void Enable() { - try - { - if (CueSDK.ProtocolDetails == null) - CueSDK.Initialize(true); - } - catch (WrapperException) - { - /*CUE is already initialized*/ - } + if (CueSDK.ProtocolDetails == null) + CueSDK.Initialize(true); + _keyboard = CueSDK.KeyboardSDK; - if (_keyboard.DeviceInfo.Model == "K95 RGB") + switch (_keyboard.DeviceInfo.Model) { - Height = 7; - Width = 25; - PreviewSettings = new PreviewSettings(626, 175, new Thickness(0, -15, 0, 0), Resources.k95); - } - else if (_keyboard.DeviceInfo.Model == "K70 RGB") - { - Height = 7; - Width = 21; - PreviewSettings = new PreviewSettings(626, 195, new Thickness(0, -25, 0, 0), Resources.k70); - } - else if (_keyboard.DeviceInfo.Model == "K65 RGB") - { - Height = 7; - Width = 18; - PreviewSettings = new PreviewSettings(610, 240, new Thickness(0, -30, 0, 0), Resources.k65); - } - else if (_keyboard.DeviceInfo.Model == "STRAFE RGB") - { - Height = 6; - Width = 22; - PreviewSettings = new PreviewSettings(620, 215, new Thickness(0, -15, 0, 0), Resources.strafe); + case "K95 RGB": + Height = 7; + Width = 25; + PreviewSettings = new PreviewSettings(626, 175, new Thickness(0, -15, 0, 0), Resources.k95); + break; + case "K70 RGB": + Height = 7; + Width = 21; + PreviewSettings = new PreviewSettings(626, 195, new Thickness(0, -25, 0, 0), Resources.k70); + break; + case "K65 RGB": + Height = 7; + Width = 18; + PreviewSettings = new PreviewSettings(610, 240, new Thickness(0, -30, 0, 0), Resources.k65); + break; + case "STRAFE RGB": + Height = 6; + Width = 22; + PreviewSettings = new PreviewSettings(620, 215, new Thickness(0, -15, 0, 0), Resources.strafe); + break; } } public override void Disable() { - CueSDK.Reinitialize(); + if (CueSDK.ProtocolDetails != null) + CueSDK.Reinitialize(); } /// diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsiarHeadsets.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsiarHeadsets.cs new file mode 100644 index 000000000..352c8eeb5 --- /dev/null +++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsiarHeadsets.cs @@ -0,0 +1,90 @@ +using System.Linq; +using System.Threading; +using System.Windows; +using System.Windows.Media; +using Artemis.Utilities; +using CUE.NET; +using CUE.NET.Devices.Generic.Enums; +using CUE.NET.Exceptions; + +namespace Artemis.DeviceProviders.Corsair +{ + internal class CorsairHeadsets : DeviceProvider + { + public CorsairHeadsets() + { + Type = DeviceType.Headset; + } + + public override bool TryEnable() + { + CanUse = CanInitializeSdk(); + return CanUse; + } + + public override void Disable() + { + if (CueSDK.ProtocolDetails != null) + CueSDK.Reinitialize(); + } + + public override void UpdateDevice(Brush brush) + { + if (!CanUse || brush == null) + return; + + var leds = CueSDK.HeadsetSDK.Leds.Count(); + var rect = new Rect(new Size(leds * 5, leds * 5)); + var img = brush.Dispatcher.Invoke(() => + { + var visual = new DrawingVisual(); + using (var c = visual.RenderOpen()) + c.DrawRectangle(brush, null, rect); + return ImageUtilities.DrawinVisualToBitmap(visual, rect); + }); + + var ledIndex = 0; + // Color each LED according to one of the pixels + foreach (var corsairLed in CueSDK.HeadsetSDK.Leds) + { + corsairLed.Color = img.GetPixel(ledIndex * 5, ledIndex * 5); + ledIndex++; + } + CueSDK.HeadsetSDK.Update(true); + } + + private static bool CanInitializeSdk() + { + // Try for about 10 seconds, in case CUE isn't started yet + var tries = 0; + while (tries < 9) + { + try + { + if (CueSDK.ProtocolDetails == null) + CueSDK.Initialize(); + else + return true; + } + catch (CUEException e) + { + if (e.Error != CorsairError.ServerNotFound) + return true; + + tries++; + Thread.Sleep(1000); + continue; + } + catch (WrapperException) + { + CueSDK.Reinitialize(); + return true; + } + + return true; + } + + return false; + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/DeviceProviders/DeviceProvider.cs b/Artemis/Artemis/DeviceProviders/DeviceProvider.cs index e2849d405..f86ee2e64 100644 --- a/Artemis/Artemis/DeviceProviders/DeviceProvider.cs +++ b/Artemis/Artemis/DeviceProviders/DeviceProvider.cs @@ -19,6 +19,16 @@ namespace Artemis.DeviceProviders /// /// public abstract void UpdateDevice(Brush brush); + + /// + /// Tries to enable the device and updates CanUse accordingly + /// + public abstract bool TryEnable(); + + /// + /// Disables the device + /// + public abstract void Disable(); } public enum DeviceType diff --git a/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs b/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs index 80ed57dce..96bce2c60 100644 --- a/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs +++ b/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs @@ -22,8 +22,6 @@ namespace Artemis.DeviceProviders public abstract bool CanEnable(); public abstract void Enable(); - // TODO: This should be done in a background thread with a callback mechanism as it causes UI lag - public abstract void Disable(); public abstract void DrawBitmap(Bitmap bitmap); /// @@ -44,6 +42,11 @@ namespace Artemis.DeviceProviders { throw new NotImplementedException("KeyboardProvider doesn't implement UpdateDevice, use DrawBitmap instead."); } + + public override bool TryEnable() + { + throw new NotImplementedException("KeyboardProvider doesn't implement TryEnable, use CanEnable instead."); + } } public struct PreviewSettings diff --git a/Artemis/Artemis/InjectionModules/ArtemisModules.cs b/Artemis/Artemis/InjectionModules/ArtemisModules.cs index 6d793db48..5b5ae02a9 100644 --- a/Artemis/Artemis/InjectionModules/ArtemisModules.cs +++ b/Artemis/Artemis/InjectionModules/ArtemisModules.cs @@ -36,10 +36,15 @@ namespace Artemis.InjectionModules // Overlays Bind().To().InSingletonScope(); - // Keyboard Providers - Bind().To().InSingletonScope(); - Bind().To().InSingletonScope(); - Bind().To().InSingletonScope(); + // Device Providers + // Keyboards + Bind().To().InSingletonScope(); + Bind().To().InSingletonScope(); + Bind().To().InSingletonScope(); + // Mice + Bind().To().InSingletonScope(); + // Headsets + Bind().To().InSingletonScope(); } } } \ No newline at end of file diff --git a/Artemis/Artemis/InjectionModules/ManagerModules.cs b/Artemis/Artemis/InjectionModules/ManagerModules.cs index 3f409230f..453345f68 100644 --- a/Artemis/Artemis/InjectionModules/ManagerModules.cs +++ b/Artemis/Artemis/InjectionModules/ManagerModules.cs @@ -8,7 +8,7 @@ namespace Artemis.InjectionModules public override void Load() { Bind().ToSelf().InSingletonScope(); - Bind().ToSelf().InSingletonScope(); + Bind().ToSelf().InSingletonScope(); Bind().ToSelf().InSingletonScope(); Bind().ToSelf().InSingletonScope(); } diff --git a/Artemis/Artemis/Managers/KeyboardManager.cs b/Artemis/Artemis/Managers/DeviceManager.cs similarity index 81% rename from Artemis/Artemis/Managers/KeyboardManager.cs rename to Artemis/Artemis/Managers/DeviceManager.cs index 570b03af9..88f9637b6 100644 --- a/Artemis/Artemis/Managers/KeyboardManager.cs +++ b/Artemis/Artemis/Managers/DeviceManager.cs @@ -1,142 +1,160 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Artemis.DeviceProviders; -using Artemis.Events; -using Artemis.Services; -using Artemis.Settings; -using Caliburn.Micro; -using Ninject; -using Ninject.Extensions.Logging; - -namespace Artemis.Managers -{ - /// - /// Manages the keyboard providers - /// - public class KeyboardManager - { - private readonly IEventAggregator _events; - private readonly ILogger _logger; - - public KeyboardManager(IEventAggregator events, ILogger logger, List keyboardProviders) - { - _logger = logger; - _logger.Info("Intializing KeyboardManager"); - - _events = events; - KeyboardProviders = keyboardProviders; - - _logger.Info("Intialized KeyboardManager"); - } - - [Inject] - public MetroDialogService DialogService { get; set; } - - public List KeyboardProviders { get; set; } - - public KeyboardProvider ActiveKeyboard { get; set; } - - public bool ChangingKeyboard { get; private set; } - - /// - /// Enables the last keyboard according to the settings file - /// - public void EnableLastKeyboard() - { - _logger.Debug("Getting last keyboard: {0}", General.Default.LastKeyboard); - if (string.IsNullOrEmpty(General.Default.LastKeyboard)) - return; - - var keyboard = KeyboardProviders.FirstOrDefault(k => k.Name == General.Default.LastKeyboard); - EnableKeyboard(keyboard); - } - - /// - /// Enables the given keyboard - /// - /// - public void EnableKeyboard(KeyboardProvider keyboardProvider) - { - lock (this) - { - ChangingKeyboard = true; - - if (keyboardProvider == null) - throw new ArgumentNullException(nameof(keyboardProvider)); - - if (ActiveKeyboard?.Name == keyboardProvider.Name) - { - ChangingKeyboard = false; - return; - } - - // Store the old keyboard so it can be used in the event we're raising later - var oldKeyboard = ActiveKeyboard; - - var wasNull = false; - if (ActiveKeyboard == null) - { - wasNull = true; - ActiveKeyboard = keyboardProvider; - } - - _logger.Debug("Enabling keyboard: {0}", keyboardProvider.Name); - - if (!wasNull) - ReleaseActiveKeyboard(); - - // Disable everything if there's no active keyboard found - if (!keyboardProvider.CanEnable()) - { - DialogService.ShowErrorMessageBox(keyboardProvider.CantEnableText); - ActiveKeyboard = null; - General.Default.LastKeyboard = null; - General.Default.Save(); - _logger.Warn("Failed enabling keyboard: {0}", keyboardProvider.Name); - ChangingKeyboard = false; - return; - } - - ActiveKeyboard = keyboardProvider; - ActiveKeyboard.Enable(); - - General.Default.LastKeyboard = ActiveKeyboard.Name; - General.Default.Save(); - - ChangingKeyboard = false; - _events.PublishOnUIThread(new ActiveKeyboardChanged(oldKeyboard, ActiveKeyboard)); - _logger.Debug("Enabled keyboard: {0}", keyboardProvider.Name); - } - } - - /// - /// Releases the active keyboard - /// - /// Whether to save the LastKeyboard (making it null) - public void ReleaseActiveKeyboard(bool save = false) - { - lock (this) - { - if (ActiveKeyboard == null) - return; - - // Store the old keyboard so it can be used in the event we're raising later - var oldKeyboard = ActiveKeyboard; - - var releaseName = ActiveKeyboard.Name; - ActiveKeyboard.Disable(); - ActiveKeyboard = null; - - if (save) - { - General.Default.LastKeyboard = null; - General.Default.Save(); - } - - _events.PublishOnUIThread(new ActiveKeyboardChanged(oldKeyboard, null)); - _logger.Debug("Released keyboard: {0}", releaseName); - } - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using Artemis.DeviceProviders; +using Artemis.Events; +using Artemis.Services; +using Artemis.Settings; +using Caliburn.Micro; +using Ninject; +using Ninject.Extensions.Logging; + +namespace Artemis.Managers +{ + /// + /// Manages the keyboard providers + /// + public class DeviceManager + { + private readonly IEventAggregator _events; + private readonly ILogger _logger; + + public DeviceManager(IEventAggregator events, ILogger logger, List deviceProviders) + { + _logger = logger; + _logger.Info("Intializing DeviceManager"); + + _events = events; + + KeyboardProviders = deviceProviders.Where(d => d.Type == DeviceType.Keyboard) + .Cast().ToList(); + MiceProviders = deviceProviders.Where(d => d.Type == DeviceType.Mouse).ToList(); + HeadsetProviders = deviceProviders.Where(d => d.Type == DeviceType.Headset).ToList(); + + _logger.Info("Intialized DeviceManager"); + } + + public List HeadsetProviders { get; set; } + + public List MiceProviders { get; set; } + + [Inject] + public MetroDialogService DialogService { get; set; } + + public List KeyboardProviders { get; set; } + + public KeyboardProvider ActiveKeyboard { get; set; } + + public bool ChangingKeyboard { get; private set; } + + /// + /// Enables the last keyboard according to the settings file + /// + public void EnableLastKeyboard() + { + _logger.Debug("Getting last keyboard: {0}", General.Default.LastKeyboard); + if (string.IsNullOrEmpty(General.Default.LastKeyboard)) + return; + + var keyboard = KeyboardProviders.FirstOrDefault(k => k.Name == General.Default.LastKeyboard); + EnableKeyboard(keyboard); + } + + /// + /// Enables the given keyboard + /// + /// + public void EnableKeyboard(KeyboardProvider keyboardProvider) + { + lock (this) + { + ChangingKeyboard = true; + + if (keyboardProvider == null) + throw new ArgumentNullException(nameof(keyboardProvider)); + + if (ActiveKeyboard?.Name == keyboardProvider.Name) + { + ChangingKeyboard = false; + return; + } + + // Store the old keyboard so it can be used in the event we're raising later + var oldKeyboard = ActiveKeyboard; + + var wasNull = false; + if (ActiveKeyboard == null) + { + wasNull = true; + ActiveKeyboard = keyboardProvider; + } + + _logger.Debug("Enabling keyboard: {0}", keyboardProvider.Name); + + if (!wasNull) + ReleaseActiveKeyboard(); + + // Disable everything if there's no active keyboard found + if (!keyboardProvider.CanEnable()) + { + DialogService.ShowErrorMessageBox(keyboardProvider.CantEnableText); + ActiveKeyboard = null; + General.Default.LastKeyboard = null; + General.Default.Save(); + _logger.Warn("Failed enabling keyboard: {0}", keyboardProvider.Name); + ChangingKeyboard = false; + return; + } + + ActiveKeyboard = keyboardProvider; + ActiveKeyboard.Enable(); + + General.Default.LastKeyboard = ActiveKeyboard.Name; + General.Default.Save(); + + EnableUsableDevices(); + + ChangingKeyboard = false; + _events.PublishOnUIThread(new ActiveKeyboardChanged(oldKeyboard, ActiveKeyboard)); + _logger.Debug("Enabled keyboard: {0}", keyboardProvider.Name); + } + } + + private void EnableUsableDevices() + { + foreach (var mouseProvider in MiceProviders) + mouseProvider.TryEnable(); + foreach (var headsetProvider in HeadsetProviders) + headsetProvider.TryEnable(); + } + + /// + /// Releases the active keyboard + /// + /// Whether to save the LastKeyboard (making it null) + public void ReleaseActiveKeyboard(bool save = false) + { + lock (this) + { + if (ActiveKeyboard == null) + return; + + // Store the old keyboard so it can be used in the event we're raising later + var oldKeyboard = ActiveKeyboard; + + var releaseName = ActiveKeyboard.Name; + ActiveKeyboard.Disable(); + ActiveKeyboard = null; + + if (save) + { + General.Default.LastKeyboard = null; + General.Default.Save(); + } + + _events.PublishOnUIThread(new ActiveKeyboardChanged(oldKeyboard, null)); + _logger.Debug("Released keyboard: {0}", releaseName); + } + } + } } \ No newline at end of file diff --git a/Artemis/Artemis/Managers/EffectManager.cs b/Artemis/Artemis/Managers/EffectManager.cs index 1bf8d8bb1..3ada533c2 100644 --- a/Artemis/Artemis/Managers/EffectManager.cs +++ b/Artemis/Artemis/Managers/EffectManager.cs @@ -16,17 +16,17 @@ namespace Artemis.Managers public class EffectManager { private readonly IEventAggregator _events; - private readonly KeyboardManager _keyboardManager; + private readonly DeviceManager _deviceManager; private readonly ILogger _logger; private EffectModel _activeEffect; - public EffectManager(ILogger logger, IEventAggregator events, KeyboardManager keyboardManager) + public EffectManager(ILogger logger, IEventAggregator events, DeviceManager deviceManager) { _logger = logger; _logger.Info("Intializing EffectManager"); _events = events; - _keyboardManager = keyboardManager; + _deviceManager = deviceManager; EffectModels = new List(); @@ -90,10 +90,10 @@ namespace Artemis.Managers if (effectModel is OverlayModel) throw new ArgumentException("Can't set an Overlay effect as the active effect"); - if (_keyboardManager.ActiveKeyboard == null) - _keyboardManager.EnableLastKeyboard(); + if (_deviceManager.ActiveKeyboard == null) + _deviceManager.EnableLastKeyboard(); // If still null, no last keyboard, so stop. - if (_keyboardManager.ActiveKeyboard == null) + if (_deviceManager.ActiveKeyboard == null) { _logger.Debug("Cancelling effect change, no LastKeyboard"); return; diff --git a/Artemis/Artemis/Managers/LoopManager.cs b/Artemis/Artemis/Managers/LoopManager.cs index f0e892a64..135e8a0db 100644 --- a/Artemis/Artemis/Managers/LoopManager.cs +++ b/Artemis/Artemis/Managers/LoopManager.cs @@ -1,5 +1,6 @@ using System; using System.Drawing; +using System.Linq; using System.Timers; using Artemis.Events; using Caliburn.Micro; @@ -14,17 +15,17 @@ namespace Artemis.Managers { private readonly EffectManager _effectManager; private readonly IEventAggregator _events; - private readonly KeyboardManager _keyboardManager; + private readonly DeviceManager _deviceManager; private readonly ILogger _logger; private readonly Timer _loopTimer; public LoopManager(ILogger logger, IEventAggregator events, EffectManager effectManager, - KeyboardManager keyboardManager) + DeviceManager deviceManager) { _logger = logger; _events = events; _effectManager = effectManager; - _keyboardManager = keyboardManager; + _deviceManager = deviceManager; _loopTimer = new Timer(40); _loopTimer.Elapsed += Render; @@ -49,10 +50,10 @@ namespace Artemis.Managers _logger.Debug("Starting LoopManager"); - if (_keyboardManager.ActiveKeyboard == null) - _keyboardManager.EnableLastKeyboard(); + if (_deviceManager.ActiveKeyboard == null) + _deviceManager.EnableLastKeyboard(); // If still null, no last keyboard, so stop. - if (_keyboardManager.ActiveKeyboard == null) + if (_deviceManager.ActiveKeyboard == null) { _logger.Debug("Cancel LoopManager start, no keyboard"); return; @@ -80,7 +81,7 @@ namespace Artemis.Managers _logger.Debug("Stopping LoopManager"); Running = false; - _keyboardManager.ReleaseActiveKeyboard(); + _deviceManager.ReleaseActiveKeyboard(); } private void Render(object sender, ElapsedEventArgs e) @@ -97,18 +98,18 @@ namespace Artemis.Managers } var renderEffect = _effectManager.ActiveEffect; - if (_keyboardManager.ChangingKeyboard) + if (_deviceManager.ChangingKeyboard) return; // Stop if no active keyboard - if (_keyboardManager.ActiveKeyboard == null) + if (_deviceManager.ActiveKeyboard == null) { _logger.Debug("No active keyboard, stopping"); Stop(); return; } - lock (_keyboardManager.ActiveKeyboard) + lock (_deviceManager.ActiveKeyboard) { // Skip frame if effect is still initializing if (renderEffect.Initialized == false) @@ -146,7 +147,12 @@ namespace Artemis.Managers bitmap = fixedBmp; // If it exists, send bitmap to the device - _keyboardManager.ActiveKeyboard?.DrawBitmap(bitmap); + _deviceManager.ActiveKeyboard?.DrawBitmap(bitmap); + + foreach (var mouse in _deviceManager.MiceProviders.Where(m => m.CanUse)) + mouse.UpdateDevice(renderEffect.GenerateMouseBrush()); + foreach (var headset in _deviceManager.HeadsetProviders.Where(h => h.CanUse)) + headset.UpdateDevice(renderEffect.GenerateHeadsetBrush()); // debugging TODO: Disable when window isn't shown (in Debug VM, or get rid of it, w/e) _events.PublishOnUIThread(new ChangeBitmap(bitmap)); diff --git a/Artemis/Artemis/Managers/MainManager.cs b/Artemis/Artemis/Managers/MainManager.cs index 096dd18f7..e1be2e03b 100644 --- a/Artemis/Artemis/Managers/MainManager.cs +++ b/Artemis/Artemis/Managers/MainManager.cs @@ -27,11 +27,11 @@ namespace Artemis.Managers private readonly Timer _processTimer; public MainManager(IEventAggregator events, ILogger logger, LoopManager loopManager, - KeyboardManager keyboardManager, EffectManager effectManager, ProfileManager profileManager) + DeviceManager deviceManager, EffectManager effectManager, ProfileManager profileManager) { _logger = logger; LoopManager = loopManager; - KeyboardManager = keyboardManager; + DeviceManager = deviceManager; EffectManager = effectManager; ProfileManager = profileManager; @@ -63,7 +63,7 @@ namespace Artemis.Managers public Lazy ShellViewModel { get; set; } public LoopManager LoopManager { get; } - public KeyboardManager KeyboardManager { get; set; } + public DeviceManager DeviceManager { get; set; } public EffectManager EffectManager { get; set; } public ProfileManager ProfileManager { get; set; } diff --git a/Artemis/Artemis/Managers/ProfileManager.cs b/Artemis/Artemis/Managers/ProfileManager.cs index 9191edec2..e873f84f1 100644 --- a/Artemis/Artemis/Managers/ProfileManager.cs +++ b/Artemis/Artemis/Managers/ProfileManager.cs @@ -11,16 +11,16 @@ namespace Artemis.Managers public class ProfileManager { private readonly EffectManager _effectManager; - private readonly KeyboardManager _keyboardManager; + private readonly DeviceManager _deviceManager; private readonly LoopManager _loopManager; private readonly ILogger _logger; private EffectModel _prePreviewEffect; - public ProfileManager(ILogger logger, EffectManager effectManager, KeyboardManager keyboardManager, LoopManager loopManager) + public ProfileManager(ILogger logger, EffectManager effectManager, DeviceManager deviceManager, LoopManager loopManager) { _logger = logger; _effectManager = effectManager; - _keyboardManager = keyboardManager; + _deviceManager = deviceManager; _loopManager = loopManager; GameViewModels = new List(); @@ -41,7 +41,7 @@ namespace Artemis.Managers /// private void SetupProfilePreview(object sender, ElapsedEventArgs e) { - if (_keyboardManager.ChangingKeyboard || ProfilePreviewModel == null) + if (_deviceManager.ChangingKeyboard || ProfilePreviewModel == null) return; var activePreview = GameViewModels.FirstOrDefault(vm => vm.IsActive); diff --git a/Artemis/Artemis/Models/EffectModel.cs b/Artemis/Artemis/Models/EffectModel.cs index f4d0b12ee..b7a1a25fc 100644 --- a/Artemis/Artemis/Models/EffectModel.cs +++ b/Artemis/Artemis/Models/EffectModel.cs @@ -1,6 +1,7 @@ using System; using System.Drawing; using Artemis.Managers; +using Brush = System.Windows.Media.Brush; namespace Artemis.Models { @@ -27,5 +28,8 @@ namespace Artemis.Models // Called after every update public abstract Bitmap GenerateBitmap(); + + public abstract Brush GenerateMouseBrush(); + public abstract Brush GenerateHeadsetBrush(); } } \ No newline at end of file diff --git a/Artemis/Artemis/Models/Profiles/LayerModel.cs b/Artemis/Artemis/Models/Profiles/LayerModel.cs index 61aaf2143..8e8688472 100644 --- a/Artemis/Artemis/Models/Profiles/LayerModel.cs +++ b/Artemis/Artemis/Models/Profiles/LayerModel.cs @@ -65,21 +65,59 @@ namespace Artemis.Models.Profiles (KeyboardPropertiesModel) appliedProperties); } - // Folders are drawn recursively - if (LayerType == LayerType.Folder) + switch (LayerType) { - foreach (var layerModel in Children.OrderByDescending(l => l.Order)) - layerModel.Draw(dataModel, c, preview, updateAnimations); + // Folders are drawn recursively + case LayerType.Folder: + foreach (var layerModel in Children.OrderByDescending(l => l.Order)) + layerModel.Draw(dataModel, c, preview, updateAnimations); + break; + case LayerType.Keyboard: + Drawer.Draw(c, (KeyboardPropertiesModel) Properties, (KeyboardPropertiesModel) appliedProperties); + break; + case LayerType.KeyboardGif: + GifImage = Drawer.DrawGif(c, (KeyboardPropertiesModel) appliedProperties, GifImage); + break; } - // All other types are handles by the Drawer helper - else if (LayerType == LayerType.Keyboard) - Drawer.Draw(c, (KeyboardPropertiesModel) Properties, (KeyboardPropertiesModel) appliedProperties); - else if (LayerType == LayerType.KeyboardGif) - GifImage = Drawer.DrawGif(c, (KeyboardPropertiesModel) appliedProperties, GifImage); - else if (LayerType == LayerType.Mouse) - Drawer.UpdateMouse(appliedProperties); - else if (LayerType == LayerType.Headset) - Drawer.UpdateHeadset(appliedProperties); + } + + public Brush GenerateBrush(LayerType type, IGameDataModel dataModel, bool preview, bool updateAnimations) + { + if (!Enabled) + return null; + if (LayerType != LayerType.Folder && LayerType != type) + return null; + + // Preview simply shows the properties as they are. When not previewing they are applied + LayerPropertiesModel appliedProperties; + if (!preview) + { + if (!ConditionsMet(dataModel)) + return null; // Don't return the brush when not previewing and the conditions arent met + appliedProperties = Properties.Brush.Dispatcher.Invoke(() => Properties.GetAppliedProperties(dataModel)); + } + else + appliedProperties = Properties.Brush.Dispatcher.Invoke(() => GeneralHelpers.Clone(Properties)); + + // TODO: Animations + // Update animations on layer types that support them + //if (LayerType != LayerType.Folder && updateAnimations) + //{ + // AnimationUpdater.UpdateAnimation((KeyboardPropertiesModel)Properties, + // (KeyboardPropertiesModel)appliedProperties); + //} + + if (LayerType != LayerType.Folder) + return appliedProperties.Brush; + + Brush res = null; + foreach (var layerModel in Children.OrderByDescending(l => l.Order)) + { + var brush = layerModel.GenerateBrush(type, dataModel, preview, updateAnimations); + if (brush != null) + res = brush; + } + return res; } public void SetupProperties() @@ -99,9 +137,15 @@ namespace Artemis.Models.Profiles }; } else if (LayerType == LayerType.Mouse && !(Properties is MousePropertiesModel)) - Properties = new MousePropertiesModel(); - else if (!(Properties is GenericPropertiesModel)) - Properties = new GenericPropertiesModel(); + Properties = new MousePropertiesModel + { + Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()) + }; + else if (LayerType == LayerType.Headset && !(Properties is HeadsetPropertiesModel)) + Properties = new HeadsetPropertiesModel + { + Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()) + }; } public void Reorder(LayerModel selectedLayer, bool moveUp) @@ -131,7 +175,7 @@ namespace Artemis.Models.Profiles } /// - /// Returns whether the layer meets the requirements to be drawn + /// Returns whether the layer meets the requirements to be drawn /// /// public bool MustDraw() diff --git a/Artemis/Artemis/Models/Profiles/ProfileModel.cs b/Artemis/Artemis/Models/Profiles/ProfileModel.cs index 8a6b88fc1..5f2dea312 100644 --- a/Artemis/Artemis/Models/Profiles/ProfileModel.cs +++ b/Artemis/Artemis/Models/Profiles/ProfileModel.cs @@ -7,6 +7,7 @@ using Artemis.Models.Interfaces; using Artemis.Models.Profiles.Properties; using Artemis.Utilities; using Artemis.Utilities.ParentChild; +using Brush = System.Windows.Media.Brush; using Color = System.Windows.Media.Color; namespace Artemis.Models.Profiles @@ -113,7 +114,7 @@ namespace Artemis.Models.Profiles public Bitmap GenerateBitmap(Rect keyboardRect, IGameDataModel gameDataModel, bool preview, bool updateAnimations) { Bitmap bitmap = null; - DrawingVisual.Dispatcher.Invoke(delegate + DrawingVisual.Dispatcher.Invoke(() => { var visual = new DrawingVisual(); using (var c = visual.RenderOpen()) @@ -134,5 +135,19 @@ namespace Artemis.Models.Profiles }); return bitmap; } + + public Brush GenerateBrush(IGameDataModel gameDataModel, LayerType type, bool preview, bool updateAnimations) + { + Brush result = null; + // Draw the layers + foreach (var layerModel in Layers.OrderByDescending(l => l.Order)) + { + var generated = layerModel.GenerateBrush(type, gameDataModel, preview, updateAnimations); + if (generated != null) + result = generated; + } + + return result; + } } } \ No newline at end of file diff --git a/Artemis/Artemis/Models/Profiles/Properties/HeadsetPropertiesModel.cs b/Artemis/Artemis/Models/Profiles/Properties/HeadsetPropertiesModel.cs new file mode 100644 index 000000000..79093aa2f --- /dev/null +++ b/Artemis/Artemis/Models/Profiles/Properties/HeadsetPropertiesModel.cs @@ -0,0 +1,14 @@ +using Artemis.Models.Interfaces; +using Artemis.Utilities; + +namespace Artemis.Models.Profiles.Properties +{ + public class HeadsetPropertiesModel : LayerPropertiesModel + { + public override LayerPropertiesModel GetAppliedProperties(IGameDataModel dataModel) + { + // TODO: Apply any properties, if applicable to headsets in the first place. + return GeneralHelpers.Clone(this); + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Models/Profiles/Properties/LayerPropertiesModel.cs b/Artemis/Artemis/Models/Profiles/Properties/LayerPropertiesModel.cs index 5e09bcc17..3bf897a0f 100644 --- a/Artemis/Artemis/Models/Profiles/Properties/LayerPropertiesModel.cs +++ b/Artemis/Artemis/Models/Profiles/Properties/LayerPropertiesModel.cs @@ -11,6 +11,8 @@ namespace Artemis.Models.Profiles.Properties [XmlInclude(typeof(MatrixTransform))] [XmlInclude(typeof(KeyboardPropertiesModel))] [XmlInclude(typeof(MousePropertiesModel))] + [XmlInclude(typeof(HeadsetPropertiesModel))] + [XmlInclude(typeof(GenericPropertiesModel))] public abstract class LayerPropertiesModel { protected LayerPropertiesModel() diff --git a/Artemis/Artemis/Modules/Effects/AmbientLightning/AmbientLightningEffectModel.cs b/Artemis/Artemis/Modules/Effects/AmbientLightning/AmbientLightningEffectModel.cs index 27140f257..3b6619e88 100644 --- a/Artemis/Artemis/Modules/Effects/AmbientLightning/AmbientLightningEffectModel.cs +++ b/Artemis/Artemis/Modules/Effects/AmbientLightning/AmbientLightningEffectModel.cs @@ -9,6 +9,7 @@ using Artemis.Models; using Artemis.Utilities.Keyboard; using Kaliko.ImageLibrary; using Kaliko.ImageLibrary.Filters; +using Brush = System.Windows.Media.Brush; namespace Artemis.Modules.Effects.AmbientLightning { @@ -49,9 +50,9 @@ namespace Artemis.Modules.Effects.AmbientLightning _colors = new List(); _screenCapturer = new ScreenCapture(); - _topRect = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard, 0, 0, new List(), - LinearGradientMode.Horizontal) {Height = MainManager.KeyboardManager.ActiveKeyboard.Height*Scale/2}; - _botRect = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard, 0, 0, new List(), + _topRect = new KeyboardRectangle(MainManager.DeviceManager.ActiveKeyboard, 0, 0, new List(), + LinearGradientMode.Horizontal) {Height = MainManager.DeviceManager.ActiveKeyboard.Height*Scale/2}; + _botRect = new KeyboardRectangle(MainManager.DeviceManager.ActiveKeyboard, 0, 0, new List(), LinearGradientMode.Horizontal); Initialized = true; @@ -102,8 +103,8 @@ namespace Artemis.Modules.Effects.AmbientLightning } // Put the resulting colors in 6 rectangles, their size differs per keyboard - var rectWidth = MainManager.KeyboardManager.ActiveKeyboard.Width/3*Scale; - var rectHeight = MainManager.KeyboardManager.ActiveKeyboard.Height/2*Scale; + var rectWidth = MainManager.DeviceManager.ActiveKeyboard.Width/3*Scale; + var rectHeight = MainManager.DeviceManager.ActiveKeyboard.Height/2*Scale; for (var row = 0; row < 2; row++) { for (var column = 0; column < 3; column++) @@ -116,7 +117,7 @@ namespace Artemis.Modules.Effects.AmbientLightning public override Bitmap GenerateBitmap() { - var bitmap = MainManager.KeyboardManager.ActiveKeyboard.KeyboardBitmap(Scale); + var bitmap = MainManager.DeviceManager.ActiveKeyboard.KeyboardBitmap(Scale); using (var g = Graphics.FromImage(bitmap)) { var i = 0; @@ -134,5 +135,15 @@ namespace Artemis.Modules.Effects.AmbientLightning ms.Position = 0; return new Bitmap(ms); } + + public override Brush GenerateMouseBrush() + { + return null; + } + + public override Brush GenerateHeadsetBrush() + { + return null; + } } } \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualizerModel.cs b/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualizerModel.cs index db31d2341..bfb24e741 100644 --- a/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualizerModel.cs +++ b/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualizerModel.cs @@ -10,6 +10,7 @@ using Artemis.Utilities; using Artemis.Utilities.Keyboard; using NAudio.CoreAudioApi; using NAudio.Wave; +using Brush = System.Windows.Media.Brush; namespace Artemis.Modules.Effects.AudioVisualizer { @@ -57,7 +58,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer public override void Enable() { Initialized = false; - Lines = MainManager.KeyboardManager.ActiveKeyboard.Width; + Lines = MainManager.DeviceManager.ActiveKeyboard.Width; // TODO: Device selection SelectedDeviceId = new MMDeviceEnumerator() @@ -69,7 +70,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer for (var i = 0; i < Lines; i++) { SoundRectangles.Add(new KeyboardRectangle( - MainManager.KeyboardManager.ActiveKeyboard, + MainManager.DeviceManager.ActiveKeyboard, 0, 0, new List { ColorHelpers.ToDrawingColor(Settings.TopColor), @@ -121,7 +122,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer // Apply Sensitivity setting height = height*_sensitivity; var keyboardHeight = - (int) Math.Round(MainManager.KeyboardManager.ActiveKeyboard.Height/100.00*height*Scale); + (int) Math.Round(MainManager.DeviceManager.ActiveKeyboard.Height/100.00*height*Scale); if (keyboardHeight > SoundRectangles[i].Height) SoundRectangles[i].Height = keyboardHeight; else @@ -131,7 +132,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer SoundRectangles[i].Width = Scale; if (_fromBottom) - SoundRectangles[i].Y = MainManager.KeyboardManager.ActiveKeyboard.Height*Scale - + SoundRectangles[i].Y = MainManager.DeviceManager.ActiveKeyboard.Height*Scale - SoundRectangles[i].Height; } _generating = false; @@ -145,7 +146,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer // Lock the _spectrumData array while busy with it _generating = true; - var bitmap = MainManager.KeyboardManager.ActiveKeyboard.KeyboardBitmap(Scale); + var bitmap = MainManager.DeviceManager.ActiveKeyboard.KeyboardBitmap(Scale); using (var g = Graphics.FromImage(bitmap)) { foreach (var soundRectangle in SoundRectangles) @@ -156,6 +157,18 @@ namespace Artemis.Modules.Effects.AudioVisualizer return bitmap; } + // TODO: Brush according to avg volume + public override Brush GenerateMouseBrush() + { + return null; + } + + // TODO: Brush according to avg volume left/right + public override Brush GenerateHeadsetBrush() + { + return null; + } + private void OnDataAvailable(object sender, WaveInEventArgs e) { var buffer = e.Buffer; diff --git a/Artemis/Artemis/Modules/Effects/Debug/DebugEffectModel.cs b/Artemis/Artemis/Modules/Effects/Debug/DebugEffectModel.cs index 317b99b53..c68bd1199 100644 --- a/Artemis/Artemis/Modules/Effects/Debug/DebugEffectModel.cs +++ b/Artemis/Artemis/Modules/Effects/Debug/DebugEffectModel.cs @@ -4,6 +4,7 @@ using System.Drawing.Drawing2D; using Artemis.Managers; using Artemis.Models; using Artemis.Utilities.Keyboard; +using Brush = System.Windows.Media.Brush; namespace Artemis.Modules.Effects.Debug { @@ -33,7 +34,7 @@ namespace Artemis.Modules.Effects.Debug { Initialized = false; - KeyboardRectangle = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard, 0, 0, new List + KeyboardRectangle = new KeyboardRectangle(MainManager.DeviceManager.ActiveKeyboard, 0, 0, new List { Color.FromArgb(0, 226, 190), Color.FromArgb(0, 208, 255) @@ -63,5 +64,15 @@ namespace Artemis.Modules.Effects.Debug } return bitmap; } + + public override Brush GenerateMouseBrush() + { + return null; + } + + public override Brush GenerateHeadsetBrush() + { + return null; + } } } \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs b/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs index a4b29ea0d..1bb6a0fe7 100644 --- a/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs +++ b/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs @@ -3,6 +3,7 @@ using Artemis.Managers; using Artemis.Models; using Artemis.Models.Interfaces; using Artemis.Models.Profiles; +using Brush = System.Windows.Media.Brush; namespace Artemis.Modules.Effects.ProfilePreview { @@ -35,13 +36,15 @@ namespace Artemis.Modules.Effects.ProfilePreview public override Bitmap GenerateBitmap() { - var bitmap = MainManager.KeyboardManager.ActiveKeyboard.KeyboardBitmap(4); + var bitmap = MainManager.DeviceManager.ActiveKeyboard.KeyboardBitmap(4); if (SelectedProfile == null) return bitmap; - var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(4); + var keyboardRect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(4); var image = SelectedProfile.GenerateBitmap(keyboardRect, _previewDataModel, true, true); + if (image == null) + return null; // Draw on top of everything else using (var g = Graphics.FromImage(bitmap)) @@ -49,6 +52,16 @@ namespace Artemis.Modules.Effects.ProfilePreview return bitmap; } + + public override Brush GenerateMouseBrush() + { + return SelectedProfile?.GenerateBrush(_previewDataModel, LayerType.Mouse, true, true); + } + + public override Brush GenerateHeadsetBrush() + { + return SelectedProfile?.GenerateBrush(_previewDataModel, LayerType.Headset, true, true); + } } public class ProfilePreviewDataModel : IGameDataModel diff --git a/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveModel.cs b/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveModel.cs index fdafa0eb5..6284fb5ca 100644 --- a/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveModel.cs +++ b/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveModel.cs @@ -8,6 +8,7 @@ using Artemis.DeviceProviders.Logitech.Utilities; using Artemis.Managers; using Artemis.Models; using Artemis.Utilities; +using Brush = System.Windows.Media.Brush; namespace Artemis.Modules.Effects.TypeWave { @@ -96,7 +97,7 @@ namespace Artemis.Modules.Effects.TypeWave if (_waves.Count == 0) return null; - var bitmap = MainManager.KeyboardManager.ActiveKeyboard.KeyboardBitmap(Scale); + var bitmap = MainManager.DeviceManager.ActiveKeyboard.KeyboardBitmap(Scale); using (var g = Graphics.FromImage(bitmap)) { g.Clear(Color.Transparent); @@ -113,7 +114,7 @@ namespace Artemis.Modules.Effects.TypeWave _waves[i].Size, _waves[i].Size); Color fillColor; - if (MainManager.KeyboardManager.ActiveKeyboard is CorsairRGB) + if (MainManager.DeviceManager.ActiveKeyboard is CorsairRGB) fillColor = Color.Black; else fillColor = Color.Transparent; @@ -134,6 +135,16 @@ namespace Artemis.Modules.Effects.TypeWave } return bitmap; } + + public override Brush GenerateMouseBrush() + { + return null; + } + + public override Brush GenerateHeadsetBrush() + { + return null; + } } public class Wave diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs index bb3daccf9..3f35e0d26 100644 --- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs +++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs @@ -2,9 +2,11 @@ using System.Drawing; using Artemis.Managers; using Artemis.Models; +using Artemis.Models.Profiles; using Artemis.Utilities.GameState; using Newtonsoft.Json; using Ninject.Extensions.Logging; +using Brush = System.Windows.Media.Brush; namespace Artemis.Modules.Games.CounterStrike { @@ -47,10 +49,20 @@ namespace Artemis.Modules.Games.CounterStrike if (Profile == null || GameDataModel == null) return null; - var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(Scale); + var keyboardRect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(Scale); return Profile.GenerateBitmap(keyboardRect, GameDataModel, false, true); } + public override Brush GenerateMouseBrush() + { + return Profile.GenerateBrush(GameDataModel, LayerType.Mouse, false, true); + } + + public override Brush GenerateHeadsetBrush() + { + return Profile.GenerateBrush(GameDataModel, LayerType.Headset, false, true); + } + public void HandleGameData(object sender, GameDataReceivedEventArgs e) { var jsonString = e.Json.ToString(); diff --git a/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs b/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs index 0b1ed01d9..ef358c266 100644 --- a/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs +++ b/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs @@ -1,8 +1,10 @@ using System.Drawing; using Artemis.Managers; using Artemis.Models; +using Artemis.Models.Profiles; using Artemis.Utilities.GameState; using Newtonsoft.Json; +using Brush = System.Windows.Media.Brush; namespace Artemis.Modules.Games.Dota2 { @@ -61,10 +63,19 @@ namespace Artemis.Modules.Games.Dota2 if (Profile == null || GameDataModel == null) return null; - var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(Scale); + var keyboardRect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(Scale); return Profile.GenerateBitmap(keyboardRect, GameDataModel, false, true); } + public override Brush GenerateMouseBrush() + { + return Profile.GenerateBrush(GameDataModel, LayerType.Mouse, false, true); + } + + public override Brush GenerateHeadsetBrush() + { + return Profile.GenerateBrush(GameDataModel, LayerType.Headset, false, true); + } public void HandleGameData(object sender, GameDataReceivedEventArgs e) { diff --git a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs index 9c7c88704..97b1e4fac 100644 --- a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs +++ b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs @@ -3,10 +3,12 @@ using System.Drawing; using System.Linq; using Artemis.Managers; using Artemis.Models; +using Artemis.Models.Profiles; using Artemis.Settings; using Artemis.Utilities; using Artemis.Utilities.Memory; using Newtonsoft.Json; +using Brush = System.Windows.Media.Brush; namespace Artemis.Modules.Games.RocketLeague { @@ -72,8 +74,18 @@ namespace Artemis.Modules.Games.RocketLeague if (Profile == null || GameDataModel == null) return null; - var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(Scale); + var keyboardRect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(Scale); return Profile.GenerateBitmap(keyboardRect, GameDataModel, false, true); } + + public override Brush GenerateMouseBrush() + { + return Profile.GenerateBrush(GameDataModel, LayerType.Mouse, false, true); + } + + public override Brush GenerateHeadsetBrush() + { + return Profile.GenerateBrush(GameDataModel, LayerType.Headset, false, 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 fb6e44447..57f31896b 100644 --- a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs +++ b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs @@ -3,10 +3,12 @@ using System.Drawing; using System.Drawing.Drawing2D; using Artemis.Managers; using Artemis.Models; +using Artemis.Models.Profiles; using Artemis.Modules.Effects.TypeWave; using Artemis.Utilities; using Artemis.Utilities.Keyboard; using Artemis.Utilities.LogitechDll; +using Brush = System.Windows.Media.Brush; namespace Artemis.Modules.Games.TheDivision { @@ -46,7 +48,7 @@ namespace Artemis.Modules.Games.TheDivision Initialized = false; _ammoWave = new Wave(new Point(30, 14), 0, Color.Transparent); - _hpRect = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard, 3*Scale, 0*Scale, + _hpRect = new KeyboardRectangle(MainManager.DeviceManager.ActiveKeyboard, 3*Scale, 0*Scale, new List(), LinearGradientMode.Horizontal) { @@ -56,7 +58,7 @@ namespace Artemis.Modules.Games.TheDivision ContainedBrush = false }; - _p2 = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard, 0*Scale, 1*Scale, + _p2 = new KeyboardRectangle(MainManager.DeviceManager.ActiveKeyboard, 0*Scale, 1*Scale, new List(), LinearGradientMode.Horizontal) { @@ -65,7 +67,7 @@ namespace Artemis.Modules.Games.TheDivision Rotate = true, ContainedBrush = false }; - _p3 = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard, 0*Scale, 3*Scale, + _p3 = new KeyboardRectangle(MainManager.DeviceManager.ActiveKeyboard, 0*Scale, 3*Scale, new List(), LinearGradientMode.Horizontal) { @@ -74,7 +76,7 @@ namespace Artemis.Modules.Games.TheDivision Rotate = true, ContainedBrush = false }; - _p4 = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard, 0*Scale, 5*Scale, + _p4 = new KeyboardRectangle(MainManager.DeviceManager.ActiveKeyboard, 0*Scale, 5*Scale, new List(), LinearGradientMode.Horizontal) { @@ -204,7 +206,7 @@ namespace Artemis.Modules.Games.TheDivision public override Bitmap GenerateBitmap() { - var bitmap = MainManager.KeyboardManager.ActiveKeyboard.KeyboardBitmap(Scale); + var bitmap = MainManager.DeviceManager.ActiveKeyboard.KeyboardBitmap(Scale); using (var g = Graphics.FromImage(bitmap)) { g.Clear(Color.Transparent); @@ -239,5 +241,15 @@ namespace Artemis.Modules.Games.TheDivision } return bitmap; } + + public override Brush GenerateMouseBrush() + { + return Profile.GenerateBrush(GameDataModel, LayerType.Mouse, false, true); + } + + public override Brush GenerateHeadsetBrush() + { + return Profile.GenerateBrush(GameDataModel, LayerType.Headset, false, true); + } } } \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs index f37836a28..185c593ea 100644 --- a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs +++ b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs @@ -7,7 +7,9 @@ using System.IO; using System.Text.RegularExpressions; using Artemis.Managers; using Artemis.Models; +using Artemis.Models.Profiles; using Artemis.Utilities.Keyboard; +using Brush = System.Windows.Media.Brush; namespace Artemis.Modules.Games.Witcher3 { @@ -45,7 +47,7 @@ namespace Artemis.Modules.Games.Witcher3 { Initialized = false; - _signRect = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard, 0, 0, new List(), + _signRect = new KeyboardRectangle(MainManager.DeviceManager.ActiveKeyboard, 0, 0, new List(), LinearGradientMode.Horizontal) { Rotate = true, @@ -109,8 +111,18 @@ namespace Artemis.Modules.Games.Witcher3 if (Profile == null || GameDataModel == null) return null; - var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(Scale); + var keyboardRect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(Scale); return Profile.GenerateBitmap(keyboardRect, GameDataModel, false, true); } + + public override Brush GenerateMouseBrush() + { + return Profile.GenerateBrush(GameDataModel, LayerType.Mouse, false, true); + } + + public override Brush GenerateHeadsetBrush() + { + return Profile.GenerateBrush(GameDataModel, LayerType.Headset, false, true); + } } } \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplay.cs b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplay.cs index 94d59408c..699ddd6f5 100644 --- a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplay.cs +++ b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplay.cs @@ -9,11 +9,11 @@ namespace Artemis.Modules.Overlays.VolumeDisplay { public class VolumeBar { - private readonly KeyboardManager _keyboardManager; + private readonly DeviceManager _deviceManager; - public VolumeBar(KeyboardManager keyboardManager, VolumeDisplaySettings settings) + public VolumeBar(DeviceManager deviceManager, VolumeDisplaySettings settings) { - _keyboardManager = keyboardManager; + _deviceManager = deviceManager; Settings = settings; Transparancy = 255; Scale = 4; @@ -30,14 +30,14 @@ namespace Artemis.Modules.Overlays.VolumeDisplay public void Draw(Graphics g) { - var volumeRect = new KeyboardRectangle(_keyboardManager.ActiveKeyboard, 0, 0, new List + var volumeRect = new KeyboardRectangle(_deviceManager.ActiveKeyboard, 0, 0, new List { ColorHelpers.ToDrawingColor(Settings.MainColor), ColorHelpers.ToDrawingColor(Settings.SecondaryColor) }, LinearGradientMode.Horizontal) { - Width = (int) (_keyboardManager.ActiveKeyboard.Width*Scale/100.00*Volume), + Width = (int) (_deviceManager.ActiveKeyboard.Width*Scale/100.00*Volume), ContainedBrush = false }; volumeRect.Draw(g); diff --git a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs index 62a72dc0e..c7538681a 100644 --- a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs +++ b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs @@ -4,6 +4,7 @@ using System.Windows.Forms; using Artemis.Managers; using Artemis.Models; using NAudio.CoreAudioApi; +using Brush = System.Windows.Media.Brush; namespace Artemis.Modules.Overlays.VolumeDisplay { @@ -15,7 +16,7 @@ namespace Artemis.Modules.Overlays.VolumeDisplay Name = "VolumeDisplay"; Enabled = Settings.Enabled; - VolumeDisplay = new VolumeBar(MainManager.KeyboardManager, settings); + VolumeDisplay = new VolumeBar(MainManager.DeviceManager, settings); } public VolumeBar VolumeDisplay { get; set; } @@ -63,7 +64,19 @@ namespace Artemis.Modules.Overlays.VolumeDisplay public override Bitmap GenerateBitmap() { - return GenerateBitmap(MainManager.KeyboardManager.ActiveKeyboard.KeyboardBitmap(4)); + return GenerateBitmap(MainManager.DeviceManager.ActiveKeyboard.KeyboardBitmap(4)); + } + + // TODO: Color according to volume + public override Brush GenerateMouseBrush() + { + return null; + } + + // TODO: Color according to volume + public override Brush GenerateHeadsetBrush() + { + return null; } public override Bitmap GenerateBitmap(Bitmap bitmap) diff --git a/Artemis/Artemis/Utilities/ColorHelpers.cs b/Artemis/Artemis/Utilities/ColorHelpers.cs index bdefa0ec5..4d9741306 100644 --- a/Artemis/Artemis/Utilities/ColorHelpers.cs +++ b/Artemis/Artemis/Utilities/ColorHelpers.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; -using System.Drawing; using System.Linq; +using System.Windows.Media; +using Brush = System.Windows.Media.Brush; +using Color = System.Drawing.Color; namespace Artemis.Utilities { diff --git a/Artemis/Artemis/Utilities/Layers/Drawer.cs b/Artemis/Artemis/Utilities/Layers/Drawer.cs index 9438ba821..5460eb44d 100644 --- a/Artemis/Artemis/Utilities/Layers/Drawer.cs +++ b/Artemis/Artemis/Utilities/Layers/Drawer.cs @@ -81,6 +81,7 @@ namespace Artemis.Utilities.Layers c.PushClip(new RectangleGeometry(clip)); c.DrawRectangle(brush, null, slide1); c.DrawRectangle(brush, null, slide2); + c.Pop(); } c.Pop(); } diff --git a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs index c44dddb92..433fc4e54 100644 --- a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs +++ b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs @@ -49,7 +49,7 @@ namespace Artemis.ViewModels.Flyouts get { var collection = - new BindableCollection(MainManager.KeyboardManager.KeyboardProviders.Select(k => k.Name)); + new BindableCollection(MainManager.DeviceManager.KeyboardProviders.Select(k => k.Name)); collection.Insert(0, "None"); return collection; } @@ -111,15 +111,15 @@ namespace Artemis.ViewModels.Flyouts return; _logger.Debug("Handling SelectedKeyboard change in UI"); - var keyboard = MainManager.KeyboardManager.KeyboardProviders + var keyboard = MainManager.DeviceManager.KeyboardProviders .FirstOrDefault(k => k.Name == SelectedKeyboardProvider); if (keyboard != null) { - MainManager.KeyboardManager.EnableKeyboard(keyboard); + MainManager.DeviceManager.EnableKeyboard(keyboard); MainManager.LoopManager.Start(); } else - MainManager.KeyboardManager.ReleaseActiveKeyboard(true); + MainManager.DeviceManager.ReleaseActiveKeyboard(true); } public void ToggleEnabled() diff --git a/Artemis/Artemis/ViewModels/LayerEditor/HeadsetPropertiesViewModel.cs b/Artemis/Artemis/ViewModels/LayerEditor/HeadsetPropertiesViewModel.cs new file mode 100644 index 000000000..7460d8b98 --- /dev/null +++ b/Artemis/Artemis/ViewModels/LayerEditor/HeadsetPropertiesViewModel.cs @@ -0,0 +1,33 @@ +using Artemis.Models.Interfaces; +using Artemis.Models.Profiles.Properties; +using Artemis.Utilities; + +namespace Artemis.ViewModels.LayerEditor +{ + public class HeadsetPropertiesViewModel : LayerPropertiesViewModel + { + private LayerPropertiesModel _proposedProperties; + + public HeadsetPropertiesViewModel(IGameDataModel gameDataModel, LayerPropertiesModel properties) + : base(gameDataModel) + { + ProposedProperties = GeneralHelpers.Clone(properties); + } + + public LayerPropertiesModel ProposedProperties + { + get { return _proposedProperties; } + set + { + if (Equals(value, _proposedProperties)) return; + _proposedProperties = value; + NotifyOfPropertyChange(() => ProposedProperties); + } + } + + public override LayerPropertiesModel GetAppliedProperties() + { + return GeneralHelpers.Clone(ProposedProperties); + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/ViewModels/LayerEditor/LayerEditorViewModel.cs b/Artemis/Artemis/ViewModels/LayerEditor/LayerEditorViewModel.cs index 28a455bf1..3b59564ac 100644 --- a/Artemis/Artemis/ViewModels/LayerEditor/LayerEditorViewModel.cs +++ b/Artemis/Artemis/ViewModels/LayerEditor/LayerEditorViewModel.cs @@ -25,7 +25,6 @@ namespace Artemis.ViewModels.LayerEditor _gameDataModel = gameDataModel; Layer = layer; - if (Layer.Properties == null) Layer.SetupProperties(); @@ -108,7 +107,7 @@ namespace Artemis.ViewModels.LayerEditor public void PreSelect() { LayerType = Layer.LayerType; - GeneralHelpers.CopyProperties(ProposedProperties, Layer.Properties); + ProposedProperties = GeneralHelpers.Clone(Layer.Properties); } private void PropertiesViewModelHandler(object sender, PropertyChangedEventArgs e) @@ -138,7 +137,9 @@ namespace Artemis.ViewModels.LayerEditor }; } else if (LayerType == LayerType.Mouse && !(LayerPropertiesViewModel is MousePropertiesViewModel)) - LayerPropertiesViewModel = new MousePropertiesViewModel(_gameDataModel); + LayerPropertiesViewModel = new MousePropertiesViewModel(_gameDataModel, Layer.Properties); + else if (LayerType == LayerType.Headset && !(LayerPropertiesViewModel is HeadsetPropertiesViewModel)) + LayerPropertiesViewModel = new HeadsetPropertiesViewModel(_gameDataModel, Layer.Properties); NotifyOfPropertyChange(() => LayerPropertiesViewModel); } @@ -146,13 +147,15 @@ namespace Artemis.ViewModels.LayerEditor public void AddCondition() { var condition = new LayerConditionModel(); - Layer.Properties.Conditions.Add(condition); LayerConditionVms.Add(new LayerConditionViewModel(this, condition, DataModelProps)); } public void Apply() { Layer.Properties = LayerPropertiesViewModel.GetAppliedProperties(); + Layer.Properties.Conditions.Clear(); + foreach (var conditionViewModel in LayerConditionVms) + Layer.Properties.Conditions.Add(conditionViewModel.LayerConditionModel); if (Layer.LayerType != LayerType.KeyboardGif) return; // Don't bother checking for a GIF path unless the type is GIF diff --git a/Artemis/Artemis/ViewModels/LayerEditor/MousePropertiesViewModel.cs b/Artemis/Artemis/ViewModels/LayerEditor/MousePropertiesViewModel.cs index 66723b78e..950f0492a 100644 --- a/Artemis/Artemis/ViewModels/LayerEditor/MousePropertiesViewModel.cs +++ b/Artemis/Artemis/ViewModels/LayerEditor/MousePropertiesViewModel.cs @@ -1,17 +1,33 @@ using Artemis.Models.Interfaces; using Artemis.Models.Profiles.Properties; +using Artemis.Utilities; namespace Artemis.ViewModels.LayerEditor { public class MousePropertiesViewModel : LayerPropertiesViewModel { - public MousePropertiesViewModel(IGameDataModel gameDataModel) : base(gameDataModel) + private LayerPropertiesModel _proposedProperties; + + public MousePropertiesViewModel(IGameDataModel gameDataModel, LayerPropertiesModel properties) + : base(gameDataModel) { + ProposedProperties = GeneralHelpers.Clone(properties); + } + + public LayerPropertiesModel ProposedProperties + { + get { return _proposedProperties; } + set + { + if (Equals(value, _proposedProperties)) return; + _proposedProperties = value; + NotifyOfPropertyChange(() => ProposedProperties); + } } public override LayerPropertiesModel GetAppliedProperties() { - return null; + return GeneralHelpers.Clone(ProposedProperties); } } } \ No newline at end of file diff --git a/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs b/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs index 1172b0d2d..5eada8599 100644 --- a/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs +++ b/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs @@ -47,7 +47,7 @@ namespace Artemis.ViewModels Profiles = new BindableCollection(); Layers = new BindableCollection(); - ActiveKeyboard = _mainManager.KeyboardManager.ActiveKeyboard; + ActiveKeyboard = _mainManager.DeviceManager.ActiveKeyboard; events.Subscribe(this); @@ -153,7 +153,7 @@ namespace Artemis.ViewModels /// public void Handle(ActiveKeyboardChanged message) { - ActiveKeyboard = _mainManager.KeyboardManager.ActiveKeyboard; + ActiveKeyboard = _mainManager.DeviceManager.ActiveKeyboard; NotifyOfPropertyChange(() => KeyboardImage); NotifyOfPropertyChange(() => PreviewSettings); LoadProfiles(); @@ -412,7 +412,7 @@ namespace Artemis.ViewModels private void InvokeUpdateKeyboardPreview(object sender, ElapsedEventArgs e) { - Application.Current.Dispatcher.Invoke(UpdateKeyboardPreview, DispatcherPriority.ContextIdle); + Application.Current.Dispatcher.InvokeAsync(UpdateKeyboardPreview, DispatcherPriority.ContextIdle); } /// diff --git a/Artemis/Artemis/Views/LayerEditor/HeadsetPropertiesView.xaml b/Artemis/Artemis/Views/LayerEditor/HeadsetPropertiesView.xaml new file mode 100644 index 000000000..310df1999 --- /dev/null +++ b/Artemis/Artemis/Views/LayerEditor/HeadsetPropertiesView.xaml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/Artemis/Artemis/Views/LayerEditor/HeadsetPropertiesView.xaml.cs b/Artemis/Artemis/Views/LayerEditor/HeadsetPropertiesView.xaml.cs new file mode 100644 index 000000000..cfc76f9a0 --- /dev/null +++ b/Artemis/Artemis/Views/LayerEditor/HeadsetPropertiesView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Artemis.Views.LayerEditor +{ + /// + /// Interaction logic for HeadsetPropertiesView.xaml + /// + public partial class HeadsetPropertiesView : UserControl + { + public HeadsetPropertiesView() + { + InitializeComponent(); + } + } +} diff --git a/Artemis/Artemis/Views/LayerEditor/LayerEditorView.xaml b/Artemis/Artemis/Views/LayerEditor/LayerEditorView.xaml index 4bb89847f..20ee71098 100644 --- a/Artemis/Artemis/Views/LayerEditor/LayerEditorView.xaml +++ b/Artemis/Artemis/Views/LayerEditor/LayerEditorView.xaml @@ -9,8 +9,6 @@ mc:Ignorable="d" Title="Artemis | Edit Layer" Height="750" Width="630" xmlns:profileEnumerations="clr-namespace:Artemis.Models.Profiles" - xmlns:ncore="http://schemas.ncore.com/wpf/xaml/colorbox" - xmlns:properties="clr-namespace:Artemis.Models.Profiles.Properties" GlowBrush="{DynamicResource AccentColorBrush}" Icon="../../Resources/bow.png" ResizeMode="NoResize"> diff --git a/Artemis/Artemis/Views/LayerEditor/MousePropertiesView.xaml b/Artemis/Artemis/Views/LayerEditor/MousePropertiesView.xaml index 76df63320..5c309e3dd 100644 --- a/Artemis/Artemis/Views/LayerEditor/MousePropertiesView.xaml +++ b/Artemis/Artemis/Views/LayerEditor/MousePropertiesView.xaml @@ -2,11 +2,33 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:local="clr-namespace:Artemis.Views.LayerEditor" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:ncore="http://schemas.ncore.com/wpf/xaml/colorbox" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> - NYI + + + + + + + + + + + + + + + + + + diff --git a/Artemis/Artemis/Views/ProfileEditorView.xaml b/Artemis/Artemis/Views/ProfileEditorView.xaml index 619419283..a11c9f9c8 100644 --- a/Artemis/Artemis/Views/ProfileEditorView.xaml +++ b/Artemis/Artemis/Views/ProfileEditorView.xaml @@ -85,8 +85,7 @@ - +