diff --git a/Artemis/Artemis/App.config b/Artemis/Artemis/App.config index 20723b413..3ccf6e7e5 100644 --- a/Artemis/Artemis/App.config +++ b/Artemis/Artemis/App.config @@ -1,304 +1,11 @@  - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - + - - - - True - - - Default - - - - - - - - True - - - Default - - - - - - - - True - - - Default - - - - - Demo (Duplicate to keep changes) - - - - - True - - - Default - - - - - - - - True - - - - - True - - - Default - - - - - - - - True - - - #FFFF2900 - - - #FF26F600 - - - - - True - - - Default - - - - - {"Game":"RocketLeague","GameVersion":"1.10","GameAddresses":[{"Description":"Boost","BasePointer":{"value":21998084},"Offsets":[88,1452,1780,540]}]} - - - {"Game":"Witcher3","GameVersion":"1.11","GameAddresses":[{"Description":"Sign","BasePointer":{"value":42942304},"Offsets":[40,16,32,3008]}]} - - - - - True - - - - - 4 - - - 21 - - - True - - - 3 - - - #FFF90000 - - - #FFFF761E - - - #FF00DF00 - - - - - True - - - Default - - - - - - - - C:\Program Files (x86)\Steam\steamapps\common\Counter-Strike Global Offensive - - - True - - - #FFFF2900 - - - #FF26F600 - - - True - - - True - - - True - - - True - - - - - 4 - - - 21 - - - 1 - - - 3 - - - #FF0000FF - - - #FF1E90FF - - - - - False - - - #FFFF5000 - - - #FFFF0000 - - - - - TypeWave - - - - - True - - - #FFFF0000 - - - True - - - 20 - - - 500 - - - 4 - - - - - True - - - #FFFF0000 - - - True - - - 25 - - - 4 - - - 12 - - - 14 - - - 25 - - - - - WindowsProfile - - - - - - True - - - 51364 - - - False - - - False - - - True - - - True - - - Light - - - Info - - - @@ -337,7 +44,6 @@ - - + \ No newline at end of file diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index 6ee49f2d7..cc6e27133 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -131,24 +131,24 @@ ..\packages\Betwixt.1.4.1\lib\net35\Betwixt.dll True - - ..\packages\Caliburn.Micro.Core.3.0.1\lib\net45\Caliburn.Micro.dll + + ..\packages\Caliburn.Micro.Core.3.0.2\lib\net45\Caliburn.Micro.dll True - - ..\packages\Caliburn.Micro.3.0.1\lib\net45\Caliburn.Micro.Platform.dll + + ..\packages\Caliburn.Micro.3.0.2\lib\net45\Caliburn.Micro.Platform.dll True - - ..\packages\Caliburn.Micro.3.0.1\lib\net45\Caliburn.Micro.Platform.Core.dll + + ..\packages\Caliburn.Micro.3.0.2\lib\net45\Caliburn.Micro.Platform.Core.dll True ..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll True - - ..\packages\Colore.5.0.0\lib\net35\Corale.Colore.dll + + ..\packages\Colore.5.1.0\lib\net35\Corale.Colore.dll True @@ -236,7 +236,7 @@ True - ..\packages\NLog.4.3.10\lib\net45\NLog.dll + ..\packages\NLog.4.4.1\lib\net45\NLog.dll True @@ -255,8 +255,8 @@ ..\packages\SharpDX.Direct3D9.3.1.1\lib\net45\SharpDX.Direct3D9.dll True - - ..\packages\Splat.1.6.2\lib\Net45\Splat.dll + + ..\packages\Splat.2.0.0\lib\Net45\Splat.dll True @@ -333,7 +333,7 @@ MarkdownDialog.xaml - + @@ -349,16 +349,17 @@ - + - - - - + + + + + @@ -454,6 +455,13 @@ + + + + + OverlayProfileView.xaml + + @@ -481,6 +489,8 @@ + + AudioPropertiesView.xaml @@ -525,24 +535,20 @@ - - - - - - + + + + BubblesView.xaml - - - - WindowsProfileView.xaml + + + + GeneralProfileView.xaml - - - - - + + + @@ -568,15 +574,6 @@ - - - - True - True - VolumeDisplay.settings - - - @@ -609,12 +606,9 @@ - - - @@ -635,7 +629,6 @@ - @@ -644,12 +637,8 @@ - - - - - + @@ -669,22 +658,18 @@ - DebugView.xaml - - EffectsView.xaml + + GeneralView.xaml FlyoutSettingsView.xaml - - AudioVisualizerView.xaml - GamesView.xaml @@ -727,9 +712,6 @@ OverlaysView.xaml - - VolumeDisplayView.xaml - LayerTweenView.xaml @@ -750,13 +732,13 @@ Code + + Designer + - - Designer - @@ -771,10 +753,6 @@ Designer Resources.Designer.cs - - SettingsSingleFileGenerator - VolumeDisplay.Designer.cs - Designer @@ -828,11 +806,11 @@ Designer MSBuild:Compile - + Designer MSBuild:Compile - + MSBuild:Compile Designer @@ -868,6 +846,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + MSBuild:Compile Designer @@ -912,11 +894,7 @@ Designer MSBuild:Compile - - Designer - MSBuild:Compile - - + Designer MSBuild:Compile @@ -980,10 +958,6 @@ Designer MSBuild:Compile - - Designer - MSBuild:Compile - Designer MSBuild:Compile diff --git a/Artemis/Artemis/DAL/ProfileProvider.cs b/Artemis/Artemis/DAL/ProfileProvider.cs index 5b757726e..2721ae7d6 100644 --- a/Artemis/Artemis/DAL/ProfileProvider.cs +++ b/Artemis/Artemis/DAL/ProfileProvider.cs @@ -6,7 +6,7 @@ using System.IO.Compression; using System.Linq; using System.Reflection; using Artemis.DeviceProviders; -using Artemis.Models; +using Artemis.Modules.Abstract; using Artemis.Profiles; using Artemis.Profiles.Layers.Types.Keyboard; using Artemis.Properties; @@ -34,18 +34,18 @@ namespace Artemis.DAL InstallDefaults(); } - public static List GetProfileNames(KeyboardProvider keyboard, EffectModel effect) + public static List GetProfileNames(KeyboardProvider keyboard, ModuleModel module) { - if (keyboard == null || effect == null) + if (keyboard == null || module == null) return null; - return ReadProfiles(keyboard.Slug + "/" + effect.Name).Select(p => p.Name).ToList(); + return ReadProfiles(keyboard.Slug + "/" + module.Name).Select(p => p.Name).ToList(); } - public static ProfileModel GetProfile(KeyboardProvider keyboard, EffectModel effect, string name) + public static ProfileModel GetProfile(KeyboardProvider keyboard, ModuleModel module, string name) { - if (keyboard == null || effect == null) + if (keyboard == null || module == null) return null; - return ReadProfiles(keyboard.Slug + "/" + effect.Name).FirstOrDefault(p => p.Name == name); + return ReadProfiles(keyboard.Slug + "/" + module.Name).FirstOrDefault(p => p.Name == name); } public static bool IsProfileUnique(ProfileModel profileModel) @@ -238,7 +238,7 @@ namespace Artemis.DAL archive.ExtractToDirectory(ProfileFolder, true); - InsertGif("WindowsProfile", "Demo (duplicate to keep changes)", "GIF", Resources.demo_gif, "demo-gif"); + InsertGif("GeneralProfile", "Demo (duplicate to keep changes)", "GIF", Resources.demo_gif, "demo-gif"); } catch (IOException e) { diff --git a/Artemis/Artemis/Events/EffectChangedEventArgs.cs b/Artemis/Artemis/Events/EffectChangedEventArgs.cs deleted file mode 100644 index 9e9d4c9a9..000000000 --- a/Artemis/Artemis/Events/EffectChangedEventArgs.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using Artemis.Models; - -namespace Artemis.Events -{ - public class EffectChangedEventArgs : EventArgs - { - public EffectChangedEventArgs(EffectModel effect) - { - Effect = effect; - } - - public EffectModel Effect { get; } - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Events/ModuleChangedEventArgs.cs b/Artemis/Artemis/Events/ModuleChangedEventArgs.cs new file mode 100644 index 000000000..ccb99f5a6 --- /dev/null +++ b/Artemis/Artemis/Events/ModuleChangedEventArgs.cs @@ -0,0 +1,15 @@ +using System; +using Artemis.Modules.Abstract; + +namespace Artemis.Events +{ + public class ModuleChangedEventArgs : EventArgs + { + public ModuleChangedEventArgs(ModuleModel module) + { + Module = module; + } + + public ModuleModel Module { get; } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Events/ProfileDeviceEventsArg.cs b/Artemis/Artemis/Events/ProfileDeviceEventsArg.cs index 6a988f1bd..d6fb74424 100644 --- a/Artemis/Artemis/Events/ProfileDeviceEventsArg.cs +++ b/Artemis/Artemis/Events/ProfileDeviceEventsArg.cs @@ -1,21 +1,22 @@ using System; using System.Windows.Media; -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; +using Artemis.Profiles.Layers.Interfaces; namespace Artemis.Events { public class ProfileDeviceEventsArg : EventArgs { - public ProfileDeviceEventsArg(string updateType, IDataModel dataModel, bool preview, DrawingContext drawingContext) + public ProfileDeviceEventsArg(DrawType updateType, ModuleDataModel dataModel, bool preview, DrawingContext drawingContext) { - UpdateType = updateType; + UpdateType = updateType.ToString().ToLower(); DataModel = dataModel; Preview = preview; DrawingContext = drawingContext; } public string UpdateType { get; } - public IDataModel DataModel { get; } + public ModuleDataModel DataModel { get; } public bool Preview { get; } public DrawingContext DrawingContext { get; } } diff --git a/Artemis/Artemis/InjectionModules/BaseModules.cs b/Artemis/Artemis/InjectionModules/BaseModules.cs index 5c975f7f9..bd0108284 100644 --- a/Artemis/Artemis/InjectionModules/BaseModules.cs +++ b/Artemis/Artemis/InjectionModules/BaseModules.cs @@ -1,11 +1,7 @@ using Artemis.DeviceProviders; -using Artemis.Models; -using Artemis.Modules.Effects.ProfilePreview; +using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Interfaces; -using Artemis.Profiles.Layers.Types.AmbientLight; -using Artemis.Profiles.Layers.Types.Audio; using Artemis.Profiles.Layers.Types.Audio.AudioCapturing; -using Artemis.Profiles.Layers.Types.KeyPress; using Artemis.Profiles.Lua; using Artemis.Services; using Artemis.Utilities.DataReaders; @@ -36,12 +32,6 @@ namespace Artemis.InjectionModules #endregion - #region Models - - Bind().ToSelf().InSingletonScope(); - - #endregion - #region Services Bind().ToSelf().InSingletonScope(); @@ -71,25 +61,17 @@ namespace Artemis.InjectionModules Kernel.Bind(x => x.FromThisAssembly() .SelectAllClasses() - .InheritedFrom() + .InheritedFrom() .BindAllBaseClasses() .Configure((b, c) => b.InSingletonScope().Named(c.Name)) ); Kernel.Bind(x => x.FromThisAssembly() .SelectAllClasses() - .InheritedFrom() - .BindBase()); - Kernel.Bind(x => - x.FromThisAssembly() - .SelectAllClasses() - .InheritedFrom() - .BindBase()); - Kernel.Bind(x => - x.FromThisAssembly() - .SelectAllClasses() - .InheritedFrom() - .BindBase()); + .InheritedFrom() + .BindAllBaseClasses() + .Configure(b => b.InSingletonScope()) + ); #endregion @@ -115,7 +97,7 @@ namespace Artemis.InjectionModules .SelectAllClasses() .InheritedFrom() .BindToSelf()); - + // Type helpers Bind().ToSelf().InSingletonScope(); diff --git a/Artemis/Artemis/InjectionModules/ManagerModules.cs b/Artemis/Artemis/InjectionModules/ManagerModules.cs index c90727795..0d5870d63 100644 --- a/Artemis/Artemis/InjectionModules/ManagerModules.cs +++ b/Artemis/Artemis/InjectionModules/ManagerModules.cs @@ -10,7 +10,7 @@ namespace Artemis.InjectionModules Bind().ToSelf().InSingletonScope(); Bind().ToSelf().InSingletonScope(); Bind().ToSelf().InSingletonScope(); - Bind().ToSelf().InSingletonScope(); + Bind().ToSelf().InSingletonScope(); Bind().ToSelf().InSingletonScope(); Bind().ToSelf().InSingletonScope(); } diff --git a/Artemis/Artemis/Managers/DeviceManager.cs b/Artemis/Artemis/Managers/DeviceManager.cs index bc79efdb1..8535f712b 100644 --- a/Artemis/Artemis/Managers/DeviceManager.cs +++ b/Artemis/Artemis/Managers/DeviceManager.cs @@ -51,7 +51,7 @@ namespace Artemis.Managers public bool ChangingKeyboard { get; private set; } - public event EventHandler OnKeyboardChangedEvent; + public event EventHandler OnKeyboardChanged; /// /// Enables the last keyboard according to the settings file @@ -178,7 +178,7 @@ namespace Artemis.Managers { // I do this in all to avoid a possible race condition // https://msdn.microsoft.com/en-us/library/w369ty8x.aspx - var handler = OnKeyboardChangedEvent; + var handler = OnKeyboardChanged; handler?.Invoke(this, e); } } diff --git a/Artemis/Artemis/Managers/EffectManager.cs b/Artemis/Artemis/Managers/EffectManager.cs deleted file mode 100644 index 4088dbda8..000000000 --- a/Artemis/Artemis/Managers/EffectManager.cs +++ /dev/null @@ -1,236 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Artemis.Events; -using Artemis.Models; -using Artemis.Modules.Effects.ProfilePreview; -using Artemis.Settings; -using Ninject.Extensions.Logging; - -namespace Artemis.Managers -{ - /// - /// Manages the effects - /// - public class EffectManager - { - private readonly DeviceManager _deviceManager; - private readonly ILogger _logger; - private EffectModel _activeEffect; - private LoopManager _waitLoopManager; - private EffectModel _waitEffect; - private readonly GeneralSettings _generalSettings; - - public EffectManager(ILogger logger, DeviceManager deviceManager, List effectModels, - List gameModels, List overlayModels) - { - _generalSettings = DAL.SettingsProvider.Load(); - _logger = logger; - _deviceManager = deviceManager; - - var models = new List(); - // Add regular effects - models.AddRange(effectModels); - // Add overlays - models.AddRange(overlayModels); - // Add games, exclude WoW if needed - models.AddRange(_generalSettings.GamestatePort != 62575 - ? gameModels.Where(e => e.Name != "WoW") - : gameModels); - - EffectModels = models; - _logger.Info("Intialized EffectManager"); - } - - public ProfilePreviewModel ProfilePreviewModel { get; set; } - - /// - /// Holds all the effects the program has - /// - public List EffectModels { get; set; } - - public EffectModel ActiveEffect - { - get { return _activeEffect; } - private set - { - _activeEffect = value; - RaiseEffectChangedEvent(new EffectChangedEventArgs(value)); - } - } - - /// - /// Returns all enabled overlays - /// - public IEnumerable EnabledOverlays - { - get { return EffectModels.OfType().Where(o => o.Enabled); } - } - - /// - /// Returns all enabled games - /// - public IEnumerable EnabledGames - { - get { return EffectModels.OfType().Where(g => g.Enabled && g.Settings.Enabled); } - } - - public event EventHandler OnEffectChangedEvent; - - /// - /// Loads the last active effect from settings and enables it. - /// - /// Whether enabling was successful or not. - public EffectModel GetLastEffect() - { - _logger.Debug("Getting last effect: {0}", _generalSettings.LastEffect); - return _generalSettings.LastEffect == null - ? null - : EffectModels.FirstOrDefault(e => e.Name == _generalSettings.LastEffect); - } - - /// - /// Disables the current effect and changes it to the provided effect. - /// - /// The effect to activate - /// Optionally pass the LoopManager to automatically start it, if it's not running. - public void ChangeEffect(EffectModel effectModel, LoopManager loopManager = null) - { - if (_waitEffect != null) - { - _logger.Debug("Stopping effect because a change is already queued"); - return; - } - - if (effectModel == null) - throw new ArgumentNullException(nameof(effectModel)); - if (effectModel is OverlayModel) - throw new ArgumentException("Can't set an Overlay effect as the active effect"); - - if (_deviceManager.ActiveKeyboard == null) - { - _logger.Debug("Stopping effect change until keyboard is enabled"); - _waitEffect = effectModel; - _waitLoopManager = loopManager; - _deviceManager.OnKeyboardChangedEvent += DeviceManagerOnOnKeyboardChangedEvent; - _deviceManager.EnableLastKeyboard(); - return; - } - - // Game models are only used if they are enabled - var gameModel = effectModel as GameModel; - if (gameModel != null) - if (!gameModel.Enabled) - { - _logger.Debug("Cancelling effect change, provided game not enabled"); - return; - } - - - var wasNull = false; - if (ActiveEffect == null) - { - wasNull = true; - ActiveEffect = effectModel; - } - - lock (ActiveEffect) - { - if (!wasNull) - ActiveEffect.Dispose(); - lock (effectModel) - { - ActiveEffect = effectModel; - ActiveEffect.Enable(); - if (!ActiveEffect.Initialized) - { - _logger.Debug("Cancelling effect change, couldn't initialize the effect ({0})", effectModel.Name); - ActiveEffect = null; - return; - } - } - } - - if (loopManager != null && !loopManager.Running) - { - _logger.Debug("Starting LoopManager for effect change"); - loopManager.StartAsync(); - } - - _logger.Debug("Changed active effect to: {0}", effectModel.Name); - - if (ActiveEffect is GameModel || ActiveEffect is ProfilePreviewModel) - return; - - // Non-game effects are stored as the new LastEffect. - _generalSettings.LastEffect = ActiveEffect?.Name; - _generalSettings.Save(); - } - - private void DeviceManagerOnOnKeyboardChangedEvent(object sender, KeyboardChangedEventArgs e) - { - _deviceManager.OnKeyboardChangedEvent -= DeviceManagerOnOnKeyboardChangedEvent; - _logger.Debug("Resuming effect change"); - - var effect = _waitEffect; - _waitEffect = null; - var loopManager = _waitLoopManager; - _waitLoopManager = null; - - ChangeEffect(effect, loopManager); - } - - - /// - /// Clears the current effect - /// - public void ClearEffect() - { - if (ActiveEffect == null) - return; - - lock (ActiveEffect) - { - ActiveEffect.Dispose(); - ActiveEffect = null; - - _generalSettings.LastEffect = null; - _generalSettings.Save(); - } - - _logger.Debug("Cleared active effect"); - } - - /// - /// Disables the given game - /// - /// - public void DisableGame(EffectModel activeEffect) - { - _logger.Debug("Disabling game: {0}", activeEffect?.Name); - if (GetLastEffect() == null) - ClearEffect(); - else - ChangeEffect(GetLastEffect()); - } - - /// - /// Disables the current ActiveEffect if it's a game that is disabled. - /// - public void DisableInactiveGame() - { - if (!(ActiveEffect is GameModel)) - return; - if (EnabledGames.Contains(ActiveEffect)) - return; - - DisableGame(ActiveEffect); - } - - protected virtual void RaiseEffectChangedEvent(EffectChangedEventArgs e) - { - var handler = OnEffectChangedEvent; - handler?.Invoke(this, e); - } - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Managers/LoopManager.cs b/Artemis/Artemis/Managers/LoopManager.cs index b0aefca54..cb1493b10 100644 --- a/Artemis/Artemis/Managers/LoopManager.cs +++ b/Artemis/Artemis/Managers/LoopManager.cs @@ -4,10 +4,11 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Timers; +using System.Windows.Media; using Artemis.DeviceProviders; using Artemis.ViewModels; -using Caliburn.Micro; using Ninject.Extensions.Logging; +using Color = System.Drawing.Color; using Timer = System.Timers.Timer; namespace Artemis.Managers @@ -19,15 +20,15 @@ namespace Artemis.Managers { private readonly DebugViewModel _debugViewModel; private readonly DeviceManager _deviceManager; - private readonly EffectManager _effectManager; private readonly ILogger _logger; private readonly Timer _loopTimer; + private readonly ModuleManager _moduleManager; - public LoopManager(ILogger logger, EffectManager effectManager, DeviceManager deviceManager, + public LoopManager(ILogger logger, ModuleManager moduleManager, DeviceManager deviceManager, DebugViewModel debugViewModel) { _logger = logger; - _effectManager = effectManager; + _moduleManager = moduleManager; _deviceManager = deviceManager; _debugViewModel = debugViewModel; @@ -89,15 +90,15 @@ namespace Artemis.Managers return; } - if (_effectManager.ActiveEffect == null) + if (_moduleManager.ActiveModule == null) { - var lastEffect = _effectManager.GetLastEffect(); - if (lastEffect == null) + var lastModule = _moduleManager.GetLastModule(); + if (lastModule == null) { - _logger.Debug("Cancel LoopManager start, no effect"); + _logger.Debug("Cancel LoopManager start, no module"); return; } - _effectManager.ChangeEffect(lastEffect); + _moduleManager.ChangeActiveModule(lastModule); } Running = true; @@ -119,14 +120,14 @@ namespace Artemis.Managers if (!Running || _deviceManager.ChangingKeyboard) return; - // Stop if no active effect - if (_effectManager.ActiveEffect == null) + // Stop if no active module + if (_moduleManager.ActiveModule == null) { - _logger.Debug("No active effect, stopping"); + _logger.Debug("No active module, stopping"); Stop(); return; } - var renderEffect = _effectManager.ActiveEffect; + var renderModule = _moduleManager.ActiveModule; // Stop if no active keyboard if (_deviceManager.ActiveKeyboard == null) @@ -138,13 +139,13 @@ namespace Artemis.Managers lock (_deviceManager.ActiveKeyboard) { - // Skip frame if effect is still initializing - if (renderEffect.Initialized == false) + // Skip frame if module is still initializing + if (renderModule.IsInitialized == false) return; - // ApplyProperties the current effect - if (renderEffect.Initialized) - renderEffect.Update(); + // ApplyProperties the current module + if (renderModule.IsInitialized) + renderModule.Update(); // Get the devices that must be rendered to var mice = _deviceManager.MiceProviders.Where(m => m.CanUse).ToList(); @@ -156,14 +157,14 @@ namespace Artemis.Managers // Setup the frame for this tick using (var frame = new RenderFrame(_deviceManager.ActiveKeyboard)) { - if (renderEffect.Initialized) - renderEffect.Render(frame, keyboardOnly); + if (renderModule.IsInitialized) + renderModule.Render(frame, keyboardOnly); - // Draw enabled overlays on top of the renderEffect - foreach (var overlayModel in _effectManager.EnabledOverlays) + // Draw enabled overlays on top of the renderModule + foreach (var overlayModel in _moduleManager.OverlayModules.Where(o => o.Settings.IsEnabled)) { overlayModel.Update(); - overlayModel.RenderOverlay(frame, keyboardOnly); + overlayModel.Render(frame, keyboardOnly); } // Update the keyboard diff --git a/Artemis/Artemis/Managers/LuaManager.cs b/Artemis/Artemis/Managers/LuaManager.cs index fbd499a8b..bae48462d 100644 --- a/Artemis/Artemis/Managers/LuaManager.cs +++ b/Artemis/Artemis/Managers/LuaManager.cs @@ -35,7 +35,7 @@ namespace Artemis.Managers public void SetupLua(ProfileModel profileModel) { - _logger.Debug("Setting up LUA for {0}-{1}.", profileModel?.Name, profileModel?.GameName); + _logger.Debug("Setting up LUA for profile '{0}', module '{1}'", profileModel?.Name, profileModel?.GameName); // Clear old state ClearLua(); diff --git a/Artemis/Artemis/Managers/MainManager.cs b/Artemis/Artemis/Managers/MainManager.cs index 68a50fd42..2d716f77e 100644 --- a/Artemis/Artemis/Managers/MainManager.cs +++ b/Artemis/Artemis/Managers/MainManager.cs @@ -4,7 +4,6 @@ using System.Reflection; using System.Threading.Tasks; using System.Timers; using Artemis.Events; -using Artemis.Models; using Artemis.Utilities; using Artemis.Utilities.DataReaders; using Artemis.Utilities.GameState; @@ -23,13 +22,13 @@ namespace Artemis.Managers private readonly Timer _processTimer; public MainManager(ILogger logger, LoopManager loopManager, DeviceManager deviceManager, - EffectManager effectManager, ProfileManager profileManager, PipeServer pipeServer, + ModuleManager moduleManager, ProfileManager profileManager, PipeServer pipeServer, GameStateWebServer gameStateWebServer) { Logger = logger; LoopManager = loopManager; DeviceManager = deviceManager; - EffectManager = effectManager; + ModuleManager = moduleManager; ProfileManager = profileManager; PipeServer = pipeServer; @@ -64,7 +63,7 @@ namespace Artemis.Managers public ILogger Logger { get; set; } public LoopManager LoopManager { get; } public DeviceManager DeviceManager { get; set; } - public EffectManager EffectManager { get; set; } + public ModuleManager ModuleManager { get; set; } public ProfileManager ProfileManager { get; set; } public PipeServer PipeServer { get; set; } @@ -79,12 +78,12 @@ namespace Artemis.Managers _processTimer?.Stop(); _processTimer?.Dispose(); LoopManager?.Stop(); - EffectManager?.ActiveEffect?.Dispose(); + ModuleManager?.ActiveModule?.Dispose(); GameStateWebServer?.Stop(); PipeServer?.Stop(); } - public event EventHandler OnEnabledChangedEvent; + public event EventHandler EnabledChanged; /// /// Restarts the loop manager when the system resumes @@ -126,7 +125,7 @@ namespace Artemis.Managers } /// - /// Manages active games by keeping an eye on their processes + /// Manages active process bound modules by keeping an eye on their processes /// /// /// @@ -135,36 +134,38 @@ namespace Artemis.Managers if (!ProgramEnabled) return; - var runningProcesses = System.Diagnostics.Process.GetProcesses(); + var processes = System.Diagnostics.Process.GetProcesses(); + var module = ModuleManager.ActiveModule; - // If the currently active effect is a disabled game, get rid of it. - if (EffectManager.ActiveEffect != null) - EffectManager.DisableInactiveGame(); + // If the active module is a process bound module, make sure it should still be enabled + if (module != null && module.IsBoundToProcess) + { + if (!module.Settings.IsEnabled) + ModuleManager.DisableProcessBoundModule(); - // If the currently active effect is a no longer running game, get rid of it. - var activeGame = EffectManager.ActiveEffect as GameModel; - if (activeGame != null) - if (!runningProcesses.Any(p => p.ProcessName == activeGame.ProcessName && p.HasExited == false)) + // If the currently active effect is a no longer running game, get rid of it. + if (!processes.Any(p => p.ProcessName == module.ProcessName && p.HasExited == false)) { - Logger.Info("Disabling game: {0}", activeGame.Name); - EffectManager.DisableGame(activeGame); + Logger.Info("Disabling process bound module because process stopped: {0}", module.Name); + ModuleManager.DisableProcessBoundModule(); } + } // Look for running games, stopping on the first one that's found. - var newGame = EffectManager.EnabledGames - .FirstOrDefault(g => runningProcesses - .Any(p => p.ProcessName == g.ProcessName && p.HasExited == false)); + var newModule = ModuleManager.ProcessModules.Where(g => g.Settings.IsEnabled && g.Settings.IsEnabled) + .FirstOrDefault(g => processes.Any(p => p.ProcessName == g.ProcessName && p.HasExited == false)); - if (newGame == null || EffectManager.ActiveEffect == newGame) + if (newModule == null || module == newModule) return; + // If it's not already enabled, do so. - Logger.Info("Detected and enabling game: {0}", newGame.Name); - EffectManager.ChangeEffect(newGame, LoopManager); + Logger.Info("Detected and enabling process bound module: {0}", newModule.Name); + ModuleManager.ChangeActiveModule(newModule, LoopManager); } protected virtual void RaiseEnabledChangedEvent(EnabledChangedEventArgs e) { - var handler = OnEnabledChangedEvent; + var handler = EnabledChanged; handler?.Invoke(this, e); } } diff --git a/Artemis/Artemis/Managers/ModuleManager.cs b/Artemis/Artemis/Managers/ModuleManager.cs new file mode 100644 index 000000000..61724e88a --- /dev/null +++ b/Artemis/Artemis/Managers/ModuleManager.cs @@ -0,0 +1,204 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Artemis.Events; +using Artemis.Modules.Abstract; +using Artemis.Settings; +using Ninject.Extensions.Logging; + +namespace Artemis.Managers +{ + public class ModuleManager + { + private readonly DeviceManager _deviceManager; + private readonly ILogger _logger; + private ModuleModel _activeModule; + private LoopManager _waitLoopManager; + private ModuleModel _waitEffect; + private readonly GeneralSettings _generalSettings; + + public ModuleManager(ILogger logger, DeviceManager deviceManager, List moduleModels) + { + _generalSettings = DAL.SettingsProvider.Load(); + _logger = logger; + _deviceManager = deviceManager; + + Modules = new List(moduleModels.Where(m => !m.IsOverlay && !m.IsBoundToProcess)); + OverlayModules = new List(moduleModels.Where(m => m.IsOverlay)); + // Exclude WoW if needed + ProcessModules = _generalSettings.GamestatePort == 62575 + ? new List(moduleModels.Where(m => m.IsBoundToProcess)) + : new List(moduleModels.Where(m => m.IsBoundToProcess && m.Name != "WoW")); + + _logger.Info("Intialized ModuleManager"); + } + + public List Modules { get; set; } + public List ProcessModules { get; set; } + public List OverlayModules { get; set; } + + public ModuleModel ActiveModule + { + get { return _activeModule; } + private set + { + _activeModule = value; + RaiseEffectChangedEvent(new ModuleChangedEventArgs(value)); + } + } + + public event EventHandler EffectChanged; + + /// + /// Loads the last active module from settings and enables it. + /// + public ModuleModel GetLastModule() + { + _logger.Debug("Getting last module: {0}", _generalSettings.LastModule); + + if (_generalSettings.LastModule != null) + { + var lastModule = Modules.FirstOrDefault(e => e.Name == _generalSettings.LastModule); + if (lastModule != null) + return lastModule; + } + + _logger.Debug("Getting last module not found, defaulting to GeneralProfile"); + return Modules.First(e => e.Name == "GeneralProfile"); + } + + /// + /// Disables the current module and changes it to the provided module. + /// + /// The module to activate + /// Optionally pass the LoopManager to automatically start it, if it's not running. + public void ChangeActiveModule(ModuleModel moduleModel, LoopManager loopManager = null) + { + if (_waitEffect != null) + { + _logger.Debug("Stopping module change because a change is already queued"); + return; + } + + if (moduleModel == null) + throw new ArgumentNullException(nameof(moduleModel)); + if (moduleModel.IsOverlay) + throw new ArgumentException("Can't set an General module as the active module"); + + if (_deviceManager.ActiveKeyboard == null) + { + _logger.Debug("Stopping module change until keyboard is enabled"); + _waitEffect = moduleModel; + _waitLoopManager = loopManager; + _deviceManager.OnKeyboardChanged += DeviceManagerOnOnKeyboardChanged; + _deviceManager.EnableLastKeyboard(); + return; + } + + // Process bound modules are only used if they are enabled + if (moduleModel.Settings != null && !moduleModel.Settings.IsEnabled && moduleModel.IsBoundToProcess) + { + _logger.Debug("Cancelling module change, provided module is process bound and not enabled"); + return; + } + + + var wasNull = false; + if (ActiveModule == null) + { + wasNull = true; + ActiveModule = moduleModel; + } + + lock (ActiveModule) + { + if (!wasNull) + ActiveModule.Dispose(); + lock (moduleModel) + { + ActiveModule = moduleModel; + ActiveModule.Enable(); + if (!ActiveModule.IsInitialized) + { + _logger.Debug("Cancelling module change, couldn't initialize the module ({0})", moduleModel.Name); + ActiveModule = null; + return; + } + } + } + + if (loopManager != null && !loopManager.Running) + { + _logger.Debug("Starting LoopManager for module change"); + loopManager.StartAsync(); + } + + _logger.Debug("Changed active module to: {0}", moduleModel.Name); + + if (ActiveModule.IsBoundToProcess || ActiveModule.IsOverlay || ActiveModule.Name == "Profile preview") + return; + + // Regular modules are stored as the last active module + _generalSettings.LastModule = ActiveModule?.Name; + _generalSettings.Save(); + } + + private void DeviceManagerOnOnKeyboardChanged(object sender, KeyboardChangedEventArgs e) + { + _deviceManager.OnKeyboardChanged -= DeviceManagerOnOnKeyboardChanged; + _logger.Debug("Resuming module change"); + + var module = _waitEffect; + _waitEffect = null; + var loopManager = _waitLoopManager; + _waitLoopManager = null; + + ChangeActiveModule(module, loopManager); + } + + + /// + /// Clears the current module + /// + public void ClearActiveModule() + { + if (ActiveModule == null) + return; + + lock (ActiveModule) + { + ActiveModule.Dispose(); + ActiveModule = null; + + _generalSettings.LastModule = null; + _generalSettings.Save(); + } + + _logger.Debug("Cleared active module"); + } + + /// + /// Disables the currently active process bound module + /// + public void DisableProcessBoundModule() + { + if (!ActiveModule.IsBoundToProcess) + { + _logger.Warn("Active module {0} is not process bound but is being disabled as if it is.", + ActiveModule.Name); + return; + } + + if (GetLastModule() == null) + ClearActiveModule(); + else + ChangeActiveModule(GetLastModule()); + } + + protected virtual void RaiseEffectChangedEvent(ModuleChangedEventArgs e) + { + var handler = EffectChanged; + handler?.Invoke(this, e); + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Managers/ProfileManager.cs b/Artemis/Artemis/Managers/ProfileManager.cs index 8d5c36836..2cc2e1dc9 100644 --- a/Artemis/Artemis/Managers/ProfileManager.cs +++ b/Artemis/Artemis/Managers/ProfileManager.cs @@ -2,32 +2,31 @@ using System.Linq; using System.Timers; using Artemis.DAL; -using Artemis.Models; -using Artemis.Modules.Effects.ProfilePreview; +using Artemis.Modules.Abstract; using Artemis.Settings; -using Artemis.ViewModels.Abstract; +using Ninject; using Ninject.Extensions.Logging; namespace Artemis.Managers { public class ProfileManager { - private readonly DeviceManager _deviceManager; - private readonly EffectManager _effectManager; private readonly ILogger _logger; + private readonly ModuleManager _moduleManager; + private readonly DeviceManager _deviceManager; private readonly LoopManager _loopManager; - private GeneralSettings _generalSettings; + private readonly GeneralSettings _generalSettings; - public ProfileManager(ILogger logger, EffectManager effectManager, DeviceManager deviceManager, + public ProfileManager(ILogger logger, ModuleManager moduleManager, DeviceManager deviceManager, LoopManager loopManager) { _logger = logger; - _effectManager = effectManager; + _moduleManager = moduleManager; _deviceManager = deviceManager; _loopManager = loopManager; _generalSettings = SettingsProvider.Load(); - GameViewModels = new List(); + PreviewViewModules = new List(); var profilePreviewTimer = new Timer(500); profilePreviewTimer.Elapsed += SetupProfilePreview; @@ -36,9 +35,7 @@ namespace Artemis.Managers _logger.Info("Intialized ProfileManager"); } - public ProfilePreviewModel ProfilePreviewModel { get; set; } - - public List GameViewModels { get; set; } + public List PreviewViewModules { get; set; } /// /// Keeps track of profiles being previewed and sets up the active efffect accordingly @@ -47,44 +44,39 @@ namespace Artemis.Managers /// private void SetupProfilePreview(object sender, ElapsedEventArgs e) { - if (string.IsNullOrEmpty(_generalSettings.LastKeyboard) || _deviceManager.ChangingKeyboard || - ProfilePreviewModel == null) - return; - - lock (GameViewModels) - { - var activePreview = GameViewModels.FirstOrDefault(vm => vm.IsActive); - - if (activePreview == null) - { - // Should not be active if no selected profile is set - if (_effectManager.ActiveEffect != ProfilePreviewModel) - return; - - _logger.Debug("Loading last effect after profile preview"); - var lastEffect = _effectManager.GetLastEffect(); - if (lastEffect != null) - _effectManager.ChangeEffect(lastEffect); - else - _effectManager.ClearEffect(); - } - else - { - if (_effectManager.ActiveEffect != ProfilePreviewModel && - !(_effectManager.ActiveEffect is GameModel)) - { - _logger.Debug("Activate profile preview"); - _effectManager.ChangeEffect(ProfilePreviewModel); - } - - // LoopManager might be running, this method won't do any harm in that case. - _loopManager.StartAsync(); - - ProfilePreviewModel.ProfileViewModel = activePreview.ProfileEditor.ProfileViewModel; - if (!ReferenceEquals(ProfilePreviewModel.Profile, activePreview.ProfileEditor.SelectedProfile)) - ProfilePreviewModel.Profile = activePreview.ProfileEditor.SelectedProfile; - } - } +// if (string.IsNullOrEmpty(_generalSettings.LastKeyboard) || _deviceManager.ChangingKeyboard) +// return; +// +// var activePreview = PreviewViewModules.FirstOrDefault(vm => vm.IsActive); +// if (activePreview == null) +// { +// // Should not be active if no selected profile is set +// if (_moduleManager.ActiveModule != _profilePreviewModel) +// return; +// +// _logger.Debug("Loading last module after profile preview"); +// var lastModule = _moduleManager.GetLastModule(); +// if (lastModule != null) +// _moduleManager.ChangeActiveModule(lastModule); +// else +// _moduleManager.ClearActiveModule(); +// } +// else +// { +// if (_moduleManager.ActiveModule != null && _moduleManager.ActiveModule != _profilePreviewModel && +// _moduleManager.ActiveModule != activePreview.ModuleModel) +// { +// _logger.Debug("Activate profile preview"); +// _moduleManager.ChangeActiveModule(_profilePreviewModel); +// } +// +// // LoopManager might be running, this method won't do any harm in that case. +// _loopManager.StartAsync(); +// +// // Can safely spam this, it won't do anything if they are equal +// _profilePreviewModel.ProfileViewModel = activePreview.ProfileEditor.ProfileViewModel; +// _profilePreviewModel.ChangeProfile(activePreview.ModuleModel.ProfileModel); +// } } } } \ No newline at end of file diff --git a/Artemis/Artemis/Models/EffectModel.cs b/Artemis/Artemis/Models/EffectModel.cs deleted file mode 100644 index a2dd083df..000000000 --- a/Artemis/Artemis/Models/EffectModel.cs +++ /dev/null @@ -1,156 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Windows; -using Artemis.DAL; -using Artemis.Events; -using Artemis.Managers; -using Artemis.Models.Interfaces; -using Artemis.Profiles; -using Artemis.Profiles.Layers.Interfaces; -using Artemis.Profiles.Layers.Models; -using Artemis.Settings; -using Newtonsoft.Json; -using Ninject; -using Ninject.Extensions.Logging; - -namespace Artemis.Models -{ - public abstract class EffectModel : IDisposable - { - public delegate void SettingsUpdateHandler(EffectSettings settings); - - protected DateTime LastTrace; - - protected EffectModel(DeviceManager deviceManager, LuaManager luaManager, EffectSettings settings, - IDataModel dataModel) - { - DeviceManager = deviceManager; - LuaManager = luaManager; - Settings = settings; - DataModel = dataModel; - - DeviceManager.OnKeyboardChangedEvent += DeviceManagerOnOnKeyboardChangedEvent; - } - - public bool Initialized { get; set; } - public DeviceManager DeviceManager { get; set; } - public LuaManager LuaManager { get; } - public EffectSettings Settings { get; set; } - public string Name { get; set; } - public int KeyboardScale { get; set; } = 4; - // Used by profile system - public IDataModel DataModel { get; set; } - - public ProfileModel Profile { get; set; } - - [Inject] - public ILogger Logger { get; set; } - - public virtual void Dispose() - { - Profile?.Deactivate(LuaManager); - Profile = null; - } - - private void DeviceManagerOnOnKeyboardChangedEvent(object sender, KeyboardChangedEventArgs args) - { - if (!Initialized) - return; - - if (!string.IsNullOrEmpty(Settings?.LastProfile)) - Profile = ProfileProvider.GetProfile(DeviceManager.ActiveKeyboard, this, Settings.LastProfile); - else - Profile = ProfileProvider.GetProfile(DeviceManager.ActiveKeyboard, this, "Default"); - - Profile?.Activate(LuaManager); - } - - // Called on creation - public virtual void Enable() - { - // If set, load the last profile from settings - if (!string.IsNullOrEmpty(Settings?.LastProfile)) - Profile = ProfileProvider.GetProfile(DeviceManager.ActiveKeyboard, this, Settings.LastProfile); - else - Profile = ProfileProvider.GetProfile(DeviceManager.ActiveKeyboard, this, "Default"); - - Profile?.Activate(LuaManager); - } - - // Called every frame - public abstract void Update(); - - // Called after every update - /// - /// Renders the currently active profile - /// - /// - /// - public virtual void Render(RenderFrame frame, bool keyboardOnly) - { - if (Profile == null || DataModel == null || DeviceManager.ActiveKeyboard == null) - return; - - lock (DataModel) - { - lock (Profile) - { - // Get all enabled layers who's conditions are met - var renderLayers = GetRenderLayers(keyboardOnly); - - // If the profile has no active LUA wrapper, create one - if (!string.IsNullOrEmpty(Profile.LuaScript)) - Profile.Activate(LuaManager); - - // Render the keyboard layer-by-layer - var keyboardRect = DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale); - using (var g = Graphics.FromImage(frame.KeyboardBitmap)) - { - Profile?.DrawLayers(g, renderLayers.Where(rl => rl.LayerType.DrawType == DrawType.Keyboard), - DataModel, keyboardRect, false, true, "keyboard"); - } - // Render mice layer-by-layer - var devRec = new Rect(0, 0, 40, 40); - using (var g = Graphics.FromImage(frame.MouseBitmap)) - { - Profile?.DrawLayers(g, renderLayers.Where(rl => rl.LayerType.DrawType == DrawType.Mouse), - DataModel, devRec, false, true, "mouse"); - } - // Render headsets layer-by-layer - using (var g = Graphics.FromImage(frame.HeadsetBitmap)) - { - Profile?.DrawLayers(g, renderLayers.Where(rl => rl.LayerType.DrawType == DrawType.Headset), - DataModel, devRec, false, true, "headset"); - } - // Render generic devices layer-by-layer - using (var g = Graphics.FromImage(frame.GenericBitmap)) - { - Profile?.DrawLayers(g, renderLayers.Where(rl => rl.LayerType.DrawType == DrawType.Generic), - DataModel, devRec, false, true, "generic"); - } - // Render mousemats layer-by-layer - using (var g = Graphics.FromImage(frame.MousematBitmap)) - { - Profile?.DrawLayers(g, renderLayers.Where(rl => rl.LayerType.DrawType == DrawType.Mousemat), - DataModel, devRec, false, true, "mousemat"); - } - - // Trace debugging - if (DateTime.Now.AddSeconds(-2) <= LastTrace || Logger == null) - return; - - LastTrace = DateTime.Now; - var dmJson = JsonConvert.SerializeObject(DataModel, Formatting.Indented); - Logger.Trace("Effect datamodel as JSON: \r\n{0}", dmJson); - Logger.Trace("Effect {0} has to render {1} layers", Name, renderLayers.Count); - foreach (var renderLayer in renderLayers) - Logger.Trace("- Layer name: {0}, layer type: {1}", renderLayer.Name, renderLayer.LayerType); - } - } - } - - public abstract List GetRenderLayers(bool keyboardOnly); - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Models/GameModel.cs b/Artemis/Artemis/Models/GameModel.cs deleted file mode 100644 index 402669db8..000000000 --- a/Artemis/Artemis/Models/GameModel.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Artemis.Managers; -using Artemis.Models.Interfaces; -using Artemis.Settings; - -namespace Artemis.Models -{ - public abstract class GameModel : EffectModel - { - protected GameModel(DeviceManager deviceManager, LuaManager luaManager, GameSettings settings, - IDataModel dataModel) : base(deviceManager, luaManager, settings, dataModel) - { - // Override settings to the GameSettings type - Settings = settings; - } - - public new GameSettings Settings { get; set; } - public bool Enabled { get; set; } - public string ProcessName { get; set; } - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Models/Interfaces/IDataModel.cs b/Artemis/Artemis/Models/Interfaces/IDataModel.cs deleted file mode 100644 index 4e5a0ec07..000000000 --- a/Artemis/Artemis/Models/Interfaces/IDataModel.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Artemis.Models.Interfaces -{ - public interface IDataModel - { - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Models/OverlayModel.cs b/Artemis/Artemis/Models/OverlayModel.cs deleted file mode 100644 index 9935ab89b..000000000 --- a/Artemis/Artemis/Models/OverlayModel.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Artemis.Managers; -using Artemis.Settings; - -namespace Artemis.Models -{ - public abstract class OverlayModel : EffectModel - { - private bool _enabled; - public string ProcessName; - - protected OverlayModel(DeviceManager deviceManager, LuaManager luaManager, OverlaySettings settings) - : base(deviceManager, luaManager, settings, null) - { - Settings = settings; - Enabled = settings.Enabled; - } - - public bool Enabled - { - get { return _enabled; } - set - { - if (_enabled == value) - return; - - if (value) - Enable(); - else - Dispose(); - _enabled = value; - } - } - - public new OverlaySettings Settings { get; set; } - public abstract void RenderOverlay(RenderFrame frame, bool keyboardOnly); - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Abstract/ModuleDataModel.cs b/Artemis/Artemis/Modules/Abstract/ModuleDataModel.cs new file mode 100644 index 000000000..48fbf1135 --- /dev/null +++ b/Artemis/Artemis/Modules/Abstract/ModuleDataModel.cs @@ -0,0 +1,7 @@ +namespace Artemis.Modules.Abstract +{ + public abstract class ModuleDataModel + { + public ModuleDataModel ParentDataModel { get; set; } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Abstract/ModuleModel.cs b/Artemis/Artemis/Modules/Abstract/ModuleModel.cs new file mode 100644 index 000000000..8f70ba617 --- /dev/null +++ b/Artemis/Artemis/Modules/Abstract/ModuleModel.cs @@ -0,0 +1,189 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows; +using Artemis.DAL; +using Artemis.Events; +using Artemis.Managers; +using Artemis.Profiles; +using Artemis.Profiles.Layers.Interfaces; +using Artemis.Profiles.Layers.Models; +using Newtonsoft.Json; +using Ninject; +using Ninject.Extensions.Logging; + +namespace Artemis.Modules.Abstract +{ + public abstract class ModuleModel : IDisposable + { + private readonly LuaManager _luaManager; + protected readonly DeviceManager DeviceManager; + private DateTime _lastTrace; + + public ModuleModel(DeviceManager deviceManager, LuaManager luaManager) + { + _luaManager = luaManager; + + DeviceManager = deviceManager; + PreviewLayers = new List(); + + DeviceManager.OnKeyboardChanged += OnKeyboardChanged; + } + + #region Abstract properties + + /// + /// The module's name, used in setting files and logging + /// + public abstract string Name { get; } + + /// + /// Whether or not the module should be rendered as an overlay + /// + public abstract bool IsOverlay { get; } + + /// + /// Whether or not the module is enabled by a certain process + /// + public abstract bool IsBoundToProcess { get; } + + /// + /// The module's settings + /// + public ModuleSettings Settings { get; set; } + + /// + /// The module's data model + /// + public ModuleDataModel DataModel { get; set; } + + #endregion + + #region Base properties + + [Inject] + public ILogger Logger { get; set; } + + /// + /// Whether or not the module is initialized and ready to be updated/rendered + /// + public bool IsInitialized { get; protected set; } + + /// + /// If this collection contains any layers they will be drawn instead of the regular profile + /// + public List PreviewLayers { get; set; } + + /// + /// The process the module is bound to + /// + public string ProcessName { get; protected set; } + + /// + /// The currently active profile of the module + /// + public ProfileModel ProfileModel { get; protected set; } + + #endregion + + #region Base methods + + public void ChangeProfile(ProfileModel profileModel) + { + if (!IsInitialized || Equals(profileModel, ProfileModel)) + return; + + ProfileModel = profileModel; + ProfileModel?.Activate(_luaManager); + } + + public virtual void Enable() + { + IsInitialized = true; + ChangeToLastProfile(); + } + + public virtual void Dispose() + { + IsInitialized = false; + + PreviewLayers.Clear(); + ProfileModel?.Deactivate(_luaManager); + ProfileModel = null; + } + + private void OnKeyboardChanged(object sender, KeyboardChangedEventArgs e) + { + ChangeToLastProfile(); + } + + private void ChangeToLastProfile() + { + var profileName = !string.IsNullOrEmpty(Settings?.LastProfile) ? Settings.LastProfile : "Default"; + ChangeProfile(ProfileProvider.GetProfile(DeviceManager.ActiveKeyboard, this, profileName)); + } + + public abstract void Update(); + + public virtual void Render(RenderFrame frame, bool keyboardOnly) + { + if (ProfileModel == null || DataModel == null || DeviceManager.ActiveKeyboard == null) + return; + + lock (DataModel) + { + lock (ProfileModel) + { + // Get all enabled layers who's conditions are met + var layers = GetRenderLayers(keyboardOnly); + + // Render the keyboard layer-by-layer + var keyboardRect = DeviceManager.ActiveKeyboard.KeyboardRectangle(); + using (var g = Graphics.FromImage(frame.KeyboardBitmap)) + { + ProfileModel?.DrawLayers(g, layers, DrawType.Keyboard, DataModel, keyboardRect, false, true); + } + // Render mice layer-by-layer + var devRec = new Rect(0, 0, 40, 40); + using (var g = Graphics.FromImage(frame.MouseBitmap)) + { + ProfileModel?.DrawLayers(g, layers, DrawType.Mouse, DataModel, devRec, false, true); + } + // Render headsets layer-by-layer + using (var g = Graphics.FromImage(frame.HeadsetBitmap)) + { + ProfileModel?.DrawLayers(g, layers, DrawType.Headset, DataModel, devRec, false, true); + } + // Render generic devices layer-by-layer + using (var g = Graphics.FromImage(frame.GenericBitmap)) + { + ProfileModel?.DrawLayers(g, layers, DrawType.Generic, DataModel, devRec, false, true); + } + // Render mousemats layer-by-layer + using (var g = Graphics.FromImage(frame.MousematBitmap)) + { + ProfileModel?.DrawLayers(g, layers, DrawType.Mousemat, DataModel, devRec, false, true); + } + + // Trace debugging + if (DateTime.Now.AddSeconds(-2) <= _lastTrace || Logger == null) + return; + + _lastTrace = DateTime.Now; + var dmJson = JsonConvert.SerializeObject(DataModel, Formatting.Indented); + Logger.Trace("Effect datamodel as JSON: \r\n{0}", dmJson); + Logger.Trace("Effect {0} has to render {1} layers", Name, layers.Count); + foreach (var renderLayer in layers) + Logger.Trace("- Layer name: {0}, layer type: {1}", renderLayer.Name, renderLayer.LayerType); + } + } + } + + public virtual List GetRenderLayers(bool keyboardOnly) + { + return ProfileModel?.GetRenderLayers(DataModel, keyboardOnly); + } + + #endregion + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Settings/EffectSettings.cs b/Artemis/Artemis/Modules/Abstract/ModuleSettings.cs similarity index 68% rename from Artemis/Artemis/Settings/EffectSettings.cs rename to Artemis/Artemis/Modules/Abstract/ModuleSettings.cs index 82568e08f..76518ea44 100644 --- a/Artemis/Artemis/Settings/EffectSettings.cs +++ b/Artemis/Artemis/Modules/Abstract/ModuleSettings.cs @@ -1,29 +1,34 @@ -using System.ComponentModel; -using Artemis.DAL; -using Newtonsoft.Json; - -namespace Artemis.Settings -{ - public class EffectSettings : IArtemisSettings - { - [DefaultValue("Default")] - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] - public string LastProfile { get; set; } - - public void Save() - { - SettingsProvider.Save(this); - } - - public void Reset(bool save = false) - { - JsonConvert.PopulateObject("{}", this, new JsonSerializerSettings - { - ObjectCreationHandling = ObjectCreationHandling.Reuse - }); - - if (save) - SettingsProvider.Save(this); - } - } +using System.ComponentModel; +using Artemis.DAL; +using Artemis.Settings; +using Newtonsoft.Json; + +namespace Artemis.Modules.Abstract +{ + public abstract class ModuleSettings : IArtemisSettings + { + [DefaultValue(true)] + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] + public bool IsEnabled { get; set; } + + [DefaultValue("Default")] + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] + public string LastProfile { get; set; } + + public void Save() + { + SettingsProvider.Save(this); + } + + public void Reset(bool save = false) + { + JsonConvert.PopulateObject("{}", this, new JsonSerializerSettings + { + ObjectCreationHandling = ObjectCreationHandling.Reuse + }); + + if (save) + SettingsProvider.Save(this); + } + } } \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Abstract/ModuleViewModel.cs b/Artemis/Artemis/Modules/Abstract/ModuleViewModel.cs new file mode 100644 index 000000000..697b328f7 --- /dev/null +++ b/Artemis/Artemis/Modules/Abstract/ModuleViewModel.cs @@ -0,0 +1,137 @@ +using Artemis.Events; +using Artemis.Managers; +using Artemis.Services; +using Artemis.ViewModels.Profiles; +using Caliburn.Micro; +using Ninject; +using Ninject.Extensions.Logging; +using Ninject.Parameters; + +namespace Artemis.Modules.Abstract +{ + public abstract class ModuleViewModel : Screen + { + private readonly ModuleManager _moduleManager; + private readonly MainManager _mainManager; + private ModuleSettings _settings; + + public ModuleViewModel(MainManager mainManager, ModuleModel moduleModel, IKernel kernel) + { + _mainManager = mainManager; + _moduleManager = mainManager.ModuleManager; + ModuleModel = moduleModel; + + Settings = moduleModel.Settings; + IParameter[] args = + { + new ConstructorArgument("mainManager", _mainManager), + new ConstructorArgument("moduleModel", ModuleModel), + new ConstructorArgument("lastProfile", Settings.LastProfile) + }; + ProfileEditor = kernel.Get(args); + + _mainManager.EnabledChanged += MainManagerOnEnabledChanged; + _moduleManager.EffectChanged += ModuleManagerOnModuleChanged; + } + + public ProfileEditorViewModel ProfileEditor { get; set; } + public ModuleModel ModuleModel { get; } + + [Inject] + public ILogger Logger { get; set; } + + [Inject] + public MetroDialogService DialogService { get; set; } + + public ModuleSettings Settings + { + get { return _settings; } + set + { + if (Equals(value, _settings)) return; + _settings = value; + NotifyOfPropertyChange(() => Settings); + } + } + + public virtual bool IsModuleActive => _moduleManager.ActiveModule == ModuleModel; + public abstract bool UsesProfileEditor { get; } + + private void MainManagerOnEnabledChanged(object sender, EnabledChangedEventArgs e) + { + NotifyOfPropertyChange(() => IsModuleActive); + UpdateIsEnabled(); + } + + private void ModuleManagerOnModuleChanged(object sender, ModuleChangedEventArgs e) + { + NotifyOfPropertyChange(() => IsModuleActive); + UpdateIsEnabled(); + } + + private void UpdateIsEnabled() + { + if (ModuleModel.IsBoundToProcess || ModuleModel.IsOverlay) + return; + + Settings.IsEnabled = IsModuleActive; + Settings.Save(); + NotifyOfPropertyChange(() => Settings); + } + + public virtual void ToggleModule() + { + Settings.IsEnabled = !Settings.IsEnabled; + Settings.Save(); + NotifyOfPropertyChange(() => Settings); + + // On process-bound modules, only set the module model + if (ModuleModel.IsBoundToProcess || ModuleModel.IsOverlay) + return; + + // On other modules, activate them if necessary + if (IsModuleActive && !Settings.IsEnabled) + _moduleManager.ClearActiveModule(); + else if (!IsModuleActive && Settings.IsEnabled) + _moduleManager.ChangeActiveModule(ModuleModel, _mainManager.LoopManager); + } + + public virtual void SaveSettings() + { + Settings?.Save(); + if (UsesProfileEditor) + ProfileEditor.SaveSelectedProfile(); + if (!IsModuleActive) + return; + + // Restart the module if it's currently running to apply settings. + _moduleManager.ChangeActiveModule(ModuleModel); + } + + public virtual async void ResetSettings() + { + var resetConfirm = await DialogService.ShowQuestionMessageBox("Reset module settings", + "Are you sure you wish to reset this module's settings? \nAny changes you made will be lost."); + + if (!resetConfirm.Value) + return; + + Settings.Reset(true); + NotifyOfPropertyChange(() => Settings); + + SaveSettings(); + } + + protected override void OnActivate() + { + base.OnActivate(); + ProfileEditor.Activate(); + } + + protected override void OnDeactivate(bool close) + { + base.OnDeactivate(close); + ProfileEditor.Deactivate(); + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualizerView.xaml b/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualizerView.xaml deleted file mode 100644 index 826776468..000000000 --- a/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualizerView.xaml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualizerView.xaml.cs b/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualizerView.xaml.cs deleted file mode 100644 index 48d3709e2..000000000 --- a/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualizerView.xaml.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Windows.Controls; - -namespace Artemis.Modules.Effects.AudioVisualizer -{ - /// - /// Interaction logic for AudioVisualizerView.xaml - /// - public partial class AudioVisualizerView : UserControl - { - public AudioVisualizerView() - { - InitializeComponent(); - } - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Effects/Bubbles/Bubbles.cs b/Artemis/Artemis/Modules/Effects/Bubbles/Bubbles.cs deleted file mode 100644 index fceb0c983..000000000 --- a/Artemis/Artemis/Modules/Effects/Bubbles/Bubbles.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.ComponentModel; -using System.Configuration; - -namespace Artemis.Modules.Effects.Bubbles -{ - // This class allows you to handle specific events on the settings class: - // The SettingChanging event is raised before a setting's value is changed. - // The PropertyChanged event is raised after a setting's value is changed. - // The SettingsLoaded event is raised after the setting values are loaded. - // The SettingsSaving event is raised before the setting values are saved. - internal sealed partial class Bubbles - { - private void SettingChangingEventHandler(object sender, SettingChangingEventArgs e) - { - // Add code to handle the SettingChangingEvent event here. - } - - private void SettingsSavingEventHandler(object sender, CancelEventArgs e) - { - // Add code to handle the SettingsSaving event here. - } - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesModel.cs b/Artemis/Artemis/Modules/Effects/Bubbles/BubblesModel.cs deleted file mode 100644 index 3eb0f1e43..000000000 --- a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesModel.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Windows; -using Artemis.DAL; -using Artemis.Managers; -using Artemis.Models; -using Artemis.Profiles.Layers.Models; -using Artemis.Utilities; -using Point = System.Windows.Point; - -namespace Artemis.Modules.Effects.Bubbles -{ - public class BubblesModel : EffectModel - { - #region Constructors - - public BubblesModel(DeviceManager deviceManager, LuaManager luaManager) - : base(deviceManager, luaManager, SettingsProvider.Load(), null) - { - Name = "Bubbles"; - Initialized = false; - Settings = (BubblesSettings) base.Settings; - } - - #endregion - - #region Properties & Fields - - private static readonly Random _random = new Random(); - - private readonly List _bubbles = new List(); - - public new BubblesSettings Settings { get; } - - #endregion - - #region Methods - - public override void Enable() - { - KeyboardScale = Settings.Smoothness; - - var rect = DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale); - var scaleFactor = Settings.Smoothness / 25.0; - - for (var i = 0; i < Settings.BubbleCount; i++) - { - var color = Settings.IsRandomColors - ? ColorHelpers.GetRandomRainbowColor() - : ColorHelpers.ToDrawingColor(Settings.BubbleColor); - // -Settings.MoveSpeed because we want to spawn at least one move away from borders - var initialPositionX = (rect.Width - Settings.BubbleSize * scaleFactor * 2 - - Settings.MoveSpeed * scaleFactor) * - _random.NextDouble() + Settings.BubbleSize * scaleFactor; - var initialPositionY = (rect.Height - Settings.BubbleSize * scaleFactor * 2 - - Settings.MoveSpeed * scaleFactor) * - _random.NextDouble() + Settings.BubbleSize * scaleFactor; - var initialDirectionX = Settings.MoveSpeed * scaleFactor * _random.NextDouble() * - (_random.Next(1) == 0 ? -1 : 1); - var initialDirectionY = (Settings.MoveSpeed * scaleFactor - Math.Abs(initialDirectionX)) * - (_random.Next(1) == 0 ? -1 : 1); - - _bubbles.Add(new Bubble(color, (int) Math.Round(Settings.BubbleSize * scaleFactor), - new Point(initialPositionX, initialPositionY), new Vector(initialDirectionX, initialDirectionY))); - } - - Initialized = true; - } - - public override void Dispose() - { - _bubbles.Clear(); - Initialized = false; - } - - public override void Update() - { - var keyboardRectangle = DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale); - foreach (var bubble in _bubbles) - { - if (Settings.IsShiftColors) - bubble.Color = ColorHelpers.ShiftColor(bubble.Color, - Settings.IsRandomColors - ? (int) Math.Round(Settings.ShiftColorSpeed * _random.NextDouble()) - : Settings.ShiftColorSpeed); - - bubble.CheckCollision(keyboardRectangle); - bubble.Move(); - } - } - - public override void Render(RenderFrame frame, bool keyboardOnly) - { - using (var g = Graphics.FromImage(frame.KeyboardBitmap)) - { - foreach (var bubble in _bubbles) - bubble.Draw(g); - } - } - - public override List GetRenderLayers(bool keyboardOnly) - { - return null; - } - - #endregion - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs b/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs deleted file mode 100644 index d30118099..000000000 --- a/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Windows; -using Artemis.Managers; -using Artemis.Models; -using Artemis.Models.Interfaces; -using Artemis.Profiles.Layers.Interfaces; -using Artemis.Profiles.Layers.Models; -using Artemis.Profiles.Lua; -using Artemis.ViewModels.Profiles; -using Castle.Components.DictionaryAdapter; -using MoonSharp.Interpreter; - -namespace Artemis.Modules.Effects.ProfilePreview -{ - public class ProfilePreviewModel : EffectModel - { - public ProfilePreviewModel(DeviceManager deviceManager, LuaManager luaManager): base(deviceManager, luaManager, null, new ProfilePreviewDataModel()) - { - Name = "Profile Preview"; - } - - public ProfileViewModel ProfileViewModel { get; set; } - - public override void Dispose() - { - Initialized = false; - base.Dispose(); - } - - public override void Enable() - { - Initialized = true; - } - - public override void Update() - { - } - - public override List GetRenderLayers(bool keyboardOnly) - { - return ProfileViewModel != null ? ProfileViewModel.GetRenderLayers() : new EditableList(); - } - - public override void Render(RenderFrame frame, bool keyboardOnly) - { - if ((Profile == null) || (DataModel == null) || (DeviceManager.ActiveKeyboard == null)) - return; - - lock (DataModel) - { - // Get all enabled layers who's conditions are met - var renderLayers = GetRenderLayers(keyboardOnly); - - // If the profile has no active LUA wrapper, create one - if (!Equals(LuaManager.ProfileModel, Profile)) - Profile.Activate(LuaManager); - - // Render the keyboard layer-by-layer - var keyboardRect = DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale); - using (var g = Graphics.FromImage(frame.KeyboardBitmap)) - { - Profile?.DrawLayers(g, renderLayers.Where(rl => rl.LayerType.DrawType == DrawType.Keyboard), - DataModel, keyboardRect, true, true, "keyboard"); - } - // Render mice layer-by-layer - var devRec = new Rect(0, 0, 40, 40); - using (var g = Graphics.FromImage(frame.MouseBitmap)) - { - Profile?.DrawLayers(g, renderLayers.Where(rl => rl.LayerType.DrawType == DrawType.Mouse), DataModel, - devRec, true, true, "mouse"); - } - // Render headsets layer-by-layer - using (var g = Graphics.FromImage(frame.HeadsetBitmap)) - { - Profile?.DrawLayers(g, renderLayers.Where(rl => rl.LayerType.DrawType == DrawType.Headset), - DataModel, devRec, true, true, "headset"); - } - // Render generic devices layer-by-layer - using (var g = Graphics.FromImage(frame.GenericBitmap)) - { - Profile?.DrawLayers(g, renderLayers.Where(rl => rl.LayerType.DrawType == DrawType.Generic), - DataModel, devRec, true, true, "generic"); - } - // Render mousemats layer-by-layer - using (var g = Graphics.FromImage(frame.MousematBitmap)) - { - Profile?.DrawLayers(g, renderLayers.Where(rl => rl.LayerType.DrawType == DrawType.Mousemat), - DataModel, devRec, true, true, "mousemat"); - } - } - } - } - - [MoonSharpUserData] - public class ProfilePreviewDataModel : IDataModel - { - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileSettings.cs b/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileSettings.cs deleted file mode 100644 index adff6e1e7..000000000 --- a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileSettings.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Artemis.Settings; - -namespace Artemis.Modules.Effects.WindowsProfile -{ - public class WindowsProfileSettings : GameSettings - { - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileViewModel.cs b/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileViewModel.cs deleted file mode 100644 index 1f16bd4b4..000000000 --- a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileViewModel.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.ComponentModel; -using Artemis.Managers; -using Artemis.Models; -using Artemis.Modules.Effects.ProfilePreview; -using Artemis.ViewModels.Abstract; -using Artemis.ViewModels.Profiles; -using Ninject; -using Ninject.Parameters; - -namespace Artemis.Modules.Effects.WindowsProfile -{ - // TODO: This effect is a hybrid between a regular effect and a game, may want to clean this up - public sealed class WindowsProfileViewModel : EffectViewModel - { - public WindowsProfileViewModel(MainManager main, IKernel kernel, ProfilePreviewModel profilePreviewModel, - [Named("WindowsProfileModel")] EffectModel model) : base(main, model) - { - DisplayName = "Windows Profile"; - ProfilePreviewModel = profilePreviewModel; - EffectSettings = ((WindowsProfileModel) EffectModel).Settings; - - IParameter[] args = - { - new ConstructorArgument("mainManager", main), - new ConstructorArgument("effectModel", (WindowsProfileModel) EffectModel), - new ConstructorArgument("lastProfile", ((WindowsProfileSettings) EffectSettings).LastProfile) - }; - ProfileEditor = kernel.Get(args); - ProfileEditor.PropertyChanged += ProfileUpdater; - - EffectModel.Profile = ProfileEditor.SelectedProfile; - ProfilePreviewModel.Profile = ProfileEditor.SelectedProfile; - } - - public ProfileEditorViewModel ProfileEditor { get; set; } - public ProfilePreviewModel ProfilePreviewModel { get; set; } - - private void ProfileUpdater(object sender, PropertyChangedEventArgs e) - { - if ((e.PropertyName != "SelectedProfile") && IsActive) - return; - - EffectModel.Profile = ProfileEditor.SelectedProfile; - ProfilePreviewModel.Profile = ProfileEditor.SelectedProfile; - - if ((e.PropertyName != "SelectedProfile") || !ProfileEditor.ProfileViewModel.Activated || - (ProfileEditor.ProfileViewModel.SelectedProfile == null)) - return; - - ((WindowsProfileSettings) EffectSettings).LastProfile = ProfileEditor.ProfileViewModel.SelectedProfile.Name; - EffectSettings.Save(); - } - - public override void SaveSettings() - { - ProfileEditor.SaveSelectedProfile(); - base.SaveSettings(); - } - - protected override void OnActivate() - { - base.OnActivate(); - ProfileEditor.Activate(); - } - - protected override void OnDeactivate(bool close) - { - base.OnDeactivate(close); - ProfileEditor.Deactivate(); - } - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeDataModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeDataModel.cs index 546937029..769be1fc3 100644 --- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeDataModel.cs +++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeDataModel.cs @@ -1,11 +1,11 @@ -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; using MoonSharp.Interpreter; using Newtonsoft.Json; namespace Artemis.Modules.Games.CounterStrike { [MoonSharpUserData] - public class CounterStrikeDataModel : IDataModel + public class CounterStrikeDataModel : ModuleDataModel { public Provider provider { get; set; } public Map map { get; set; } diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs index cb4ffe5a4..284436c60 100644 --- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs +++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs @@ -1,10 +1,8 @@ using System; -using System.Collections.Generic; using System.IO; using Artemis.DAL; using Artemis.Managers; -using Artemis.Models; -using Artemis.Profiles.Layers.Models; +using Artemis.Modules.Abstract; using Artemis.Properties; using Artemis.Services; using Artemis.Utilities; @@ -13,7 +11,7 @@ using Newtonsoft.Json; namespace Artemis.Modules.Games.CounterStrike { - public class CounterStrikeModel : GameModel + public class CounterStrikeModel : ModuleModel { private readonly MetroDialogService _dialogService; private readonly GameStateWebServer _gameStateWebServer; @@ -22,40 +20,34 @@ namespace Artemis.Modules.Games.CounterStrike private DateTime _lastKill; private int _lastKills; - public CounterStrikeModel(DeviceManager deviceManager, LuaManager luaManager, - GameStateWebServer gameStateWebServer, MetroDialogService dialogService) - : base(deviceManager, luaManager, SettingsProvider.Load(), - new CounterStrikeDataModel()) + public CounterStrikeModel(DeviceManager deviceManager, LuaManager luaManager, MetroDialogService dialogService, + GameStateWebServer gameStateWebServer) : base(deviceManager, luaManager) { _gameStateWebServer = gameStateWebServer; _dialogService = dialogService; - Name = "CounterStrike"; + Settings = SettingsProvider.Load(); + DataModel = new CounterStrikeDataModel(); ProcessName = "csgo"; - Scale = 4; - Enabled = Settings.Enabled; - Initialized = false; FindGameDir(); PlaceConfigFile(); } - public int Scale { get; set; } + public override string Name => "CounterStrike"; + public override bool IsOverlay => false; + public override bool IsBoundToProcess => true; public override void Dispose() { - Initialized = false; - _gameStateWebServer.GameDataReceived -= HandleGameData; - base.Dispose(); + _gameStateWebServer.GameDataReceived -= HandleGameData; } public override void Enable() { - base.Enable(); - _gameStateWebServer.GameDataReceived += HandleGameData; - Initialized = true; + base.Enable(); } public override void Update() @@ -80,8 +72,10 @@ namespace Artemis.Modules.Games.CounterStrike dm.player.state.made_kill = true; _lastKill = DateTime.Now; } - else if (dm.player.state.made_kill && (DateTime.Now - _lastKill > TimeSpan.FromMilliseconds(500))) + else if (dm.player.state.made_kill && DateTime.Now - _lastKill > TimeSpan.FromMilliseconds(500)) + { dm.player.state.made_kill = false; + } _lastKills = dm.player.state.round_kills; // Detect a headshot @@ -90,8 +84,10 @@ namespace Artemis.Modules.Games.CounterStrike dm.player.state.made_headshot = true; _lastHeadshot = DateTime.Now; } - else if (dm.player.state.made_headshot && (DateTime.Now - _lastHeadshot > TimeSpan.FromMilliseconds(500))) + else if (dm.player.state.made_headshot && DateTime.Now - _lastHeadshot > TimeSpan.FromMilliseconds(500)) + { dm.player.state.made_headshot = false; + } _lastHeadshots = dm.player.state.round_killhs; // Detect a round win @@ -106,7 +102,7 @@ namespace Artemis.Modules.Games.CounterStrike { var gameSettings = (CounterStrikeSettings) Settings; // If already propertly set up, don't do anything - if ((gameSettings.GameDirectory != null) && File.Exists(gameSettings.GameDirectory + "csgo.exe") && + if (gameSettings.GameDirectory != null && File.Exists(gameSettings.GameDirectory + "csgo.exe") && File.Exists(gameSettings.GameDirectory + "/csgo/cfg/gamestate_integration_artemis.cfg")) return; @@ -159,11 +155,5 @@ namespace Artemis.Modules.Games.CounterStrike throw; } } - - - public override List GetRenderLayers(bool keyboardOnly) - { - return Profile.GetRenderLayers(DataModel, keyboardOnly); - } } } \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeSettings.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeSettings.cs index cb5d20c9b..d0845801f 100644 --- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeSettings.cs +++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeSettings.cs @@ -1,8 +1,9 @@ -using Artemis.Settings; +using Artemis.Modules.Abstract; +using Artemis.Settings; namespace Artemis.Modules.Games.CounterStrike { - public class CounterStrikeSettings : GameSettings + public class CounterStrikeSettings : ModuleSettings { public string GameDirectory { get; set; } } diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml index 8cc599305..52f0ef258 100644 --- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml +++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml @@ -28,11 +28,12 @@ - @@ -43,7 +44,7 @@ - public partial class WindowsProfileView : UserControl + public partial class GeneralProfileView : UserControl { - public WindowsProfileView() + public GeneralProfileView() { InitializeComponent(); } diff --git a/Artemis/Artemis/Modules/General/GeneralProfile/GeneralProfileViewModel.cs b/Artemis/Artemis/Modules/General/GeneralProfile/GeneralProfileViewModel.cs new file mode 100644 index 000000000..33bfd7de0 --- /dev/null +++ b/Artemis/Artemis/Modules/General/GeneralProfile/GeneralProfileViewModel.cs @@ -0,0 +1,17 @@ +using Artemis.Managers; +using Artemis.Modules.Abstract; +using Ninject; + +namespace Artemis.Modules.General.GeneralProfile +{ + public sealed class GeneralProfileViewModel : ModuleViewModel + { + public GeneralProfileViewModel(MainManager mainManager, [Named(nameof(GeneralProfileModel))] ModuleModel model, + IKernel kernel) : base(mainManager, model, kernel) + { + DisplayName = "General profile"; + } + + public override bool UsesProfileEditor => true; + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Effects/WindowsProfile/PerformanceInfo.cs b/Artemis/Artemis/Modules/General/GeneralProfile/PerformanceInfo.cs similarity index 97% rename from Artemis/Artemis/Modules/Effects/WindowsProfile/PerformanceInfo.cs rename to Artemis/Artemis/Modules/General/GeneralProfile/PerformanceInfo.cs index e807c6582..ef88e7064 100644 --- a/Artemis/Artemis/Modules/Effects/WindowsProfile/PerformanceInfo.cs +++ b/Artemis/Artemis/Modules/General/GeneralProfile/PerformanceInfo.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; -namespace Artemis.Modules.Effects.WindowsProfile +namespace Artemis.Modules.General.GeneralProfile { internal static class PerformanceInfo { diff --git a/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileDataModel.cs b/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileDataModel.cs new file mode 100644 index 000000000..4889d0a70 --- /dev/null +++ b/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileDataModel.cs @@ -0,0 +1,13 @@ +using Artemis.Modules.Abstract; +using Artemis.Modules.General.GeneralProfile; + +namespace Artemis.Modules.Overlays.OverlayProfile +{ + public class OverlayProfileDataModel : ModuleDataModel + { + public OverlayProfileDataModel() + { + ParentDataModel = new GeneralProfileDataModel(); + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileModel.cs b/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileModel.cs new file mode 100644 index 000000000..d8036d19f --- /dev/null +++ b/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileModel.cs @@ -0,0 +1,31 @@ +using Artemis.DAL; +using Artemis.Managers; +using Artemis.Modules.Abstract; +using Artemis.Modules.General.GeneralProfile; +using Ninject; + +namespace Artemis.Modules.Overlays.OverlayProfile +{ + public class OverlayProfileModel : ModuleModel + { + private readonly GeneralProfileModel _generalProfileModel; + + public OverlayProfileModel(DeviceManager deviceManager, LuaManager luaManager, + [Named(nameof(GeneralProfileModel))] ModuleModel generalProfileModel) : base(deviceManager, luaManager) + { + _generalProfileModel = (GeneralProfileModel) generalProfileModel; + Settings = SettingsProvider.Load(); + DataModel = new OverlayProfileDataModel(); + } + + public override string Name => "OverlayProfile"; + public override bool IsOverlay => true; + public override bool IsBoundToProcess => false; + + public override void Update() + { + // TODO: Find a clean way to update the parent profile model + DataModel.ParentDataModel = _generalProfileModel.DataModel; + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileSettings.cs b/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileSettings.cs new file mode 100644 index 000000000..a802554d9 --- /dev/null +++ b/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileSettings.cs @@ -0,0 +1,8 @@ +using Artemis.Modules.Abstract; + +namespace Artemis.Modules.Overlays.OverlayProfile +{ + public class OverlayProfileSettings : ModuleSettings + { + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileView.xaml b/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileView.xaml new file mode 100644 index 000000000..1d427a91c --- /dev/null +++ b/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileView.xaml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /// /// - public bool ConditionsMet(IDataModel dataModel) + public bool ConditionsMet(ModuleDataModel dataModel) { // Conditions are not even checked if the layer isn't enabled return Enabled && LayerCondition.ConditionsMet(this, dataModel); @@ -50,7 +50,7 @@ namespace Artemis.Profiles.Layers.Models /// /// /// - public void Update(IDataModel dataModel, bool preview, bool updateAnimations) + public void Update(ModuleDataModel dataModel, bool preview, bool updateAnimations) { if (LayerType == null) return; @@ -58,7 +58,7 @@ namespace Artemis.Profiles.Layers.Models LayerType.Update(this, dataModel, preview); LayerAnimation?.Update(this, updateAnimations); - if (!preview && updateAnimations) + if (!preview) TweenModel.Update(); LastRender = DateTime.Now; @@ -89,7 +89,7 @@ namespace Artemis.Profiles.Layers.Models /// /// /// - public void Draw(IDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations) + public void Draw(ModuleDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations) { if (Brush == null) return; @@ -257,7 +257,7 @@ namespace Artemis.Profiles.Layers.Models /// Whether or not to ignore anything but keyboards /// /// A flat list containing all layers that must be rendered - public List GetRenderLayers(IDataModel dataModel, bool keyboardOnly, bool ignoreConditions = false) + public List GetRenderLayers(ModuleDataModel dataModel, bool keyboardOnly, bool ignoreConditions = false) { var layers = new List(); foreach (var layerModel in Children.OrderByDescending(l => l.Order)) diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightType.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightType.cs index 5795bdbb0..d1170138b 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightType.cs @@ -3,7 +3,7 @@ using System.ComponentModel; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; @@ -52,7 +52,7 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight layerModel.Properties = new AmbientLightPropertiesModel(layerModel.Properties); } - public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) + public void Update(LayerModel layerModel, ModuleDataModel dataModel, bool isPreview = false) { var properties = layerModel?.Properties as AmbientLightPropertiesModel; if (properties == null) return; diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCaptureManager.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCaptureManager.cs index 8d1df47a1..04ca51a5d 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCaptureManager.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCaptureManager.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Artemis.Modules.Effects.AudioVisualizer.Utilities; using NAudio.CoreAudioApi; using NAudio.Dsp; using NAudio.Wave; diff --git a/Artemis/Artemis/Modules/Effects/AudioVisualizer/Utilities/FftEventArgs.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/FftEventArgs.cs similarity index 75% rename from Artemis/Artemis/Modules/Effects/AudioVisualizer/Utilities/FftEventArgs.cs rename to Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/FftEventArgs.cs index 01ce5163f..fb5466c7b 100644 --- a/Artemis/Artemis/Modules/Effects/AudioVisualizer/Utilities/FftEventArgs.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/FftEventArgs.cs @@ -1,8 +1,8 @@ -using System; +using System; using System.Diagnostics; using NAudio.Dsp; -namespace Artemis.Modules.Effects.AudioVisualizer.Utilities +namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing { public class FftEventArgs : EventArgs { diff --git a/Artemis/Artemis/Modules/Effects/AudioVisualizer/Utilities/SampleAggregator.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/SampleAggregator.cs similarity index 83% rename from Artemis/Artemis/Modules/Effects/AudioVisualizer/Utilities/SampleAggregator.cs rename to Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/SampleAggregator.cs index 14599c6be..ed286733a 100644 --- a/Artemis/Artemis/Modules/Effects/AudioVisualizer/Utilities/SampleAggregator.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/SampleAggregator.cs @@ -1,9 +1,8 @@ using System; using NAudio.Dsp; -namespace Artemis.Modules.Effects.AudioVisualizer.Utilities -{ // The Complex and FFT are here! - +namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing +{ public class SampleAggregator { private readonly FftEventArgs fftArgs; @@ -17,9 +16,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer.Utilities public SampleAggregator(int fftLength) { if (!IsPowerOfTwo(fftLength)) - { throw new ArgumentException("FFT Length must be a power of two"); - } m = (int) Math.Log(fftLength, 2.0); this.fftLength = fftLength; fftBuffer = new Complex[fftLength]; @@ -40,7 +37,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer.Utilities if (PerformFFT && FftCalculated != null) { // Remember the window function! There are many others as well. - fftBuffer[fftPos].X = (float) (value*FastFourierTransform.HammingWindow(fftPos, fftLength)); + fftBuffer[fftPos].X = (float) (value * FastFourierTransform.HammingWindow(fftPos, fftLength)); fftBuffer[fftPos].Y = 0; // This is always zero with audio. fftPos++; if (fftPos >= fftLength) diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs index 8aa99cefd..e2ee2999a 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Media; -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; @@ -77,7 +77,7 @@ namespace Artemis.Profiles.Layers.Types.Audio } } - public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) + public void Update(LayerModel layerModel, ModuleDataModel dataModel, bool isPreview = false) { layerModel.ApplyProperties(true); if (isPreview) diff --git a/Artemis/Artemis/Profiles/Layers/Types/Folder/FolderType.cs b/Artemis/Artemis/Profiles/Layers/Types/Folder/FolderType.cs index 2db638ead..52f5668c2 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Folder/FolderType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Folder/FolderType.cs @@ -1,6 +1,6 @@ using System.Windows; using System.Windows.Media; -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; @@ -32,7 +32,7 @@ namespace Artemis.Profiles.Layers.Types.Folder { } - public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) + public void Update(LayerModel layerModel, ModuleDataModel dataModel, bool isPreview = false) { } diff --git a/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericType.cs b/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericType.cs index 97fde86e3..04a01016e 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericType.cs @@ -1,7 +1,7 @@ using System.Linq; using System.Windows; using System.Windows.Media; -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Animations; using Artemis.Profiles.Layers.Interfaces; @@ -50,7 +50,7 @@ namespace Artemis.Profiles.Layers.Types.Generic c.Pop(); } - public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) + public void Update(LayerModel layerModel, ModuleDataModel dataModel, bool isPreview = false) { // Generic layers are always drawn 10*10 (which is 40*40 when scaled up) layerModel.Properties.Width = 10; diff --git a/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs b/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs index 76092cbea..1df4777bc 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs @@ -1,7 +1,7 @@ using System.Linq; using System.Windows; using System.Windows.Media; -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Animations; using Artemis.Profiles.Layers.Interfaces; @@ -50,7 +50,7 @@ namespace Artemis.Profiles.Layers.Types.Headset c.Pop(); } - public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) + public void Update(LayerModel layerModel, ModuleDataModel dataModel, bool isPreview = false) { // Headset layers are always drawn 10*10 (which is 40*40 when scaled up) layerModel.Properties.Width = 10; diff --git a/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs index 6c3628cd6..74f4d7cb0 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs @@ -5,7 +5,7 @@ using System.Windows; using System.Windows.Forms; using System.Windows.Media; using Artemis.Managers; -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Animations; using Artemis.Profiles.Layers.Interfaces; @@ -60,7 +60,7 @@ namespace Artemis.Profiles.Layers.Types.KeyPress } } - public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) + public void Update(LayerModel layerModel, ModuleDataModel dataModel, bool isPreview = false) { // Key press is always as large as the entire keyboard it is drawn for layerModel.Properties.Width = _deviceManager.ActiveKeyboard.Width; diff --git a/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardType.cs b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardType.cs index d1ef34882..6e6627d43 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardType.cs @@ -1,6 +1,6 @@ using System.Windows; using System.Windows.Media; -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Animations; using Artemis.Profiles.Layers.Interfaces; @@ -59,7 +59,7 @@ namespace Artemis.Profiles.Layers.Types.Keyboard c.Pop(); } - public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) + public void Update(LayerModel layerModel, ModuleDataModel dataModel, bool isPreview = false) { layerModel.ApplyProperties(true); if (isPreview || dataModel == null) diff --git a/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs b/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs index 4245d5350..bd0527a47 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs @@ -2,7 +2,7 @@ using System.IO; using System.Windows; using System.Windows.Media; -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; @@ -56,10 +56,10 @@ namespace Artemis.Profiles.Layers.Types.KeyboardGif } } - public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) + public void Update(LayerModel layerModel, ModuleDataModel dataModel, bool isPreview = false) { layerModel.ApplyProperties(true); - if (isPreview) + if (isPreview || dataModel == null) return; // If not previewing, apply dynamic properties according to datamodel diff --git a/Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs b/Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs index 14b74f57b..df6d46592 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs @@ -1,7 +1,7 @@ using System.Linq; using System.Windows; using System.Windows.Media; -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Animations; using Artemis.Profiles.Layers.Interfaces; @@ -52,7 +52,7 @@ namespace Artemis.Profiles.Layers.Types.Mouse c.Pop(); } - public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) + public void Update(LayerModel layerModel, ModuleDataModel dataModel, bool isPreview = false) { // Mouse layers are always drawn 10*10 (which is 40*40 when scaled up) layerModel.Properties.Width = 10; diff --git a/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematType.cs b/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematType.cs index d4986e7c0..58583e475 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematType.cs @@ -1,7 +1,7 @@ using System.Linq; using System.Windows; using System.Windows.Media; -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Animations; using Artemis.Profiles.Layers.Interfaces; @@ -50,7 +50,7 @@ namespace Artemis.Profiles.Layers.Types.Mousemat c.Pop(); } - public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) + public void Update(LayerModel layerModel, ModuleDataModel dataModel, bool isPreview = false) { // Mousemat layers are always drawn 10*10 (which is 40*40 when scaled up) layerModel.Properties.Width = 10; diff --git a/Artemis/Artemis/Profiles/Lua/Modules/Events/LuaDeviceDrawingEventArgs.cs b/Artemis/Artemis/Profiles/Lua/Modules/Events/LuaDeviceDrawingEventArgs.cs index 3c5681a4d..3f46148e9 100644 --- a/Artemis/Artemis/Profiles/Lua/Modules/Events/LuaDeviceDrawingEventArgs.cs +++ b/Artemis/Artemis/Profiles/Lua/Modules/Events/LuaDeviceDrawingEventArgs.cs @@ -1,5 +1,5 @@ using System; -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; using Artemis.Profiles.Lua.Wrappers; using MoonSharp.Interpreter; @@ -8,7 +8,7 @@ namespace Artemis.Profiles.Lua.Modules.Events [MoonSharpUserData] public class LuaDeviceDrawingEventArgs : EventArgs { - public LuaDeviceDrawingEventArgs(string deviceType, IDataModel dataModel, bool preview, + public LuaDeviceDrawingEventArgs(string deviceType, ModuleDataModel dataModel, bool preview, LuaDrawWrapper luaDrawWrapper) { DeviceType = deviceType; @@ -18,7 +18,7 @@ namespace Artemis.Profiles.Lua.Modules.Events } public string DeviceType { get; set; } - public IDataModel DataModel { get; } + public ModuleDataModel DataModel { get; } public bool Preview { get; } public LuaDrawWrapper Drawing { get; set; } } diff --git a/Artemis/Artemis/Profiles/Lua/Modules/Events/LuaDeviceUpdatingEventArgs.cs b/Artemis/Artemis/Profiles/Lua/Modules/Events/LuaDeviceUpdatingEventArgs.cs index 58945694f..83a500c41 100644 --- a/Artemis/Artemis/Profiles/Lua/Modules/Events/LuaDeviceUpdatingEventArgs.cs +++ b/Artemis/Artemis/Profiles/Lua/Modules/Events/LuaDeviceUpdatingEventArgs.cs @@ -1,5 +1,5 @@ using System; -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; using MoonSharp.Interpreter; namespace Artemis.Profiles.Lua.Modules.Events @@ -7,7 +7,7 @@ namespace Artemis.Profiles.Lua.Modules.Events [MoonSharpUserData] public class LuaDeviceUpdatingEventArgs : EventArgs { - public LuaDeviceUpdatingEventArgs(string deviceType, IDataModel dataModel, bool preview) + public LuaDeviceUpdatingEventArgs(string deviceType, ModuleDataModel dataModel, bool preview) { DeviceType = deviceType; DataModel = dataModel; @@ -15,7 +15,7 @@ namespace Artemis.Profiles.Lua.Modules.Events } public string DeviceType { get; set; } - public IDataModel DataModel { get; } + public ModuleDataModel DataModel { get; } public bool Preview { get; } } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Lua/Modules/LuaLayerModule.cs b/Artemis/Artemis/Profiles/Lua/Modules/LuaLayerModule.cs index 77b99e7c8..f7e42ea1d 100644 --- a/Artemis/Artemis/Profiles/Lua/Modules/LuaLayerModule.cs +++ b/Artemis/Artemis/Profiles/Lua/Modules/LuaLayerModule.cs @@ -2,7 +2,6 @@ using System.Linq; using System.Windows.Media; using Artemis.Managers; -using Artemis.Modules.Effects.ProfilePreview; using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Lua.Modules.Brushes; using Artemis.Profiles.Lua.Wrappers; @@ -21,7 +20,7 @@ namespace Artemis.Profiles.Lua.Modules SavedProperties = new Wrappers.LuaLayerProperties(_layerModel); // Trigger an update to fill up the Properties - _layerModel.Update(new ProfilePreviewDataModel(), true, false); + _layerModel.Update(null, true, false); } public override string ModuleName => "Layer"; diff --git a/Artemis/Artemis/Profiles/Lua/Wrappers/LuaLayerWrapper.cs b/Artemis/Artemis/Profiles/Lua/Wrappers/LuaLayerWrapper.cs index 25a44a777..d107f57ff 100644 --- a/Artemis/Artemis/Profiles/Lua/Wrappers/LuaLayerWrapper.cs +++ b/Artemis/Artemis/Profiles/Lua/Wrappers/LuaLayerWrapper.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Linq; using System.Windows.Media; -using Artemis.Modules.Effects.ProfilePreview; using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Lua.Modules.Brushes; using MoonSharp.Interpreter; @@ -22,7 +21,7 @@ namespace Artemis.Profiles.Lua.Wrappers SavedProperties = new LuaLayerProperties(layerModel); // Triger an update to fill up the Properties - _layerModel.Update(new ProfilePreviewDataModel(), true, false); + _layerModel.Update(null, true, false); } #region Child methods diff --git a/Artemis/Artemis/Profiles/ProfileModel.cs b/Artemis/Artemis/Profiles/ProfileModel.cs index da2f65901..b4ee3b625 100644 --- a/Artemis/Artemis/Profiles/ProfileModel.cs +++ b/Artemis/Artemis/Profiles/ProfileModel.cs @@ -8,7 +8,7 @@ using System.Windows.Media; using Artemis.DeviceProviders; using Artemis.Events; using Artemis.Managers; -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; using Artemis.Utilities; @@ -71,12 +71,12 @@ namespace Artemis.Profiles /// Generates a flat list containing all layers that must be rendered on the keyboard, /// the first mouse layer to be rendered and the first headset layer to be rendered /// - /// The game data model to base the conditions on /// Instance of said game data model /// Whether or not to ignore anything but keyboards /// /// A flat list containing all layers that must be rendered - public List GetRenderLayers(IDataModel dataModel, bool keyboardOnly, bool ignoreConditions = false) + public List GetRenderLayers(ModuleDataModel dataModel, bool keyboardOnly, + bool ignoreConditions = false) { var layers = new List(); foreach (var layerModel in Layers.OrderByDescending(l => l.Order)) @@ -85,10 +85,8 @@ namespace Artemis.Profiles continue; if (!ignoreConditions) - { if (!layerModel.ConditionsMet(dataModel)) continue; - } layers.Add(layerModel); layers.AddRange(layerModel.GetRenderLayers(dataModel, keyboardOnly, ignoreConditions)); @@ -102,14 +100,15 @@ namespace Artemis.Profiles /// /// The graphics to draw on /// The layers to render + /// The type of device to draw for /// The data model to base the layer's properties on /// A rectangle matching the current keyboard's size on a scale of 4, used for clipping /// Indicates wheter the layer is drawn as a preview, ignoring dynamic properties /// Wheter or not to update the layer's animations - /// The type of layers that are being updated, for reference in LUA - internal void DrawLayers(Graphics g, IEnumerable renderLayers, IDataModel dataModel, Rect rect, - bool preview, bool updateAnimations, string updateType) + internal void DrawLayers(Graphics g, List renderLayers, DrawType drawType, ModuleDataModel dataModel, + Rect rect, bool preview, bool updateAnimations) { + renderLayers = renderLayers.Where(rl => rl.LayerType.DrawType == drawType).ToList(); var visual = new DrawingVisual(); var layerModels = renderLayers.ToList(); using (var c = visual.RenderOpen()) @@ -121,12 +120,12 @@ namespace Artemis.Profiles // Update the layers foreach (var layerModel in layerModels) layerModel.Update(dataModel, preview, updateAnimations); - RaiseDeviceUpdatedEvent(new ProfileDeviceEventsArg(updateType, dataModel, preview, null)); + RaiseDeviceUpdatedEvent(new ProfileDeviceEventsArg(drawType, dataModel, preview, null)); // Draw the layers foreach (var layerModel in layerModels) layerModel.Draw(dataModel, c, preview, updateAnimations); - RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(updateType, dataModel, preview, c)); + RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(drawType, dataModel, preview, c)); // Remove the clip c.Pop(); diff --git a/Artemis/Artemis/Settings/GameSettings.cs b/Artemis/Artemis/Settings/GameSettings.cs deleted file mode 100644 index aa0c8015f..000000000 --- a/Artemis/Artemis/Settings/GameSettings.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.ComponentModel; -using Newtonsoft.Json; - -namespace Artemis.Settings -{ - public abstract class GameSettings : EffectSettings - { - [DefaultValue(true)] - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] - public bool Enabled { get; set; } - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Settings/GeneralSettings.cs b/Artemis/Artemis/Settings/GeneralSettings.cs index b8cf81ee0..e9e16ea9c 100644 --- a/Artemis/Artemis/Settings/GeneralSettings.cs +++ b/Artemis/Artemis/Settings/GeneralSettings.cs @@ -20,9 +20,9 @@ namespace Artemis.Settings ApplyAutorun(); } - [DefaultValue("WindowsProfile")] + [DefaultValue("GeneralProfile")] [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] - public string LastEffect { get; set; } + public string LastModule { get; set; } [DefaultValue(null)] [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] diff --git a/Artemis/Artemis/Settings/OverlaySettings.cs b/Artemis/Artemis/Settings/OverlaySettings.cs deleted file mode 100644 index efc7486c6..000000000 --- a/Artemis/Artemis/Settings/OverlaySettings.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.ComponentModel; -using Newtonsoft.Json; - -namespace Artemis.Settings -{ - public class OverlaySettings : EffectSettings - { - [DefaultValue(true)] - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] - public bool Enabled { get; set; } - } -} \ No newline at end of file diff --git a/Artemis/Artemis/Utilities/Keyboard/KeyboardRectangle.cs b/Artemis/Artemis/Utilities/Keyboard/KeyboardRectangle.cs deleted file mode 100644 index ae443a4d6..000000000 --- a/Artemis/Artemis/Utilities/Keyboard/KeyboardRectangle.cs +++ /dev/null @@ -1,195 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Drawing.Drawing2D; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Artemis.DeviceProviders; - -namespace Artemis.Utilities.Keyboard -{ - // TODO: Obsolete - public class KeyboardRectangle - { - private readonly BackgroundWorker _blinkWorker = new BackgroundWorker {WorkerSupportsCancellation = true}; - private readonly KeyboardProvider _keyboard; - private int _blinkDelay; - private double _rotationProgress; - - /// - /// Represents a Rectangle on the keyboard which can be drawn to a Bitmap. - /// By default, a rectangle is the entire keyboard's size. - /// - /// The keyboard this rectangle will be used for - /// - /// - /// An array of colors the ColorBlend will use - /// - public KeyboardRectangle(KeyboardProvider keyboard, int x, int y, List colors, - LinearGradientMode gradientMode) - { - _keyboard = keyboard; - _rotationProgress = 0; - _blinkWorker.DoWork += BlinkWorker_DoWork; - - Scale = 4; - X = x; - Y = y; - Width = keyboard.Width*Scale; - Height = keyboard.Height*Scale; - Visible = true; - Opacity = 255; - - ContainedBrush = true; - GradientMode = gradientMode; - Rotate = false; - LoopSpeed = 1; - Colors = colors; - } - - public int X { get; set; } - public int Y { get; set; } - public int Width { get; set; } - public int Height { get; set; } - public bool Visible { get; set; } - public byte Opacity { get; set; } // TODO: Remove - - /// - /// Sets wether or not the colors should be contained within the rectangle, or span the entire keyboard. - /// - public bool ContainedBrush { get; set; } - - /// - /// Used when ContainedBrush is set to false to make sure the colors span the entire keyboard on a higher scale. - /// - public int Scale { get; set; } - - /// - /// Determines what grientmode to use in the LinearGradientBrush. - /// - public LinearGradientMode GradientMode { get; set; } - - /// - /// Wether or not to rotate the colors over the brush. - /// - public bool Rotate { get; set; } - - /// - /// What speed to ratate the colors on. - /// - public double LoopSpeed { get; set; } - - /// - /// Colors used on the brush. - /// - public List Colors { get; set; } - - public void StartBlink(int delay) - { - _blinkDelay = delay; - - if (!_blinkWorker.IsBusy) - _blinkWorker.RunWorkerAsync(); - } - - public void StartBlink(int delay, int time) - { - StartBlink(delay); - Task.Factory.StartNew(() => - { - Thread.Sleep(delay); - StopBlink(); - }); - } - - public void StopBlink() - { - if (_blinkWorker.IsBusy) - _blinkWorker.CancelAsync(); - } - - private void BlinkWorker_DoWork(object sender, DoWorkEventArgs e) - { - while (!_blinkWorker.CancellationPending) - { - Thread.Sleep(_blinkDelay); - Visible = !Visible; - } - Visible = true; - } - - public void Draw(Graphics g) - { - if (!Visible || Height < 1 || Width < 1 || !Colors.Any()) - return; - - var brush = CreateBrush(); - var baseRect = new Rectangle(X, Y, Width, Height); - - g.FillRectangle(brush, baseRect); - if (!Rotate) - return; - - _rotationProgress = _rotationProgress + LoopSpeed; - if (ContainedBrush && _rotationProgress > Width) - _rotationProgress = LoopSpeed; - else if (!ContainedBrush && _rotationProgress > _keyboard.Width*Scale) - _rotationProgress = LoopSpeed; - } - - private LinearGradientBrush CreateBrush() - { - var colorBlend = CreateColorBlend(); - RectangleF rect; - if (Rotate) - rect = ContainedBrush - ? new Rectangle((int) _rotationProgress, Y, Width*2, Height*2) - : new Rectangle((int) _rotationProgress, 0, _keyboard.Width*Scale*2, _keyboard.Height*Scale*2); - else - rect = ContainedBrush - ? new Rectangle(X, Y, Width, Height) - : new Rectangle(0, 0, _keyboard.Width*Scale, _keyboard.Height*Scale); - - return new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, GradientMode) - { - InterpolationColors = colorBlend - }; - } - - private ColorBlend CreateColorBlend() - { - if (Colors.Count == 1) - return new ColorBlend {Colors = new[] {Colors[0], Colors[0]}, Positions = new[] {0F, 1F}}; - var colorBlend = Rotate - ? new ColorBlend {Colors = CreateTilebleColors(Colors).ToArray()} - : new ColorBlend {Colors = Colors.ToArray()}; - - // If needed, apply opacity to the colors in the blend - if (Opacity < 255) - for (var i = 0; i < colorBlend.Colors.Length; i++) - colorBlend.Colors[i] = Color.FromArgb(Opacity, colorBlend.Colors[i]); - - // Devide the colors over the colorblend - var devider = (float) colorBlend.Colors.Length - 1; - var positions = new List(); - for (var i = 0; i < colorBlend.Colors.Length; i++) - positions.Add(i/devider); - - // Apply the devided positions - colorBlend.Positions = positions.ToArray(); - return colorBlend; - } - - private List CreateTilebleColors(List sourceColors) - { - // Create a list using the original colors - var tilebleColors = new List(sourceColors); - // Add the original colors again - tilebleColors.AddRange(sourceColors); - // Add the first color, smoothing the transition - tilebleColors.Add(sourceColors.FirstOrDefault()); - return tilebleColors; - } - } -} \ No newline at end of file diff --git a/Artemis/Artemis/ViewModels/Abstract/EffectViewModel.cs b/Artemis/Artemis/ViewModels/Abstract/EffectViewModel.cs deleted file mode 100644 index 89e9ec09e..000000000 --- a/Artemis/Artemis/ViewModels/Abstract/EffectViewModel.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using Artemis.DAL; -using Artemis.Events; -using Artemis.Managers; -using Artemis.Models; -using Artemis.Services; -using Artemis.Settings; -using Caliburn.Micro; -using Ninject; - -namespace Artemis.ViewModels.Abstract -{ - public abstract class EffectViewModel : Screen - { - protected readonly EffectModel EffectModel; - private EffectSettings _effectSettings; - private bool _showDisabledPopup; - protected MainManager MainManager; - - protected EffectViewModel(MainManager mainManager, EffectModel effectModel) - { - MainManager = mainManager; - EffectModel = effectModel; - EffectSettings = effectModel.Settings; - - MainManager.OnEnabledChangedEvent += MainManagerOnOnEnabledChangedEvent; - MainManager.EffectManager.OnEffectChangedEvent += EffectManagerOnOnEffectChangedEvent; - } - - private void MainManagerOnOnEnabledChangedEvent(object sender, EnabledChangedEventArgs e) - { - NotifyOfPropertyChange(() => EffectEnabled); - } - - private void EffectManagerOnOnEffectChangedEvent(object sender, EffectChangedEventArgs e) - { - NotifyOfPropertyChange(() => EffectEnabled); - } - - [Inject] - public MetroDialogService DialogService { get; set; } - - public EffectSettings EffectSettings - { - get { return _effectSettings; } - set - { - if (Equals(value, _effectSettings)) return; - _effectSettings = value; - NotifyOfPropertyChange(() => EffectSettings); - } - } - - public bool EffectEnabled => MainManager.EffectManager.ActiveEffect == EffectModel; - - public bool ShowDisabledPopup - { - get { return _showDisabledPopup; } - set - { - if (value == _showDisabledPopup) return; - _showDisabledPopup = value; - NotifyOfPropertyChange(() => ShowDisabledPopup); - } - } - - public void ToggleEffect() - { - if (!MainManager.ProgramEnabled) - { - NotifyOfPropertyChange(() => EffectEnabled); - ShowDisabledPopup = true; - return; - } - - if (EffectEnabled) - MainManager.EffectManager.ClearEffect(); - else - MainManager.EffectManager.ChangeEffect(EffectModel, MainManager.LoopManager); - } - - public virtual void SaveSettings() - { - EffectSettings?.Save(); - if (!EffectEnabled) - return; - - // Restart the effect if it's currently running to apply settings. - MainManager.EffectManager.ChangeEffect(EffectModel); - } - - public async void ResetSettings() - { - var resetConfirm = 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; - - EffectSettings.Reset(true); - NotifyOfPropertyChange(() => EffectSettings); - - SaveSettings(); - } - } -} \ No newline at end of file diff --git a/Artemis/Artemis/ViewModels/Abstract/GameViewModel.cs b/Artemis/Artemis/ViewModels/Abstract/GameViewModel.cs deleted file mode 100644 index 6c8a9703d..000000000 --- a/Artemis/Artemis/ViewModels/Abstract/GameViewModel.cs +++ /dev/null @@ -1,128 +0,0 @@ -using System.ComponentModel; -using System.Timers; -using Artemis.Managers; -using Artemis.Models; -using Artemis.Modules.Effects.ProfilePreview; -using Artemis.Services; -using Artemis.Settings; -using Artemis.ViewModels.Profiles; -using Caliburn.Micro; -using Ninject; -using Ninject.Extensions.Logging; -using Ninject.Parameters; - -namespace Artemis.ViewModels.Abstract -{ - public abstract class GameViewModel : Screen - { - private GameSettings _gameSettings; - - protected GameViewModel(MainManager mainManager, GameModel gameModel, IKernel kernel) - { - MainManager = mainManager; - GameModel = gameModel; - GameSettings = gameModel.Settings; - - IParameter[] args = - { - new ConstructorArgument("mainManager", mainManager), - new ConstructorArgument("effectModel", gameModel), - new ConstructorArgument("lastProfile", GameSettings.LastProfile) - }; - ProfileEditor = kernel.Get(args); - ProfileEditor.PropertyChanged += ProfileUpdater; - - GameModel.Profile = ProfileEditor.SelectedProfile; - } - - [Inject] - public ILogger Logger { get; set; } - - [Inject] - public ProfilePreviewModel ProfilePreviewModel { get; set; } - - [Inject] - public MetroDialogService DialogService { get; set; } - - public ProfileEditorViewModel ProfileEditor { get; set; } - - public GameModel GameModel { get; set; } - public MainManager MainManager { get; set; } - - public GameSettings GameSettings - { - get { return _gameSettings; } - set - { - if (Equals(value, _gameSettings)) return; - _gameSettings = value; - NotifyOfPropertyChange(() => GameSettings); - } - } - - public bool GameEnabled => MainManager.EffectManager.ActiveEffect.Name == GameModel.Name; - - public void ToggleEffect() - { - GameModel.Enabled = GameSettings.Enabled; - } - - public void SaveSettings() - { - GameSettings?.Save(); - ProfileEditor.SaveSelectedProfile(); - - if (!GameEnabled) - return; - - // Restart the game if it's currently running to apply settings. - MainManager.EffectManager.ChangeEffect(GameModel, MainManager.LoopManager); - } - - public async void ResetSettings() - { - var resetConfirm = - 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; - - GameSettings.Reset(true); - NotifyOfPropertyChange(() => GameSettings); - - SaveSettings(); - } - - private void ProfileUpdater(object sender, PropertyChangedEventArgs e) - { - if ((e.PropertyName != "SelectedProfile") && IsActive) - return; - - GameModel.Profile = ProfileEditor.SelectedProfile; - ProfilePreviewModel.Profile = ProfileEditor.SelectedProfile; - - // Only update the last selected profile if it the editor was active and the new profile isn't null - if ((e.PropertyName != "SelectedProfile") || !ProfileEditor.ProfileViewModel.Activated || - (ProfileEditor.ProfileViewModel.SelectedProfile == null)) - return; - - GameSettings.LastProfile = ProfileEditor.ProfileViewModel.SelectedProfile.Name; - GameSettings.Save(); - } - - protected override void OnActivate() - { - base.OnActivate(); - ProfileEditor.Activate(); - } - - protected override void OnDeactivate(bool close) - { - base.OnDeactivate(close); - ProfileEditor.Deactivate(); - } - } - - public delegate void OnLayersUpdatedCallback(object sender); -} \ No newline at end of file diff --git a/Artemis/Artemis/ViewModels/Abstract/OverlayViewModel.cs b/Artemis/Artemis/ViewModels/Abstract/OverlayViewModel.cs deleted file mode 100644 index 7d0a315cd..000000000 --- a/Artemis/Artemis/ViewModels/Abstract/OverlayViewModel.cs +++ /dev/null @@ -1,64 +0,0 @@ -using Artemis.Managers; -using Artemis.Models; -using Artemis.Services; -using Artemis.Settings; -using Caliburn.Micro; -using Ninject; - -namespace Artemis.ViewModels.Abstract -{ - public abstract class OverlayViewModel : Screen - { - protected readonly MainManager MainManager; - private OverlaySettings _overlaySettings; - - protected OverlayViewModel(MainManager mainManager, OverlayModel overlayModel) - { - MainManager = mainManager; - OverlayModel = overlayModel; - OverlaySettings = overlayModel.Settings; - } - - [Inject] - public MetroDialogService DialogService { get; set; } - - public OverlayModel OverlayModel { get; set; } - - public OverlaySettings OverlaySettings - { - get { return _overlaySettings; } - set - { - if (Equals(value, _overlaySettings)) return; - _overlaySettings = value; - NotifyOfPropertyChange(() => OverlaySettings); - } - } - - public void ToggleOverlay() - { - OverlayModel.Enabled = OverlaySettings.Enabled; - } - - public void SaveSettings() - { - OverlaySettings?.Save(); - } - - public async void ResetSettings() - { - var resetConfirm = await - 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) - return; - - OverlaySettings.Reset(true); - NotifyOfPropertyChange(() => OverlaySettings); - - OverlayModel.Enabled = OverlaySettings.Enabled; - SaveSettings(); - } - } -} \ No newline at end of file diff --git a/Artemis/Artemis/ViewModels/EffectsViewModel.cs b/Artemis/Artemis/ViewModels/EffectsViewModel.cs deleted file mode 100644 index 5f41ea4a3..000000000 --- a/Artemis/Artemis/ViewModels/EffectsViewModel.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Linq; -using Artemis.ViewModels.Abstract; - -namespace Artemis.ViewModels -{ - public sealed class EffectsViewModel : BaseViewModel - { - private IOrderedEnumerable _vms; - - public EffectsViewModel(EffectViewModel[] effectViewModels) - { - DisplayName = "Effects"; - - _vms = effectViewModels.OrderBy(o => o.DisplayName); - } - - protected override void OnActivate() - { - base.OnActivate(); - Items.Clear(); - Items.AddRange(_vms); - } - } -} \ No newline at end of file diff --git a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs index cda9415c9..1f9e8c4ad 100644 --- a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs +++ b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs @@ -40,8 +40,8 @@ namespace Artemis.ViewModels.Flyouts LogLevels.AddRange(LogLevel.AllLoggingLevels.Select(l => l.Name)); PropertyChanged += KeyboardUpdater; - mainManager.OnEnabledChangedEvent += MainManagerOnOnEnabledChangedEvent; - mainManager.EffectManager.OnEffectChangedEvent += EffectManagerOnOnEffectChangedEvent; + mainManager.EnabledChanged += MainManagerEnabledChanged; + mainManager.ModuleManager.EffectChanged += EffectManagerEffectChanged; } public MainManager MainManager { get; set; } @@ -162,14 +162,14 @@ namespace Artemis.ViewModels.Flyouts } } - private void MainManagerOnOnEnabledChangedEvent(object sender, EnabledChangedEventArgs enabledChangedEventArgs) + private void MainManagerEnabledChanged(object sender, EnabledChangedEventArgs enabledChangedEventArgs) { NotifyOfPropertyChange(() => Enabled); } - private void EffectManagerOnOnEffectChangedEvent(object sender, EffectChangedEventArgs e) + private void EffectManagerEffectChanged(object sender, ModuleChangedEventArgs e) { - var effectDisplay = string.IsNullOrEmpty(e.Effect?.Name) ? "none" : e.Effect.Name; + var effectDisplay = string.IsNullOrEmpty(e.Module?.Name) ? "none" : e.Module.Name; ActiveEffectName = $"Active effect: {effectDisplay}"; } diff --git a/Artemis/Artemis/ViewModels/GamesViewModel.cs b/Artemis/Artemis/ViewModels/GamesViewModel.cs index 6aac8e4e5..68a5d6041 100644 --- a/Artemis/Artemis/ViewModels/GamesViewModel.cs +++ b/Artemis/Artemis/ViewModels/GamesViewModel.cs @@ -1,7 +1,8 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using Artemis.DAL; using Artemis.Managers; -using Artemis.Modules.Effects.ProfilePreview; +using Artemis.Modules.Abstract; using Artemis.Settings; using Artemis.ViewModels.Abstract; @@ -9,21 +10,24 @@ namespace Artemis.ViewModels { public sealed class GamesViewModel : BaseViewModel { - private readonly IOrderedEnumerable _vms; + private readonly List _vms; - public GamesViewModel(GameViewModel[] gameViewModels, ProfileManager profileManager, - ProfilePreviewModel profilePreviewModel) + public GamesViewModel(IEnumerable moduleViewModels) { DisplayName = "Games"; // Currently WoW is locked behind a hidden trigger (obviously not that hidden since you're reading this) // It is using memory reading and lets first try to contact Blizzard - _vms = SettingsProvider.Load().GamestatePort == 62575 - ? gameViewModels.OrderBy(g => g.DisplayName) - : gameViewModels.Where(g => g.DisplayName != "WoW").OrderBy(g => g.DisplayName); - - profileManager.ProfilePreviewModel = profilePreviewModel; - profileManager.GameViewModels.AddRange(_vms); + if (SettingsProvider.Load().GamestatePort == 62575) + { + _vms = moduleViewModels.Where(m => m.ModuleModel.IsBoundToProcess) + .OrderBy(g => g.DisplayName).ToList(); + } + else + { + _vms = moduleViewModels.Where(m => m.ModuleModel.IsBoundToProcess && m.DisplayName != "WoW") + .OrderBy(g => g.DisplayName).ToList(); + } } protected override void OnActivate() diff --git a/Artemis/Artemis/ViewModels/GeneralViewModel.cs b/Artemis/Artemis/ViewModels/GeneralViewModel.cs new file mode 100644 index 000000000..f800712fe --- /dev/null +++ b/Artemis/Artemis/ViewModels/GeneralViewModel.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Linq; +using Artemis.Managers; +using Artemis.Modules.Abstract; +using Artemis.ViewModels.Abstract; + +namespace Artemis.ViewModels +{ + public sealed class GeneralViewModel : BaseViewModel + { + private readonly List _vms; + + public GeneralViewModel(List moduleViewModels, ProfileManager profileManager) + { + DisplayName = "General"; + _vms = moduleViewModels.Where(m => !m.ModuleModel.IsOverlay && !m.ModuleModel.IsBoundToProcess) + .OrderBy(m => m.DisplayName).ToList(); + + profileManager.PreviewViewModules.Clear(); + profileManager.PreviewViewModules.AddRange(moduleViewModels.Where(m => m.UsesProfileEditor)); + } + + protected override void OnActivate() + { + base.OnActivate(); + Items.Clear(); + Items.AddRange(_vms); + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/ViewModels/OverlaysViewModel.cs b/Artemis/Artemis/ViewModels/OverlaysViewModel.cs index cb7d93271..5844d44ff 100644 --- a/Artemis/Artemis/ViewModels/OverlaysViewModel.cs +++ b/Artemis/Artemis/ViewModels/OverlaysViewModel.cs @@ -1,16 +1,18 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; +using Artemis.Modules.Abstract; using Artemis.ViewModels.Abstract; namespace Artemis.ViewModels { public sealed class OverlaysViewModel : BaseViewModel { - private IOrderedEnumerable _vms; + private readonly List _vms; - public OverlaysViewModel(OverlayViewModel[] overlayViewModels) + public OverlaysViewModel(IEnumerable moduleViewModels) { DisplayName = "Overlays"; - _vms = overlayViewModels.OrderBy(o => o.DisplayName); + _vms = moduleViewModels.Where(m => m.ModuleModel.IsOverlay).OrderBy(m => m.DisplayName).ToList(); } protected override void OnActivate() diff --git a/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs index edea36331..035fd42ad 100644 --- a/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs +++ b/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; -using Artemis.Models.Interfaces; +using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; @@ -26,7 +26,7 @@ namespace Artemis.ViewModels.Profiles private LayerModel _proposedLayer; private ILayerType _selectedLayerType; - public LayerEditorViewModel(LayerModel layer, IDataModel dataModel, IEnumerable types, + public LayerEditorViewModel(LayerModel layer, ModuleDataModel dataModel, IEnumerable types, IEnumerable layerAnimations) { Layer = layer; diff --git a/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs index 1a6a8d678..82882ec80 100644 --- a/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs +++ b/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs @@ -14,7 +14,7 @@ using Artemis.DAL; using Artemis.DeviceProviders; using Artemis.Events; using Artemis.Managers; -using Artemis.Models; +using Artemis.Modules.Abstract; using Artemis.Profiles; using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Layers.Types.Folder; @@ -23,10 +23,8 @@ using Artemis.Services; using Artemis.Styles.DropTargetAdorners; using Artemis.Utilities; using Caliburn.Micro; -using Castle.Core.Internal; using GongSolutions.Wpf.DragDrop; using MahApps.Metro.Controls.Dialogs; -using Ninject; using Ninject.Parameters; using NuGet; using DragDropEffects = System.Windows.DragDropEffects; @@ -40,34 +38,33 @@ namespace Artemis.ViewModels.Profiles public sealed class ProfileEditorViewModel : Screen, IDropTarget { private readonly DeviceManager _deviceManager; - private readonly EffectModel _effectModel; private readonly LuaManager _luaManager; + private readonly ModuleModel _moduleModel; private readonly Timer _saveTimer; + private readonly MetroDialogService _dialogService; + private readonly WindowService _windowService; private ImageSource _keyboardPreview; private ObservableCollection _layers; private ObservableCollection _profileNames; private bool _saving; - private ProfileModel _selectedProfile; private FileSystemWatcher _watcher; - public ProfileEditorViewModel(DeviceManager deviceManager, LuaManager luaManager, EffectModel effectModel, - ProfileViewModel profileViewModel, MetroDialogService dialogService, WindowService windowService, - string lastProfile) + public ProfileEditorViewModel(DeviceManager deviceManager, LuaManager luaManager, ModuleModel moduleModel, + ProfileViewModel profileViewModel, MetroDialogService dialogService, WindowService windowService) { _deviceManager = deviceManager; _luaManager = luaManager; - _effectModel = effectModel; + _moduleModel = moduleModel; + _dialogService = dialogService; + _windowService = windowService; ProfileNames = new ObservableCollection(); Layers = new ObservableCollection(); ProfileViewModel = profileViewModel; - DialogService = dialogService; - WindowService = windowService; - LastProfile = lastProfile; PropertyChanged += EditorStateHandler; ProfileViewModel.PropertyChanged += LayerSelectedHandler; - _deviceManager.OnKeyboardChangedEvent += DeviceManagerOnOnKeyboardChangedEvent; + _deviceManager.OnKeyboardChanged += DeviceManagerOnOnKeyboardChanged; _saveTimer = new Timer(5000); _saveTimer.Elapsed += ProfileSaveHandler; @@ -75,17 +72,14 @@ namespace Artemis.ViewModels.Profiles LoadProfiles(); } - [Inject] - public MetroDialogService DialogService { get; set; } - - public WindowService WindowService { get; set; } - - public string LastProfile { get; set; } - public ProfileViewModel ProfileViewModel { get; set; } public bool EditorEnabled - => SelectedProfile != null && !SelectedProfile.IsDefault && _deviceManager.ActiveKeyboard != null; + => + SelectedProfile != null && !SelectedProfile.IsDefault && + _deviceManager.ActiveKeyboard != null; + + public ProfileModel SelectedProfile => _moduleModel?.ProfileModel; public ObservableCollection ProfileNames { @@ -117,36 +111,9 @@ namespace Artemis.ViewModels.Profiles if (value == SelectedProfile?.Name) return; - SelectedProfile = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _effectModel, value); + _moduleModel.ChangeProfile(ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _moduleModel, value)); NotifyOfPropertyChange(() => SelectedProfileName); - } - } - - public ProfileModel SelectedProfile - { - get { return _selectedProfile; } - set - { - if (Equals(value, _selectedProfile)) - return; - - if (IsActive) - { - // Deactivate old profile - _selectedProfile?.Deactivate(_luaManager); - // Update the value - _selectedProfile = value; - // Activate new profile - _selectedProfile?.Activate(_luaManager); - } - else - { - // Update the value - _selectedProfile = value; - } - NotifyOfPropertyChange(() => SelectedProfile); - NotifyOfPropertyChange(() => SelectedProfileName); } } @@ -237,7 +204,7 @@ namespace Artemis.ViewModels.Profiles /// /// Handles chaning the active keyboard, updating the preview image and profiles collection /// - private void DeviceManagerOnOnKeyboardChangedEvent(object sender, KeyboardChangedEventArgs e) + private void DeviceManagerOnOnKeyboardChanged(object sender, KeyboardChangedEventArgs e) { NotifyOfPropertyChange(() => PreviewSettings); LoadProfiles(); @@ -245,7 +212,6 @@ namespace Artemis.ViewModels.Profiles public void Activate() { - _selectedProfile?.Activate(_luaManager); ProfileViewModel.Activate(); _saveTimer.Start(); } @@ -265,22 +231,10 @@ namespace Artemis.ViewModels.Profiles Execute.OnUIThread(() => { ProfileNames.Clear(); - if (_effectModel == null || _deviceManager.ActiveKeyboard == null) - return; + if (_moduleModel != null && _deviceManager.ActiveKeyboard != null) + ProfileNames.AddRange(ProfileProvider.GetProfileNames(_deviceManager.ActiveKeyboard, _moduleModel)); - ProfileNames.AddRange(ProfileProvider.GetProfileNames(_deviceManager.ActiveKeyboard, _effectModel)); - - // If a profile name was provided, try to load it - ProfileModel lastProfileModel = null; - if (!string.IsNullOrEmpty(LastProfile)) - lastProfileModel = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _effectModel, - LastProfile); - - if (lastProfileModel != null) - SelectedProfile = lastProfileModel; - else - SelectedProfile = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _effectModel, - ProfileNames.FirstOrDefault()); + NotifyOfPropertyChange(() => SelectedProfile); }); } @@ -313,10 +267,10 @@ namespace Artemis.ViewModels.Profiles IParameter[] args = { - new ConstructorArgument("dataModel", _effectModel.DataModel), + new ConstructorArgument("dataModel", _moduleModel.DataModel), new ConstructorArgument("layer", layer) }; - WindowService.ShowDialog(args); + _windowService.ShowDialog(args); // If the layer was a folder, but isn't anymore, assign it's children to it's parent. if (!(layer.LayerType is FolderType) && layer.Children.Any()) @@ -410,7 +364,7 @@ namespace Artemis.ViewModels.Profiles var newName = await - DialogService.ShowInputDialog("Rename layer", "Please enter a name for the layer", + _dialogService.ShowInputDialog("Rename layer", "Please enter a name for the layer", new MetroDialogSettings {DefaultText = layer.Name}); // Null when the user cancelled if (string.IsNullOrEmpty(newName)) @@ -498,12 +452,12 @@ namespace Artemis.ViewModels.Profiles { if (_deviceManager.ActiveKeyboard == null) { - DialogService.ShowMessageBox("Cannot add profile.", + _dialogService.ShowMessageBox("Cannot add profile.", "To add a profile, please select a keyboard in the options menu first."); return; } - var name = await DialogService.ShowInputDialog("Add new profile", + var name = await _dialogService.ShowInputDialog("Add new profile", "Please provide a profile name unique to this game and keyboard."); // Null when the user cancelled @@ -512,7 +466,7 @@ namespace Artemis.ViewModels.Profiles if (name.Length < 2) { - DialogService.ShowMessageBox("Invalid profile name", "Please provide a valid profile name"); + _dialogService.ShowMessageBox("Invalid profile name", "Please provide a valid profile name"); return; } @@ -522,12 +476,12 @@ namespace Artemis.ViewModels.Profiles KeyboardSlug = _deviceManager.ActiveKeyboard.Slug, Width = _deviceManager.ActiveKeyboard.Width, Height = _deviceManager.ActiveKeyboard.Height, - GameName = _effectModel.Name + GameName = _moduleModel.Name }; if (!ProfileProvider.IsProfileUnique(profile)) { - var overwrite = await 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; @@ -535,7 +489,6 @@ namespace Artemis.ViewModels.Profiles ProfileProvider.AddOrUpdate(profile); - LastProfile = profile.Name; LoadProfiles(); } @@ -545,7 +498,7 @@ namespace Artemis.ViewModels.Profiles return; var oldName = SelectedProfile.Name; - var name = await DialogService.ShowInputDialog("Rename profile", "Please enter a unique new profile name"); + var name = await _dialogService.ShowInputDialog("Rename profile", "Please enter a unique new profile name"); // Null when the user cancelled if (string.IsNullOrEmpty(name) || name.Length < 2) @@ -556,7 +509,7 @@ namespace Artemis.ViewModels.Profiles // Verify the name while (!ProfileProvider.IsProfileUnique(SelectedProfile)) { - name = await DialogService + name = await _dialogService .ShowInputDialog("Name already in use", "Please enter a unique new profile name"); // Null when the user cancelled @@ -571,8 +524,6 @@ namespace Artemis.ViewModels.Profiles var profile = SelectedProfile; ProfileProvider.RenameProfile(profile, name); - SelectedProfile = null; - LastProfile = name; LoadProfiles(); } @@ -582,7 +533,7 @@ namespace Artemis.ViewModels.Profiles return; var newProfile = GeneralHelpers.Clone(SelectedProfile); - newProfile.Name = await DialogService + newProfile.Name = await _dialogService .ShowInputDialog("Duplicate profile", "Please enter a unique profile name"); // Null when the user cancelled @@ -592,7 +543,7 @@ namespace Artemis.ViewModels.Profiles // Verify the name while (!ProfileProvider.IsProfileUnique(newProfile)) { - newProfile.Name = await DialogService + newProfile.Name = await _dialogService .ShowInputDialog("Name already in use", "Please enter a unique profile name"); // Null when the user cancelled @@ -602,7 +553,6 @@ namespace Artemis.ViewModels.Profiles newProfile.IsDefault = false; ProfileProvider.AddOrUpdate(newProfile); - LastProfile = newProfile.Name; LoadProfiles(); } @@ -612,13 +562,18 @@ namespace Artemis.ViewModels.Profiles return; var confirm = await - DialogService.ShowQuestionMessageBox("Delete profile", + _dialogService.ShowQuestionMessageBox("Delete profile", $"Are you sure you want to delete the profile named: {SelectedProfile.Name}?\n\n" + "This cannot be undone."); if (!confirm.Value) return; - ProfileProvider.DeleteProfile(SelectedProfile); + var defaultProfile = ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _moduleModel, "Default"); + var deleteProfile = SelectedProfile; + + _moduleModel.ChangeProfile(defaultProfile); + ProfileProvider.DeleteProfile(deleteProfile); + LoadProfiles(); } @@ -626,7 +581,7 @@ namespace Artemis.ViewModels.Profiles { if (_deviceManager.ActiveKeyboard == null) { - DialogService.ShowMessageBox("Cannot import profile.", + _dialogService.ShowMessageBox("Cannot import profile.", "To import a profile, please select a keyboard in the options menu first."); return; } @@ -638,16 +593,16 @@ namespace Artemis.ViewModels.Profiles var profile = ProfileProvider.LoadProfileIfValid(dialog.FileName); if (profile == null) { - DialogService.ShowErrorMessageBox("Oh noes, the profile you provided is invalid. " + - "If this keeps happening, please make an issue on GitHub and provide the profile."); + _dialogService.ShowErrorMessageBox("Oh noes, the profile you provided is invalid. " + + "If this keeps happening, please make an issue on GitHub and provide the profile."); return; } // Verify the game - if (profile.GameName != _effectModel.Name) + if (profile.GameName != _moduleModel.Name) { - DialogService.ShowErrorMessageBox( - $"Oh oops! This profile is ment for {profile.GameName}, not {_effectModel.Name} :c"); + _dialogService.ShowErrorMessageBox( + $"Oh oops! This profile is ment for {profile.GameName}, not {_moduleModel.Name} :c"); return; } @@ -655,7 +610,8 @@ namespace Artemis.ViewModels.Profiles var deviceManager = _deviceManager; if (profile.KeyboardSlug != deviceManager.ActiveKeyboard.Slug) { - var adjustKeyboard = await DialogService.ShowQuestionMessageBox("Profile not inteded for this keyboard", + var adjustKeyboard = await _dialogService.ShowQuestionMessageBox( + "Profile not inteded for this keyboard", $"Watch out, this profile wasn't ment for this keyboard, but for the {profile.KeyboardSlug}. " + "You can still import it but you'll probably have to do some adjusting\n\n" + "Continue?"); @@ -678,7 +634,7 @@ namespace Artemis.ViewModels.Profiles // Verify the name while (!ProfileProvider.IsProfileUnique(profile)) { - profile.Name = await DialogService.ShowInputDialog("Rename imported profile", + profile.Name = await _dialogService.ShowInputDialog("Rename imported profile", "A profile with this name already exists for this game. Please enter a new name"); // Null when the user cancelled @@ -687,7 +643,6 @@ namespace Artemis.ViewModels.Profiles } ProfileProvider.AddOrUpdate(profile); - LastProfile = profile.Name; LoadProfiles(); } @@ -714,7 +669,7 @@ namespace Artemis.ViewModels.Profiles } catch (Exception e) { - DialogService.ShowMessageBox("Couldn't open LUA file", + _dialogService.ShowMessageBox("Couldn't open LUA file", "Please make sure you have a text editor associated with the .lua extension.\n\n" + "Windows error message: \n" + e.Message); } @@ -727,8 +682,6 @@ namespace Artemis.ViewModels.Profiles // Update editor enabled state NotifyOfPropertyChange(() => EditorEnabled); - // Update ProfileViewModel - ProfileViewModel.SelectedProfile = SelectedProfile; // Update interface Layers.Clear(); @@ -768,66 +721,66 @@ namespace Artemis.ViewModels.Profiles _saving = false; } - #region LUA Editor - - public void OpenEditor() - { - if (SelectedProfile == null) - return; - - // Create a temp file - var fileName = Guid.NewGuid() + ".lua"; - var file = File.Create(Path.GetTempPath() + fileName); - file.Dispose(); - - // Add instructions to LUA script if it's a new file - if (SelectedProfile.LuaScript.IsNullOrEmpty()) - SelectedProfile.LuaScript = Encoding.UTF8.GetString(Resources.lua_placeholder); - File.WriteAllText(Path.GetTempPath() + fileName, SelectedProfile.LuaScript); - - // Watch the file for changes - SetupWatcher(Path.GetTempPath(), fileName); - - // Open the temp file with the default editor - System.Diagnostics.Process.Start(Path.GetTempPath() + fileName); - } - - private void SetupWatcher(string path, string fileName) - { - if (_watcher == null) - { - _watcher = new FileSystemWatcher(Path.GetTempPath(), fileName); - _watcher.Changed += LuaFileChanged; - _watcher.EnableRaisingEvents = true; - } - - _watcher.Path = path; - _watcher.Filter = fileName; - } - - private void LuaFileChanged(object sender, FileSystemEventArgs args) - { - if (args.ChangeType != WatcherChangeTypes.Changed) - return; - - if (SelectedProfile == null) - return; - - lock (SelectedProfile) - { - using (var fs = new FileStream(args.FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - { - using (var sr = new StreamReader(fs)) - { - SelectedProfile.LuaScript = sr.ReadToEnd(); - } - } - - ProfileProvider.AddOrUpdate(SelectedProfile); - _luaManager.SetupLua(SelectedProfile); - } - } - + #region LUA Editor + + public void OpenEditor() + { + if (SelectedProfile == null) + return; + + // Create a temp file + var fileName = Guid.NewGuid() + ".lua"; + var file = File.Create(Path.GetTempPath() + fileName); + file.Dispose(); + + // Add instructions to LUA script if it's a new file + if (string.IsNullOrEmpty(SelectedProfile.LuaScript)) + SelectedProfile.LuaScript = Encoding.UTF8.GetString(Resources.lua_placeholder); + File.WriteAllText(Path.GetTempPath() + fileName, SelectedProfile.LuaScript); + + // Watch the file for changes + SetupWatcher(Path.GetTempPath(), fileName); + + // Open the temp file with the default editor + System.Diagnostics.Process.Start(Path.GetTempPath() + fileName); + } + + private void SetupWatcher(string path, string fileName) + { + if (_watcher == null) + { + _watcher = new FileSystemWatcher(Path.GetTempPath(), fileName); + _watcher.Changed += LuaFileChanged; + _watcher.EnableRaisingEvents = true; + } + + _watcher.Path = path; + _watcher.Filter = fileName; + } + + private void LuaFileChanged(object sender, FileSystemEventArgs args) + { + if (args.ChangeType != WatcherChangeTypes.Changed) + return; + + if (SelectedProfile == null) + return; + + lock (SelectedProfile) + { + using (var fs = new FileStream(args.FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + using (var sr = new StreamReader(fs)) + { + SelectedProfile.LuaScript = sr.ReadToEnd(); + } + } + + ProfileProvider.AddOrUpdate(SelectedProfile); + _luaManager.SetupLua(SelectedProfile); + } + } + #endregion } } \ No newline at end of file diff --git a/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs index 219136b0e..f25ccf9da 100644 --- a/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs +++ b/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs @@ -7,8 +7,8 @@ using System.Windows.Input; using System.Windows.Media; using Artemis.Events; using Artemis.Managers; -using Artemis.Modules.Effects.ProfilePreview; using Artemis.Profiles; +using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Layers.Types.Folder; using Artemis.Properties; @@ -40,7 +40,7 @@ namespace Artemis.ViewModels.Profiles ShowAll = false; loopManager.RenderCompleted += LoopManagerOnRenderCompleted; - deviceManager.OnKeyboardChangedEvent += DeviceManagerOnOnKeyboardChangedEvent; + deviceManager.OnKeyboardChanged += DeviceManagerOnOnKeyboardChanged; } public ProfileModel SelectedProfile { get; set; } @@ -166,8 +166,8 @@ namespace Artemis.ViewModels.Profiles new Point(layerRect.BottomRight.X - 0.7, layerRect.BottomRight.Y - 0.7)); } - SelectedProfile.RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg("preview", - new ProfilePreviewDataModel(), true, drawingContext)); + SelectedProfile.RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(DrawType.Preview, null, true, + drawingContext)); // Remove the clip drawingContext.Pop(); @@ -178,7 +178,7 @@ namespace Artemis.ViewModels.Profiles KeyboardPreview = drawnPreview; } - private void DeviceManagerOnOnKeyboardChangedEvent(object sender, KeyboardChangedEventArgs e) + private void DeviceManagerOnOnKeyboardChanged(object sender, KeyboardChangedEventArgs e) { NotifyOfPropertyChange(() => KeyboardImage); } @@ -356,13 +356,13 @@ namespace Artemis.ViewModels.Profiles // Get the layers that must be drawn List drawLayers; if (ShowAll) - return SelectedProfile.GetRenderLayers(new ProfilePreviewDataModel(), false, true); + return SelectedProfile.GetRenderLayers(null, false, true); if (SelectedLayer == null || !SelectedLayer.Enabled) return new EditableList(); if (SelectedLayer.LayerType is FolderType) - drawLayers = SelectedLayer.GetRenderLayers(new ProfilePreviewDataModel(), false, true); + drawLayers = SelectedLayer.GetRenderLayers(null, false, true); else drawLayers = new List {SelectedLayer}; diff --git a/Artemis/Artemis/ViewModels/ShellViewModel.cs b/Artemis/Artemis/ViewModels/ShellViewModel.cs index 163fdb432..ffdf07735 100644 --- a/Artemis/Artemis/ViewModels/ShellViewModel.cs +++ b/Artemis/Artemis/ViewModels/ShellViewModel.cs @@ -42,7 +42,7 @@ namespace Artemis.ViewModels flyoutSettings }; - MainManager.OnEnabledChangedEvent += (sender, args) => Enabled = args.Enabled; + MainManager.EnabledChanged += (sender, args) => Enabled = args.Enabled; // This gets updated automatically but during startup lets quickly preset it Enabled = GeneralSettings.Suspended; diff --git a/Artemis/Artemis/Views/EffectsView.xaml b/Artemis/Artemis/Views/GeneralView.xaml similarity index 94% rename from Artemis/Artemis/Views/EffectsView.xaml rename to Artemis/Artemis/Views/GeneralView.xaml index cf0b791bf..a2e24e6f8 100644 --- a/Artemis/Artemis/Views/EffectsView.xaml +++ b/Artemis/Artemis/Views/GeneralView.xaml @@ -1,4 +1,4 @@ - /// Interaction logic for EffectsView.xaml /// - public partial class EffectsView : UserControl + public partial class GeneralView : UserControl { - public EffectsView() + public GeneralView() { InitializeComponent(); } diff --git a/Artemis/Artemis/packages.config b/Artemis/Artemis/packages.config index 6faac38d1..507184401 100644 --- a/Artemis/Artemis/packages.config +++ b/Artemis/Artemis/packages.config @@ -1,10 +1,10 @@  - - + + - + @@ -21,12 +21,12 @@ - - + + - +