diff --git a/Artemis/Artemis/App.config b/Artemis/Artemis/App.config index 9c4523b0b..9734b6d7c 100644 --- a/Artemis/Artemis/App.config +++ b/Artemis/Artemis/App.config @@ -2,50 +2,21 @@ - -
-
-
-
-
-
-
-
-
-
-
-
-
-
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -321,6 +292,10 @@ + + + + diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index 9f86bf865..b84e937a0 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -132,8 +132,8 @@ ..\packages\Caliburn.Micro.3.0.1\lib\net45\Caliburn.Micro.Platform.Core.dll True - - ..\packages\Castle.Core.3.2.0\lib\net45\Castle.Core.dll + + ..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll True diff --git a/Artemis/Artemis/InjectionModules/BaseModules.cs b/Artemis/Artemis/InjectionModules/BaseModules.cs index 145255a33..8e895bfb1 100644 --- a/Artemis/Artemis/InjectionModules/BaseModules.cs +++ b/Artemis/Artemis/InjectionModules/BaseModules.cs @@ -1,5 +1,6 @@ using Artemis.InjectionFactories; using Artemis.Modules.Effects.ProfilePreview; +using Artemis.Services; using Artemis.ViewModels; using Artemis.ViewModels.Abstract; using Caliburn.Micro; @@ -22,6 +23,9 @@ namespace Artemis.InjectionModules // Models Bind().ToSelf().InSingletonScope(); + + // Services + Bind().ToSelf().InSingletonScope(); } } } \ No newline at end of file diff --git a/Artemis/Artemis/KeyboardProviders/Corsair/CorsairRGB.cs b/Artemis/Artemis/KeyboardProviders/Corsair/CorsairRGB.cs index 8e451a9ca..a3a674566 100644 --- a/Artemis/Artemis/KeyboardProviders/Corsair/CorsairRGB.cs +++ b/Artemis/Artemis/KeyboardProviders/Corsair/CorsairRGB.cs @@ -21,7 +21,8 @@ namespace Artemis.KeyboardProviders.Corsair { Name = "Corsair RGB Keyboards"; CantEnableText = "Couldn't connect to your Corsair keyboard.\n" + - "Please check your cables and/or drivers (could be outdated) and that Corsair Utility Engine is running.\n\n" + + "Please check your cables and/or drivers (could be outdated) and that Corsair Utility Engine is running.\n" + + "In CUE, make sure \"Enable SDK\" is checked under Settings > Program.\n\n" + "If needed, you can select a different keyboard in Artemis under settings."; KeyboardRegions = new List(); } @@ -34,7 +35,8 @@ namespace Artemis.KeyboardProviders.Corsair { try { - CueSDK.Initialize(); + if (CueSDK.ProtocolDetails == null) + CueSDK.Initialize(); } catch (CUEException e) { @@ -64,7 +66,8 @@ namespace Artemis.KeyboardProviders.Corsair { try { - CueSDK.Initialize(); + if (CueSDK.ProtocolDetails == null) + CueSDK.Initialize(); } catch (WrapperException) { diff --git a/Artemis/Artemis/KeyboardProviders/KeyboardProvider.cs b/Artemis/Artemis/KeyboardProviders/KeyboardProvider.cs index 746163184..7917fa75c 100644 --- a/Artemis/Artemis/KeyboardProviders/KeyboardProvider.cs +++ b/Artemis/Artemis/KeyboardProviders/KeyboardProvider.cs @@ -17,7 +17,7 @@ namespace Artemis.KeyboardProviders public PreviewSettings PreviewSettings { get; set; } public abstract bool CanEnable(); - public abstract void Enable(); + 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); diff --git a/Artemis/Artemis/Managers/EffectManager.cs b/Artemis/Artemis/Managers/EffectManager.cs index a1688a6f1..43329a0c6 100644 --- a/Artemis/Artemis/Managers/EffectManager.cs +++ b/Artemis/Artemis/Managers/EffectManager.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Timers; using Artemis.Events; using Artemis.Models; using Artemis.Modules.Effects.ProfilePreview; using Artemis.Settings; using Caliburn.Micro; -using NLog; +using Ninject.Extensions.Logging; namespace Artemis.Managers { @@ -19,6 +20,7 @@ namespace Artemis.Managers private readonly KeyboardManager _keyboardManager; private readonly ILogger _logger; private EffectModel _activeEffect; + private EffectModel _prePreviewEffect; public EffectManager(IEventAggregator events, ILogger logger, KeyboardManager keyboardManager) { @@ -29,9 +31,16 @@ namespace Artemis.Managers _keyboardManager = keyboardManager; EffectModels = new List(); + + var profilePreviewTimer = new Timer(500); + profilePreviewTimer.Elapsed += SetupProfilePreview; + profilePreviewTimer.Start(); + _logger.Info("Intialized EffectManager"); } + public ProfilePreviewModel ProfilePreviewModel { get; set; } + /// /// Holds all the effects the program has /// @@ -63,6 +72,43 @@ namespace Artemis.Managers get { return EffectModels.OfType().Where(g => g.Enabled); } } + /// + /// Keeps track of profiles being previewed and sets up the active efffect accordingly + /// + /// + /// + private void SetupProfilePreview(object sender, ElapsedEventArgs e) + { + // Make sure the preview model should still be active + if (ActiveEffect is ProfilePreviewModel) + { + // Should not be active if no selected profile is set + if (ProfilePreviewModel.SelectedProfile != null) + return; + + if (_prePreviewEffect != null) + { + _logger.Debug("Change back effect after profile preview"); + ChangeEffect(_prePreviewEffect); + } + else + { + _logger.Debug("Clear effect after profile preview"); + ClearEffect(); // TODO: This fails to lock + } + } + // Else make sure preview model indeed shouldn't be active + else + { + if (ProfilePreviewModel?.SelectedProfile == null) + return; + + _prePreviewEffect = ActiveEffect; + _logger.Debug("Activate profile preview"); + ChangeEffect(ProfilePreviewModel); + } + } + /// /// Loads the last active effect from settings and enables it. /// @@ -87,26 +133,28 @@ 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(); - - lock (_keyboardManager.ActiveKeyboard) + lock (_keyboardManager) { - // Game models are only used if they are enabled - var gameModel = effectModel as GameModel; - if (gameModel != null) - if (!gameModel.Enabled) + lock (this) + { + if (_keyboardManager.ActiveKeyboard == null) + _keyboardManager.EnableLastKeyboard(); + // If still null, no last keyboard, so stop. + if (_keyboardManager.ActiveKeyboard == null) return; - var wasNull = false; - if (ActiveEffect == null) - { - wasNull = true; - ActiveEffect = effectModel; - } + // Game models are only used if they are enabled + var gameModel = effectModel as GameModel; + if (gameModel != null) + if (!gameModel.Enabled) + return; - lock (ActiveEffect) - { + var wasNull = false; + if (ActiveEffect == null) + { + wasNull = true; + ActiveEffect = effectModel; + } if (!wasNull) ActiveEffect.Dispose(); @@ -124,10 +172,11 @@ namespace Artemis.Managers if (loopManager != null && !loopManager.Running) { + _logger.Debug("Starting LoopManager for effect change"); loopManager.Start(); } - _logger.Debug($"Changed active effect to: {effectModel.Name}"); + _logger.Debug("Changed active effect to: {0}", effectModel.Name); } @@ -136,9 +185,9 @@ namespace Artemis.Managers /// public void ClearEffect() { - lock (_keyboardManager.ActiveKeyboard) + lock (_keyboardManager) { - lock (ActiveEffect) + lock (this) { ActiveEffect.Dispose(); ActiveEffect = null; @@ -157,7 +206,7 @@ namespace Artemis.Managers /// public void DisableGame(EffectModel activeEffect) { - _logger.Debug($"Disabling game: {activeEffect?.Name}"); + _logger.Debug("Disabling game: {0}", activeEffect?.Name); if (GetLastEffect() == null) ClearEffect(); else diff --git a/Artemis/Artemis/Managers/KeyboardManager.cs b/Artemis/Artemis/Managers/KeyboardManager.cs index f09bfb685..34542cd1c 100644 --- a/Artemis/Artemis/Managers/KeyboardManager.cs +++ b/Artemis/Artemis/Managers/KeyboardManager.cs @@ -3,9 +3,11 @@ using System.Collections.Generic; using System.Linq; using Artemis.Events; using Artemis.KeyboardProviders; +using Artemis.Services; using Artemis.Settings; using Caliburn.Micro; -using NLog; +using Ninject; +using Ninject.Extensions.Logging; namespace Artemis.Managers { @@ -29,6 +31,9 @@ namespace Artemis.Managers _logger.Info("Intialized KeyboardManager"); } + [Inject] + public MetroDialogService DialogService { get; set; } + public List KeyboardProviders { get; set; } public KeyboardProvider ActiveKeyboard @@ -47,7 +52,7 @@ namespace Artemis.Managers /// public void EnableLastKeyboard() { - _logger.Debug($"Enabling last keyboard: {General.Default.LastKeyboard}"); + _logger.Debug("Getting last keyboard: {0}", General.Default.LastKeyboard); if (string.IsNullOrEmpty(General.Default.LastKeyboard)) return; @@ -61,22 +66,22 @@ namespace Artemis.Managers /// public void EnableKeyboard(KeyboardProvider keyboardProvider) { - if (keyboardProvider == null) - throw new ArgumentNullException(nameof(keyboardProvider)); - - if (ActiveKeyboard?.Name == keyboardProvider.Name) - return; - - var wasNull = false; - if (ActiveKeyboard == null) + lock (this) { - wasNull = true; - ActiveKeyboard = keyboardProvider; - } + if (keyboardProvider == null) + throw new ArgumentNullException(nameof(keyboardProvider)); - lock (ActiveKeyboard) - { - _logger.Debug($"Enabling keyboard: {keyboardProvider.Name}"); + if (ActiveKeyboard?.Name == keyboardProvider.Name) + return; + + var wasNull = false; + if (ActiveKeyboard == null) + { + wasNull = true; + ActiveKeyboard = keyboardProvider; + } + + _logger.Debug("Enabling keyboard: {0}", keyboardProvider.Name); if (!wasNull) ReleaseActiveKeyboard(); @@ -84,9 +89,11 @@ namespace Artemis.Managers // Disable everything if there's no active keyboard found if (!keyboardProvider.CanEnable()) { - // TODO: MainManager.DialogService.ShowErrorMessageBox(keyboardProvider.CantEnableText); + DialogService.ShowErrorMessageBox(keyboardProvider.CantEnableText); + ActiveKeyboard = null; General.Default.LastKeyboard = null; General.Default.Save(); + _logger.Warn("Failed enabling keyboard: {0}", keyboardProvider.Name); return; } @@ -95,6 +102,7 @@ namespace Artemis.Managers General.Default.LastKeyboard = ActiveKeyboard.Name; General.Default.Save(); + _logger.Debug("Enabled keyboard: {0}", keyboardProvider.Name); } } @@ -103,16 +111,16 @@ namespace Artemis.Managers /// public void ReleaseActiveKeyboard() { - lock (ActiveKeyboard) + lock (this) { if (ActiveKeyboard == null) return; + var releaseName = ActiveKeyboard.Name; ActiveKeyboard.Disable(); ActiveKeyboard = null; + _logger.Debug("Released keyboard: {0}", releaseName); } - - _logger.Debug($"Released keyboard: {ActiveKeyboard?.Name}"); } } } \ No newline at end of file diff --git a/Artemis/Artemis/Managers/LoopManager.cs b/Artemis/Artemis/Managers/LoopManager.cs index 5e4e1e504..7d855ecd7 100644 --- a/Artemis/Artemis/Managers/LoopManager.cs +++ b/Artemis/Artemis/Managers/LoopManager.cs @@ -43,18 +43,29 @@ namespace Artemis.Managers public void Start() { + if (Running) + return; + _logger.Debug("Starting LoopManager"); if (_keyboardManager.ActiveKeyboard == null) _keyboardManager.EnableLastKeyboard(); + // If still null, no last keyboard, so stop. + if (_keyboardManager.ActiveKeyboard == null) + { + _logger.Debug("Cancel LoopManager start, no keyboard"); + return; + } // TODO: Deadlock maybe? I don't know what Resharper is on about if (_effectManager.ActiveEffect == null) { var lastEffect = _effectManager.GetLastEffect(); if (lastEffect == null) + { + _logger.Debug("Cancel LoopManager start, no effect"); return; - + } _effectManager.ChangeEffect(lastEffect); } @@ -63,6 +74,9 @@ namespace Artemis.Managers public void Stop() { + if (!Running) + return; + _logger.Debug("Stopping LoopManager"); Running = false; @@ -74,21 +88,26 @@ namespace Artemis.Managers if (!Running) return; - // Stop if no active keyboard/efffect - if (_keyboardManager.ActiveKeyboard == null || _effectManager.ActiveEffect == null) + // Stop if no active keyboard + if (_keyboardManager.ActiveKeyboard == null) { - _logger.Debug("No active keyboard/effect, stopping. " + - $"Keyboard={_keyboardManager.ActiveKeyboard?.Name}, " + - $"effect={_effectManager.ActiveEffect?.Name}"); + _logger.Debug("No active keyboard, stopping"); Stop(); return; } - // Lock both the active keyboard and active effect so they will not change while rendering. - lock (_keyboardManager.ActiveKeyboard) + lock (_keyboardManager) { - lock (_effectManager.ActiveEffect) + lock (_effectManager) { + // Stop if no active effect + if (_effectManager.ActiveEffect == null) + { + _logger.Debug("No active effect, stopping"); + Stop(); + return; + } + // Skip frame if effect is still initializing if (_effectManager.ActiveEffect.Initialized == false) return; @@ -102,16 +121,13 @@ namespace Artemis.Managers ? _effectManager.ActiveEffect.GenerateBitmap() : null; - lock (_effectManager.EnabledOverlays) + // Draw enabled overlays on top + foreach (var overlayModel in _effectManager.EnabledOverlays) { - // Draw enabled overlays on top - foreach (var overlayModel in _effectManager.EnabledOverlays) - { - overlayModel.Update(); - bitmap = bitmap != null - ? overlayModel.GenerateBitmap(bitmap) - : overlayModel.GenerateBitmap(); - } + overlayModel.Update(); + bitmap = bitmap != null + ? overlayModel.GenerateBitmap(bitmap) + : overlayModel.GenerateBitmap(); } if (bitmap == null) diff --git a/Artemis/Artemis/Managers/MainManager.cs b/Artemis/Artemis/Managers/MainManager.cs index 345063e8f..dbbdf7b8c 100644 --- a/Artemis/Artemis/Managers/MainManager.cs +++ b/Artemis/Artemis/Managers/MainManager.cs @@ -71,7 +71,6 @@ namespace Artemis.Managers public PipeServer PipeServer { get; set; } public BackgroundWorker ProcessWorker { get; set; } - public MetroDialogService DialogService { get; set; } public KeyboardHook KeyboardHook { get; set; } public GameStateWebServer GameStateWebServer { get; set; } public bool ProgramEnabled { get; private set; } diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs index deebbe23a..1ee23f942 100644 --- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs +++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs @@ -49,7 +49,7 @@ namespace Artemis.Modules.Games.CounterStrike return; } - MainManager.DialogService.ShowErrorMessageBox("Please select a valid CS:GO directory\n\n" + + DialogService.ShowErrorMessageBox("Please select a valid CS:GO directory\n\n" + @"By default CS:GO is in \SteamApps\common\Counter-Strike Global Offensive"); ((CounterStrikeSettings) GameSettings).GameDirectory = string.Empty; NotifyOfPropertyChange(() => GameSettings); diff --git a/Artemis/Artemis/Modules/Games/Dota2/Dota2ViewModel.cs b/Artemis/Artemis/Modules/Games/Dota2/Dota2ViewModel.cs index ee7b73d04..b7595c502 100644 --- a/Artemis/Artemis/Modules/Games/Dota2/Dota2ViewModel.cs +++ b/Artemis/Artemis/Modules/Games/Dota2/Dota2ViewModel.cs @@ -75,7 +75,7 @@ namespace Artemis.Modules.Games.Dota2 return; } - MainManager.DialogService.ShowErrorMessageBox("Please select a valid Dota 2 directory\n\n" + + DialogService.ShowErrorMessageBox("Please select a valid Dota 2 directory\n\n" + @"By default Dota 2 is in \SteamApps\common\dota 2 beta"); ((Dota2Settings) GameSettings).GameDirectory = string.Empty; NotifyOfPropertyChange(() => GameSettings); diff --git a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3ViewModel.cs b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3ViewModel.cs index bbb8df0a7..4e810b3df 100644 --- a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3ViewModel.cs +++ b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3ViewModel.cs @@ -38,7 +38,7 @@ namespace Artemis.Modules.Games.Witcher3 if (!File.Exists(dialog.SelectedPath + @"\bin\x64\witcher3.exe")) { var retry = await - MainManager.DialogService.ShowQuestionMessageBox("Installation error", + DialogService.ShowQuestionMessageBox("Installation error", "That's not a valid Witcher 3 directory\n\n" + "Default directories:\n" + "Steam: \\SteamApps\\common\\The Witcher 3\n" + @@ -61,7 +61,7 @@ namespace Artemis.Modules.Games.Witcher3 if (!file.Contains("modArtemis")) { var viewHelp = await - MainManager.DialogService.ShowQuestionMessageBox("Conflicting mod found", + DialogService.ShowQuestionMessageBox("Conflicting mod found", "Oh no, you have a conflicting mod!\n\n" + "Conflicting file: " + file.Remove(0, dialog.SelectedPath.Length) + "\n\nWould you like to view instructions on how to manually install the mod?"); @@ -104,7 +104,7 @@ namespace Artemis.Modules.Games.Witcher3 File.WriteAllText(dialog.SelectedPath + @"\mods\modArtemis\content\scripts\game\player\playerWitcher.ws", Resources.playerWitcherWs); - MainManager.DialogService.ShowMessageBox("Success", "The mod was successfully installed!"); + DialogService.ShowMessageBox("Success", "The mod was successfully installed!"); } } diff --git a/Artemis/Artemis/Services/MetroDialogService.cs b/Artemis/Artemis/Services/MetroDialogService.cs index 953a134ab..1f4a59c54 100644 --- a/Artemis/Artemis/Services/MetroDialogService.cs +++ b/Artemis/Artemis/Services/MetroDialogService.cs @@ -27,29 +27,20 @@ using Caliburn.Micro; using MahApps.Metro.Controls; using MahApps.Metro.Controls.Dialogs; using Microsoft.Win32; +using Ninject; namespace Artemis.Services { public class MetroDialogService : DialogService { - private readonly IScreen _viewModel; - - public MetroDialogService(IScreen viewModel) - { - _viewModel = viewModel; - } - private MetroWindow GetActiveWindow() { MetroWindow window = null; Execute.OnUIThread(() => { - window = Application.Current.Windows.OfType().FirstOrDefault(w => w.IsActive); - if (window == null) - { - window = Application.Current.Windows.OfType().FirstOrDefault(); - } + window = Application.Current.Windows.OfType().FirstOrDefault(w => w.IsActive) ?? + Application.Current.Windows.OfType().FirstOrDefault(); }); return window; @@ -57,7 +48,7 @@ namespace Artemis.Services public override void ShowMessageBox(string title, string message) { - if (_viewModel.IsActive == false) + if (GetActiveWindow() == null) return; Execute.OnUIThread(() => GetActiveWindow().ShowMessageAsync(title, message)); @@ -65,7 +56,7 @@ namespace Artemis.Services public override async Task ShowQuestionMessageBox(string title, string message) { - if (_viewModel.IsActive == false) + if (GetActiveWindow() == null) return null; var metroDialogSettings = new MetroDialogSettings {AffirmativeButtonText = "Yes", NegativeButtonText = "No"}; @@ -86,7 +77,7 @@ namespace Artemis.Services public override Task ShowInputDialog(string title, string message) { - if (_viewModel.IsActive == false) + if (GetActiveWindow() == null) return null; return GetActiveWindow().ShowInputAsync(title, message); @@ -94,7 +85,7 @@ namespace Artemis.Services public override bool ShowOpenDialog(out string path, string defaultExt, string filter, string initialDir = null) { - if (_viewModel.IsActive == false) + if (GetActiveWindow() == null) { path = null; return false; diff --git a/Artemis/Artemis/ViewModels/Abstract/EffectViewModel.cs b/Artemis/Artemis/ViewModels/Abstract/EffectViewModel.cs index 46bb14c22..b4850b2bb 100644 --- a/Artemis/Artemis/ViewModels/Abstract/EffectViewModel.cs +++ b/Artemis/Artemis/ViewModels/Abstract/EffectViewModel.cs @@ -1,6 +1,8 @@ using Artemis.Managers; using Artemis.Models; +using Artemis.Services; using Caliburn.Micro; +using Ninject; namespace Artemis.ViewModels.Abstract { @@ -17,6 +19,8 @@ namespace Artemis.ViewModels.Abstract EffectModel = effectModel; } + [Inject] + public MetroDialogService DialogService { get; set; } public EffectSettings EffectSettings { get { return _effectSettings; } @@ -69,7 +73,7 @@ namespace Artemis.ViewModels.Abstract public async void ResetSettings() { var resetConfirm = await - MainManager.DialogService.ShowQuestionMessageBox("Reset effect settings", + DialogService.ShowQuestionMessageBox("Reset effect settings", "Are you sure you wish to reset this effect's settings? \nAny changes you made will be lost."); if (!resetConfirm.Value) diff --git a/Artemis/Artemis/ViewModels/Abstract/GameViewModel.cs b/Artemis/Artemis/ViewModels/Abstract/GameViewModel.cs index 1eb0cc2ff..dec3ef5ec 100644 --- a/Artemis/Artemis/ViewModels/Abstract/GameViewModel.cs +++ b/Artemis/Artemis/ViewModels/Abstract/GameViewModel.cs @@ -1,22 +1,22 @@ -using System.ComponentModel; +using System; +using System.ComponentModel; using System.Threading; using System.Threading.Tasks; using Artemis.InjectionFactories; using Artemis.Managers; using Artemis.Models; using Artemis.Modules.Effects.ProfilePreview; +using Artemis.Services; using Caliburn.Micro; using Ninject; +using Ninject.Extensions.Logging; namespace Artemis.ViewModels.Abstract { public abstract class GameViewModel : Screen { - private bool _doActivate; - - private bool _editorShown; private GameSettings _gameSettings; - private EffectModel _lastEffect; + private bool _startLoopManager; protected GameViewModel(MainManager mainManager, GameModel gameModel, IEventAggregator events, IProfileEditorViewModelFactory pFactory) @@ -32,9 +32,14 @@ namespace Artemis.ViewModels.Abstract ProfileEditor.PropertyChanged += ProfileUpdater; } + [Inject] + public ILogger Logger { get; set; } [Inject] public ProfilePreviewModel ProfilePreviewModel { get; set; } + [Inject] + public MetroDialogService DialogService { get; set; } + public IEventAggregator Events { get; set; } public IProfileEditorViewModelFactory PFactory { get; set; } @@ -74,9 +79,8 @@ namespace Artemis.ViewModels.Abstract public async void ResetSettings() { var resetConfirm = - await - MainManager.DialogService.ShowQuestionMessageBox("Reset effect settings", - "Are you sure you wish to reset this effect's settings? \nAny changes you made will be lost."); + await DialogService.ShowQuestionMessageBox("Reset effect settings", + "Are you sure you wish to reset this effect's settings? \nAny changes you made will be lost."); if (!resetConfirm.Value) return; @@ -90,57 +94,34 @@ namespace Artemis.ViewModels.Abstract protected override void OnActivate() { base.OnActivate(); + SetEditorShown(true); - // OnActive is triggered at odd moments, only activate the profile - // preview if OnDeactivate isn't called right after it - _doActivate = true; + // OnActivate gets called at odd times, only start the LoopManager if it's been active + // for 600ms. + _startLoopManager = true; Task.Factory.StartNew(() => { - Thread.Sleep(100); - if (_doActivate) - SetEditorShown(true); + Thread.Sleep(600); + if (MainManager.LoopManager.Running || !_startLoopManager) + return; + + Logger.Debug("Starting LoopManager for profile preview"); + MainManager.LoopManager.Start(); }); } protected override void OnDeactivate(bool close) { base.OnDeactivate(close); - - _doActivate = false; SetEditorShown(false); + + _startLoopManager = false; } public void SetEditorShown(bool enable) { - if (enable == _editorShown) - return; - - if (enable) - { - // Store the current effect so it can be restored later - if (!(MainManager.EffectManager.ActiveEffect is ProfilePreviewModel)) - _lastEffect = MainManager.EffectManager.ActiveEffect; - - ProfilePreviewModel.SelectedProfile = ProfileEditor.SelectedProfile; - MainManager.EffectManager.ChangeEffect(ProfilePreviewModel, MainManager.LoopManager); - } - else - { - if (_lastEffect != null) - { - // Game models are only used if they are enabled - var gameModel = _lastEffect as GameModel; - if (gameModel != null) - if (!gameModel.Enabled) - MainManager.EffectManager.GetLastEffect(); - else - MainManager.EffectManager.ChangeEffect(_lastEffect, MainManager.LoopManager); - } - else - MainManager.EffectManager.ClearEffect(); - } - - _editorShown = enable; + MainManager.EffectManager.ProfilePreviewModel = ProfilePreviewModel; + MainManager.EffectManager.ProfilePreviewModel.SelectedProfile = enable ? ProfileEditor.SelectedProfile : null; } private void ProfileUpdater(object sender, PropertyChangedEventArgs e) diff --git a/Artemis/Artemis/ViewModels/Abstract/OverlayViewModel.cs b/Artemis/Artemis/ViewModels/Abstract/OverlayViewModel.cs index 4223b4364..b665f0941 100644 --- a/Artemis/Artemis/ViewModels/Abstract/OverlayViewModel.cs +++ b/Artemis/Artemis/ViewModels/Abstract/OverlayViewModel.cs @@ -1,6 +1,8 @@ using Artemis.Managers; using Artemis.Models; +using Artemis.Services; using Caliburn.Micro; +using Ninject; namespace Artemis.ViewModels.Abstract { @@ -14,6 +16,8 @@ namespace Artemis.ViewModels.Abstract MainManager = mainManager; } + [Inject] + public MetroDialogService DialogService { get; set; } public OverlayModel OverlayModel { get; set; } public OverlaySettings OverlaySettings @@ -40,7 +44,7 @@ namespace Artemis.ViewModels.Abstract public async void ResetSettings() { var resetConfirm = await - MainManager.DialogService.ShowQuestionMessageBox("Reset overlay settings", + DialogService.ShowQuestionMessageBox("Reset overlay settings", "Are you sure you wish to reset this overlay's settings? \nAny changes you made will be lost."); if (!resetConfirm.Value) diff --git a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs index d3fb9bee3..a34568039 100644 --- a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs +++ b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs @@ -1,3 +1,4 @@ +using System.ComponentModel; using System.Diagnostics; using System.Linq; using Artemis.Events; @@ -5,24 +6,28 @@ using Artemis.Managers; using Artemis.Settings; using Caliburn.Micro; using MahApps.Metro.Controls; +using Ninject.Extensions.Logging; namespace Artemis.ViewModels.Flyouts { - public class FlyoutSettingsViewModel : FlyoutBaseViewModel, IHandle, IHandle + public sealed class FlyoutSettingsViewModel : FlyoutBaseViewModel, IHandle, + IHandle { - private readonly KeyboardManager _keyboardManager; + private readonly ILogger _logger; private string _activeEffectName; private GeneralSettings _generalSettings; private string _selectedKeyboardProvider; - public FlyoutSettingsViewModel(MainManager mainManager, KeyboardManager keyboardManager, IEventAggregator events) + public FlyoutSettingsViewModel(MainManager mainManager, IEventAggregator events, ILogger logger) { - _keyboardManager = keyboardManager; + _logger = logger; + MainManager = mainManager; Header = "Settings"; Position = Position.Right; GeneralSettings = new GeneralSettings(); + PropertyChanged += KeyboardUpdater; events.Subscribe(this); } @@ -43,7 +48,7 @@ namespace Artemis.ViewModels.Flyouts { get { - var collection = new BindableCollection(_keyboardManager.KeyboardProviders.Select(k => k.Name)); + var collection = new BindableCollection(MainManager.KeyboardManager.KeyboardProviders.Select(k => k.Name)); collection.Insert(0, "None"); return collection; } @@ -57,12 +62,6 @@ namespace Artemis.ViewModels.Flyouts if (value == _selectedKeyboardProvider) return; _selectedKeyboardProvider = value; NotifyOfPropertyChange(() => SelectedKeyboardProvider); - if (value == null) - return; - - _keyboardManager.EnableKeyboard( - _keyboardManager.KeyboardProviders.FirstOrDefault( - k => k.Name == _selectedKeyboardProvider)); } } @@ -71,6 +70,7 @@ namespace Artemis.ViewModels.Flyouts get { return MainManager.ProgramEnabled; } set { + if (value) MainManager.EnableProgram(); else @@ -100,6 +100,28 @@ namespace Artemis.ViewModels.Flyouts NotifyOfPropertyChange(() => Enabled); } + /// + /// Takes proper action when the selected keyboard is changed in the UI + /// + /// + /// + private void KeyboardUpdater(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName != "SelectedKeyboardProvider") + return; + + _logger.Debug("Handling SelectedKeyboard change in UI"); + var keyboard = MainManager.KeyboardManager.KeyboardProviders.FirstOrDefault(k => k.Name == SelectedKeyboardProvider); + if (keyboard != null) + { + MainManager.KeyboardManager.EnableKeyboard(keyboard); + MainManager.LoopManager.Start(); + } + else + MainManager.KeyboardManager.ReleaseActiveKeyboard(); + + } + public void ToggleEnabled() { if (Enabled) diff --git a/Artemis/Artemis/ViewModels/LayerEditor/LayerEditorViewModel.cs b/Artemis/Artemis/ViewModels/LayerEditor/LayerEditorViewModel.cs index 2ffc978af..8c20796a0 100644 --- a/Artemis/Artemis/ViewModels/LayerEditor/LayerEditorViewModel.cs +++ b/Artemis/Artemis/ViewModels/LayerEditor/LayerEditorViewModel.cs @@ -10,6 +10,7 @@ using Artemis.Models.Profiles; using Artemis.Services; using Artemis.Utilities; using Caliburn.Micro; +using Ninject; using Screen = Caliburn.Micro.Screen; namespace Artemis.ViewModels.LayerEditor @@ -17,7 +18,6 @@ namespace Artemis.ViewModels.LayerEditor public class LayerEditorViewModel : Screen { private readonly KeyboardProvider _activeKeyboard; - private readonly MetroDialogService _dialogService; private readonly BackgroundWorker _previewWorker; private readonly bool _wasEnabled; private LayerModel _layer; @@ -30,7 +30,6 @@ namespace Artemis.ViewModels.LayerEditor _activeKeyboard = activeKeyboard; _wasEnabled = layer.Enabled; - _dialogService = new MetroDialogService(this); Layer = layer; ProposedLayer = new LayerModel(); GeneralHelpers.CopyProperties(ProposedLayer, Layer); @@ -53,6 +52,8 @@ namespace Artemis.ViewModels.LayerEditor PreSelect(); } + [Inject] + public MetroDialogService DialogService { get; set; } public LayerDynamicPropertiesViewModel OpacityProperties { get; set; } public LayerDynamicPropertiesViewModel WidthProperties { get; set; } @@ -177,7 +178,7 @@ namespace Artemis.ViewModels.LayerEditor OpacityProperties.Apply(); if (!File.Exists(Layer.GifFile) && Layer.LayerType == LayerType.KeyboardGif) - _dialogService.ShowErrorMessageBox("Couldn't find or access the provided GIF file."); + DialogService.ShowErrorMessageBox("Couldn't find or access the provided GIF file."); } public void DeleteCondition(LayerConditionViewModel layerConditionViewModel, diff --git a/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs b/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs index a865a7d0c..ca1a6dccf 100644 --- a/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs +++ b/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs @@ -12,10 +12,12 @@ using Artemis.KeyboardProviders; using Artemis.Managers; using Artemis.Models; using Artemis.Models.Profiles; +using Artemis.Services; using Artemis.Utilities; using Artemis.ViewModels.LayerEditor; using Caliburn.Micro; using MahApps.Metro; +using Ninject; namespace Artemis.ViewModels { @@ -47,6 +49,8 @@ namespace Artemis.ViewModels LoadProfiles(); } + [Inject] + public MetroDialogService DialogService { get; set; } public BindableCollection Profiles { get { return _profiles; } @@ -217,11 +221,11 @@ namespace Artemis.ViewModels /// public async void AddProfile() { - var name = await _mainManager.DialogService.ShowInputDialog("Add new profile", + var name = await DialogService.ShowInputDialog("Add new profile", "Please provide a profile name unique to this game and keyboard."); if (name.Length < 1) { - _mainManager.DialogService.ShowMessageBox("Invalid profile name", "Please provide a valid profile name"); + DialogService.ShowMessageBox("Invalid profile name", "Please provide a valid profile name"); return; } @@ -234,7 +238,7 @@ namespace Artemis.ViewModels if (ProfileProvider.GetAll().Contains(profile)) { - var overwrite = await _mainManager.DialogService.ShowQuestionMessageBox("Overwrite existing profile", + var overwrite = await DialogService.ShowQuestionMessageBox("Overwrite existing profile", "A profile with this name already exists for this game. Would you like to overwrite it?"); if (!overwrite.Value) return; diff --git a/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs b/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs index 4938b42b2..3c6b1c7c7 100644 --- a/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs +++ b/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs @@ -2,9 +2,11 @@ using System.Windows; using Artemis.Events; using Artemis.Managers; +using Artemis.Services; using Artemis.Settings; using Artemis.Utilities; using Caliburn.Micro; +using Ninject; namespace Artemis.ViewModels { @@ -33,6 +35,8 @@ namespace Artemis.ViewModels ShowWindow(); } + [Inject] + public MetroDialogService DialogService { get; set; } public MainManager MainManager { get; set; } public bool CanShowWindow => !_shellViewModel.IsActive; @@ -110,7 +114,7 @@ namespace Artemis.ViewModels return; _checkedForUpdate = true; - Updater.CheckForUpdate(MainManager.DialogService); + Updater.CheckForUpdate(DialogService); } diff --git a/Artemis/Artemis/packages.config b/Artemis/Artemis/packages.config index f1426999b..c355321fe 100644 --- a/Artemis/Artemis/packages.config +++ b/Artemis/Artemis/packages.config @@ -1,9 +1,8 @@  - - + @@ -19,7 +18,6 @@ -