diff --git a/Artemis/Artemis.sln b/Artemis/Artemis.sln index 180e87f3f..69fb5b679 100644 --- a/Artemis/Artemis.sln +++ b/Artemis/Artemis.sln @@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColorBox", "ColorBox\ColorB EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LogiLed2Artemis", "LogiLed2Artemis\LogiLed2Artemis.vcxproj", "{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis86Wrapper", "Artemis86Wrapper\Artemis86Wrapper.csproj", "{47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution CD_ROM|Any CPU = CD_ROM|Any CPU @@ -146,6 +148,36 @@ Global {D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.SingleImage|x64.Build.0 = Release|x64 {D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.SingleImage|x86.ActiveCfg = Release|Win32 {D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.SingleImage|x86.Build.0 = Release|Win32 + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.CD_ROM|Any CPU.ActiveCfg = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.CD_ROM|Any CPU.Build.0 = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.CD_ROM|x64.ActiveCfg = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.CD_ROM|x64.Build.0 = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.CD_ROM|x86.ActiveCfg = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.CD_ROM|x86.Build.0 = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.Debug|x64.ActiveCfg = Debug|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.Debug|x64.Build.0 = Debug|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.Debug|x86.ActiveCfg = Debug|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.Debug|x86.Build.0 = Debug|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.DVD-5|Any CPU.ActiveCfg = Debug|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.DVD-5|Any CPU.Build.0 = Debug|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.DVD-5|x64.ActiveCfg = Debug|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.DVD-5|x64.Build.0 = Debug|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.DVD-5|x86.ActiveCfg = Debug|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.DVD-5|x86.Build.0 = Debug|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.Release|Any CPU.Build.0 = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.Release|x64.ActiveCfg = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.Release|x64.Build.0 = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.Release|x86.ActiveCfg = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.Release|x86.Build.0 = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.SingleImage|Any CPU.ActiveCfg = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.SingleImage|Any CPU.Build.0 = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.SingleImage|x64.ActiveCfg = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.SingleImage|x64.Build.0 = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.SingleImage|x86.ActiveCfg = Release|Any CPU + {47A9BBFD-4BEA-4D7D-8AB7-896E760B2CF2}.SingleImage|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Artemis/Artemis/App.xaml.cs b/Artemis/Artemis/App.xaml.cs index f6b42a8e5..3d53eec5c 100644 --- a/Artemis/Artemis/App.xaml.cs +++ b/Artemis/Artemis/App.xaml.cs @@ -38,7 +38,7 @@ namespace Artemis } } - private static ExceptionViewer GetArtemisExceptionViewer(Exception e) + public static ExceptionViewer GetArtemisExceptionViewer(Exception e) { var logger = LogManager.GetCurrentClassLogger(); logger.Fatal(e, "Unhandled exception, showing dialog and shutting down."); diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index 198390572..f68851e2e 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -127,6 +127,10 @@ LocalIntranet + + ..\packages\Betwixt.1.4.1\lib\net35\Betwixt.dll + True + ..\packages\Caliburn.Micro.Core.3.0.1\lib\net45\Caliburn.Micro.dll True @@ -318,10 +322,11 @@ + - - - + + + @@ -339,7 +344,7 @@ - + @@ -403,6 +408,7 @@ + @@ -425,6 +431,7 @@ + AudioPropertiesView.xaml @@ -597,6 +604,7 @@ + @@ -669,6 +677,9 @@ VolumeDisplayView.xaml + + LayerTweenView.xaml + ProfileEditorView.xaml @@ -686,6 +697,7 @@ Code + @@ -911,6 +923,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/Artemis/Artemis/ArtemisBootstrapper.cs b/Artemis/Artemis/ArtemisBootstrapper.cs index 23efdc1bf..30f3b2d3c 100644 --- a/Artemis/Artemis/ArtemisBootstrapper.cs +++ b/Artemis/Artemis/ArtemisBootstrapper.cs @@ -8,9 +8,9 @@ using Artemis.InjectionModules; using Artemis.Settings; using Artemis.Utilities; using Artemis.Utilities.Converters; +using Artemis.Utilities.DataReaders; using Artemis.ViewModels; using Caliburn.Micro; -using MoonSharp.Interpreter; using Newtonsoft.Json; using Ninject; @@ -24,6 +24,8 @@ namespace Artemis { // Start logging before anything else Logging.SetupLogging(SettingsProvider.Load().LogLevel); + // Restore DDLs before interacting with any SDKs + DllManager.RestoreLogitechDll(); Initialize(); BindSpecialValues(); diff --git a/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProL.cs b/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProL.cs index e2e95528f..dbc939d47 100644 --- a/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProL.cs +++ b/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProL.cs @@ -58,7 +58,7 @@ namespace Artemis.DeviceProviders.CoolerMaster using (var b = ImageUtilities.ResizeImage(bitmap, Width, Height)) { // Create an empty matrix - var matrix = new COLOR_MATRIX {KeyColor = new KEY_COLOR[Height, Width]}; + var matrix = new COLOR_MATRIX {KeyColor = new KEY_COLOR[6, 22]}; // Map the bytes to the matix for (var x = 0; x < Width; x++) diff --git a/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProS.cs b/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProS.cs new file mode 100644 index 000000000..36a9f5b72 --- /dev/null +++ b/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProS.cs @@ -0,0 +1,91 @@ +using System.Drawing; +using System.Linq; +using System.Threading; +using System.Windows; +using System.Windows.Forms; +using Artemis.DAL; +using Artemis.DeviceProviders.CoolerMaster.Utilities; +using Artemis.DeviceProviders.Logitech.Utilities; +using Artemis.Properties; +using Artemis.Settings; +using Artemis.Utilities; + +namespace Artemis.DeviceProviders.CoolerMaster +{ + public class MasterkeysProS : KeyboardProvider + { + private GeneralSettings _generalSettings; + + public MasterkeysProS() + { + Name = "CM Masterkeys Pro S"; + Slug = "cm-masterkeys-pro-s"; + + CantEnableText = "Couldn't connect to your CM Masterkeys Pro S.\n" + + "Please check your cables and try updating your CM software.\n\n" + + "If needed, you can select a different keyboard in Artemis under settings."; + + Height = 6; + Width = 18; + + PreviewSettings = new PreviewSettings(683, 242, new Thickness(0, 0, 0, 0), Resources.masterkeys_pro_s); + _generalSettings = SettingsProvider.Load(); + } + + public override void Disable() + { + CmSdk.EnableLedControl(false); + Thread.Sleep(500); + } + + public override bool CanEnable() + { + CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MKeys_L); + + // Doesn't seem reliable but better than nothing I suppose + return CmSdk.IsDevicePlug(); + } + + public override void Enable() + { + CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MKeys_S); + CmSdk.EnableLedControl(true); + } + + public override void DrawBitmap(Bitmap bitmap) + { + // Resize the bitmap + using (var b = ImageUtilities.ResizeImage(bitmap, Width, Height)) + { + // Create an empty matrix + var matrix = new COLOR_MATRIX { KeyColor = new KEY_COLOR[6, 22] }; + + // Map the bytes to the matix + for (var x = 0; x < Width; x++) + { + for (var y = 0; y < Height; y++) + { + var c = b.GetPixel(x, y); + matrix.KeyColor[y, x] = new KEY_COLOR(c.R, c.G, c.B); + } + } + + // Send the matrix to the keyboard + CmSdk.SetAllLedColor(matrix); + } + } + + public override KeyMatch? GetKeyPosition(Keys keyCode) + { + switch (_generalSettings.Layout) + { + case "Qwerty": + return KeyMap.QwertyLayout.FirstOrDefault(k => k.KeyCode == keyCode); + case "Qwertz": + return KeyMap.QwertzLayout.FirstOrDefault(k => k.KeyCode == keyCode); + default: + return KeyMap.AzertyLayout.FirstOrDefault(k => k.KeyCode == keyCode); + } + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadsets.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs similarity index 95% rename from Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadsets.cs rename to Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs index 7a727f095..f30936674 100644 --- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadsets.cs +++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs @@ -8,9 +8,9 @@ using Ninject.Extensions.Logging; namespace Artemis.DeviceProviders.Corsair { - internal class CorsairHeadsets : DeviceProvider + internal class CorsairHeadset : DeviceProvider { - public CorsairHeadsets(ILogger logger) + public CorsairHeadset(ILogger logger) { Logger = logger; Type = DeviceType.Headset; diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboards.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboard.cs similarity index 80% rename from Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboards.cs rename to Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboard.cs index a1840dcbe..4494b793d 100644 --- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboards.cs +++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboard.cs @@ -10,19 +10,18 @@ using CUE.NET; using CUE.NET.Brushes; using CUE.NET.Devices.Generic; using CUE.NET.Devices.Generic.Enums; -using CUE.NET.Devices.Keyboard; using CUE.NET.Helper; using Ninject.Extensions.Logging; using Point = System.Drawing.Point; namespace Artemis.DeviceProviders.Corsair { - public class CorsairKeyboards : KeyboardProvider + public class CorsairKeyboard : KeyboardProvider { - private CorsairKeyboard _keyboard; + private CUE.NET.Devices.Keyboard.CorsairKeyboard _keyboard; private ImageBrush _keyboardBrush; - public CorsairKeyboards(ILogger logger) + public CorsairKeyboard(ILogger logger) { Logger = logger; Name = "Corsair RGB Keyboards"; @@ -83,7 +82,6 @@ namespace Artemis.DeviceProviders.Corsair } Logger.Debug("Corsair SDK reported device as: {0}", _keyboard.DeviceInfo.Model); - _keyboard.Brush = _keyboardBrush ?? (_keyboardBrush = new ImageBrush()); } @@ -100,28 +98,30 @@ namespace Artemis.DeviceProviders.Corsair /// public override void DrawBitmap(Bitmap bitmap) { - var image = ImageUtilities.ResizeImage(bitmap, Width, Height); - - // For STRAFE, stretch the image on row 2. - if (_keyboard.DeviceInfo.Model == "STRAFE RGB") + using (var image = ImageUtilities.ResizeImage(bitmap, Width, Height)) { - using (var strafeBitmap = new Bitmap(22, 8)) + // For STRAFE, stretch the image on row 2. + if (_keyboard.DeviceInfo.Model == "STRAFE RGB") { - using (var g = Graphics.FromImage(strafeBitmap)) + using (var strafeBitmap = new Bitmap(22, 8)) { - g.DrawImage(image, new Point(0, 0)); - g.DrawImage(image, new Rectangle(0, 3, 22, 7), new Rectangle(0, 2, 22, 7), GraphicsUnit.Pixel); - } + using (var g = Graphics.FromImage(strafeBitmap)) + { + g.DrawImage(image, new Point(0, 0)); + g.DrawImage(image, new Rectangle(0, 3, 22, 7), new Rectangle(0, 2, 22, 7), + GraphicsUnit.Pixel); - image.Dispose(); - image = strafeBitmap; + _keyboardBrush.Image = strafeBitmap; + _keyboard.Update(); + } + } + } + else + { + _keyboardBrush.Image = image; + _keyboard.Update(); } } - - _keyboardBrush.Image = image; - _keyboard.Update(); - - image.Dispose(); } public override KeyMatch? GetKeyPosition(Keys keyCode) @@ -144,7 +144,7 @@ namespace Artemis.DeviceProviders.Corsair return null; var center = cueLed.LedRectangle.GetCenter(); - return new KeyMatch(keyCode, (int) (center.X*widthMultiplier),(int) (center.Y*heightMultiplier)); + return new KeyMatch(keyCode, (int) (center.X*widthMultiplier), (int) (center.Y*heightMultiplier)); } } } \ No newline at end of file diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs similarity index 96% rename from Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs rename to Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs index 06ba59735..e153be07e 100644 --- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs +++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs @@ -8,9 +8,9 @@ using Ninject.Extensions.Logging; namespace Artemis.DeviceProviders.Corsair { - internal class CorsairMice : DeviceProvider + internal class CorsairMouse : DeviceProvider { - public CorsairMice(ILogger logger) + public CorsairMouse(ILogger logger) { Logger = logger; Type = DeviceType.Mouse; diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemats.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs similarity index 94% rename from Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemats.cs rename to Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs index 1a24cdd83..badf7b4e4 100644 --- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemats.cs +++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs @@ -4,14 +4,13 @@ using System.Linq; using System.Threading; using CUE.NET; using CUE.NET.Devices.Generic.Enums; -using CUE.NET.Devices.Mousemat.Enums; using Ninject.Extensions.Logging; namespace Artemis.DeviceProviders.Corsair { - internal class CorsairMousemats : DeviceProvider + internal class CorsairMousemat : DeviceProvider { - public CorsairMousemats(ILogger logger) + public CorsairMousemat(ILogger logger) { Logger = logger; Type = DeviceType.Mousemat; @@ -40,7 +39,7 @@ namespace Artemis.DeviceProviders.Corsair public override void UpdateDevice(Bitmap bitmap) { - if (!CanUse || bitmap == null) + if (!CanUse || (bitmap == null)) return; if (bitmap.Width != bitmap.Height) throw new ArgumentException("Bitmap must be a perfect square"); diff --git a/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs b/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs index 80491a1b1..d31ec3ee0 100644 --- a/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs +++ b/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs @@ -1,6 +1,5 @@ using System.Drawing; using System.Threading; -using System.Windows; using Artemis.DeviceProviders.Logitech.Utilities; using Artemis.Utilities.DataReaders; using Microsoft.Win32; @@ -23,8 +22,17 @@ namespace Artemis.DeviceProviders.Logitech return false; } - if (DllManager.RestoreLogitechDll()) - RestoreDll(); + if (DllManager.DllPlaced()) + { + CantEnableText = + "Artemis couldn't enable your Logitech keyboard, because the required files are not in place.\n\n" + + "This happens when you run The Division or GTA and shut down Artemis before shutting down The Division\n" + + "Artemis tries to fix this automatically on startup but because the files may have been in use it failed.\n\n" + + "To try again, restart Artemis or check out the FAQ."; + + return false; + } + int majorNum = 0, minorNum = 0, buildNum = 0; LogitechGSDK.LogiLedInit(); @@ -42,15 +50,6 @@ namespace Artemis.DeviceProviders.Logitech return version >= 88115; } - private void RestoreDll() - { - MessageBox.Show( - "Artemis couldn't enable your Logitech keyboard, because the required files are not in place.\n\n" + - "This happens when you run The Division and shut down Artemis before shutting down The Division\n" + - "It can be fixed automatically by clicking OK, but to avoid this message in the future please\n" + - "shut down The Division before shutting down Artemis."); - } - public override void Enable() { // Initialize the SDK diff --git a/Artemis/Artemis/Dialogs/MarkdownDialog.xaml.cs b/Artemis/Artemis/Dialogs/MarkdownDialog.xaml.cs index 3d6b1d7e6..3b9c69bed 100644 --- a/Artemis/Artemis/Dialogs/MarkdownDialog.xaml.cs +++ b/Artemis/Artemis/Dialogs/MarkdownDialog.xaml.cs @@ -16,8 +16,6 @@ namespace Artemis.Dialogs public static readonly DependencyProperty MarkdownProperty = DependencyProperty.Register("Markdown", typeof(string), typeof(MarkdownDialog), new PropertyMetadata(default(string))); - - public MarkdownDialog(MetroWindow parentWindow) { ParentWindow = parentWindow; diff --git a/Artemis/Artemis/InjectionModules/DeviceModules.cs b/Artemis/Artemis/InjectionModules/DeviceModules.cs index d250abf40..46839dd26 100644 --- a/Artemis/Artemis/InjectionModules/DeviceModules.cs +++ b/Artemis/Artemis/InjectionModules/DeviceModules.cs @@ -12,20 +12,21 @@ namespace Artemis.InjectionModules public override void Load() { // Keyboards - Bind().To().InSingletonScope(); + Bind().To().InSingletonScope(); Bind().To().InSingletonScope(); Bind().To().InSingletonScope(); Bind().To().InSingletonScope(); Bind().To().InSingletonScope(); + Bind().To().InSingletonScope(); // Mice - Bind().To().InSingletonScope(); + Bind().To().InSingletonScope(); // Headsets - Bind().To().InSingletonScope(); + Bind().To().InSingletonScope(); // Mousemats - Bind().To().InSingletonScope(); + Bind().To().InSingletonScope(); // Other Bind().To().InSingletonScope(); diff --git a/Artemis/Artemis/InjectionModules/ProfileModules.cs b/Artemis/Artemis/InjectionModules/ProfileModules.cs index bca7fa868..8e91b68b8 100644 --- a/Artemis/Artemis/InjectionModules/ProfileModules.cs +++ b/Artemis/Artemis/InjectionModules/ProfileModules.cs @@ -3,6 +3,7 @@ using Artemis.Profiles.Layers.Conditions; 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.Folder; using Artemis.Profiles.Layers.Types.Generic; using Artemis.Profiles.Layers.Types.Headset; @@ -48,6 +49,9 @@ namespace Artemis.InjectionModules Bind().ToSelf(); Bind().ToSelf(); Bind().ToSelf(); + + // Type helpers + Bind().ToSelf().InSingletonScope(); } } } \ No newline at end of file diff --git a/Artemis/Artemis/Managers/LoopManager.cs b/Artemis/Artemis/Managers/LoopManager.cs index 631017882..1261bdb48 100644 --- a/Artemis/Artemis/Managers/LoopManager.cs +++ b/Artemis/Artemis/Managers/LoopManager.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Timers; +using System.Windows; +using System.Windows.Threading; using Artemis.DeviceProviders; using Ninject.Extensions.Logging; using Timer = System.Timers.Timer; @@ -19,21 +21,44 @@ namespace Artemis.Managers private readonly EffectManager _effectManager; private readonly ILogger _logger; private readonly Timer _loopTimer; + private bool _canShowException; public LoopManager(ILogger logger, EffectManager effectManager, DeviceManager deviceManager) { _logger = logger; _effectManager = effectManager; _deviceManager = deviceManager; + _canShowException = true; // Setup timers _loopTimer = new Timer(40); - _loopTimer.Elapsed += Render; + _loopTimer.Elapsed += LoopTimerOnElapsed; _loopTimer.Start(); _logger.Info("Intialized LoopManager"); } + private void LoopTimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs) + { + try + { + Render(); + } + catch (Exception e) + { + if (_canShowException) + { + Caliburn.Micro.Execute.OnUIThread(delegate + { + _canShowException = false; + _loopTimer.Stop(); + App.GetArtemisExceptionViewer(e).ShowDialog(); + Environment.Exit(0); + }); + } + } + } + /// /// Gets whether the loop is running /// @@ -95,7 +120,7 @@ namespace Artemis.Managers _deviceManager.ReleaseActiveKeyboard(); } - private void Render(object sender, ElapsedEventArgs e) + private void Render() { if (!Running || _deviceManager.ChangingKeyboard) return; diff --git a/Artemis/Artemis/Models/EffectModel.cs b/Artemis/Artemis/Models/EffectModel.cs index 478884cdb..6df55e873 100644 --- a/Artemis/Artemis/Models/EffectModel.cs +++ b/Artemis/Artemis/Models/EffectModel.cs @@ -89,8 +89,8 @@ namespace Artemis.Models 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"); + 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); diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchDataModel.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchDataModel.cs index 5d0353154..4a0cdd3a1 100644 --- a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchDataModel.cs +++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchDataModel.cs @@ -46,6 +46,8 @@ namespace Artemis.Modules.Games.Overwatch Lúcio, Mercy, Symmetra, - Zenyatta + Zenyatta, + Ana, + Sombra } } \ No newline at end of file diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs index 45bd862fc..7f53834eb 100644 --- a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs +++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs @@ -10,14 +10,16 @@ using Artemis.Profiles.Layers.Models; using Artemis.Services; using Artemis.Utilities; using Artemis.Utilities.DataReaders; +using Artemis.ViewModels; using Microsoft.Win32; namespace Artemis.Modules.Games.Overwatch { public class OverwatchModel : GameModel { - private readonly PipeServer _pipeServer; + private readonly DebugViewModel _debugViewModel; private readonly MetroDialogService _dialogService; + private readonly PipeServer _pipeServer; private DateTime _characterChange; private string _lastMessage; // Using sticky values on these since they can cause flickering @@ -27,11 +29,13 @@ namespace Artemis.Modules.Games.Overwatch private DateTime _ultimateReady; private DateTime _ultimateUsed; - public OverwatchModel(DeviceManager deviceManager, PipeServer pipeServer, MetroDialogService dialogService) + public OverwatchModel(DeviceManager deviceManager, PipeServer pipeServer, MetroDialogService dialogService, + DebugViewModel debugViewModel) : base(deviceManager, SettingsProvider.Load(), new OverwatchDataModel()) { _pipeServer = pipeServer; _dialogService = dialogService; + _debugViewModel = debugViewModel; Name = "Overwatch"; ProcessName = "Overwatch"; Scale = 4; @@ -70,7 +74,9 @@ namespace Artemis.Modules.Games.Overwatch new CharacterColor {Character = OverwatchCharacter.Lúcio, Color = Color.FromRgb(34, 142, 2)}, new CharacterColor {Character = OverwatchCharacter.Mercy, Color = Color.FromRgb(243, 226, 106)}, new CharacterColor {Character = OverwatchCharacter.Symmetra, Color = Color.FromRgb(46, 116, 148)}, - new CharacterColor {Character = OverwatchCharacter.Zenyatta, Color = Color.FromRgb(248, 218, 26)} + new CharacterColor {Character = OverwatchCharacter.Zenyatta, Color = Color.FromRgb(248, 218, 26)}, + new CharacterColor {Character = OverwatchCharacter.Ana, Color = Color.FromRgb(16, 36, 87)}, + new CharacterColor {Character = OverwatchCharacter.Sombra, Color = Color.FromRgb(20, 5, 101)} }; } @@ -127,8 +133,7 @@ namespace Artemis.Modules.Games.Overwatch if (colors == null) return; - // TODO: Get the debug viewmodel and update the color array - //_events.PublishOnUIThread(new RazerColorArrayChanged(colors)); + _debugViewModel.UpdateRazerDisplay(colors); // Determine general game state ParseGameSate(gameDataModel, colors); @@ -276,19 +281,20 @@ namespace Artemis.Modules.Games.Overwatch public void FindOverwatch() { - var gameSettings = (OverwatchSettings) Settings; + var gameSettings = Settings as OverwatchSettings; + if (gameSettings == null) + return; + // If already propertly set up, don't do anything if ((gameSettings.GameDirectory != null) && File.Exists(gameSettings.GameDirectory + "Overwatch.exe") && File.Exists(gameSettings.GameDirectory + "RzChromaSDK64.dll")) return; var key = Registry.LocalMachine.OpenSubKey( - @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Overwatch"); - if (key == null) - return; + @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Overwatch"); + var path = key?.GetValue("DisplayIcon")?.ToString(); - var path = key.GetValue("DisplayIcon").ToString(); - if (!File.Exists(path)) + if (string.IsNullOrEmpty(path) || !File.Exists(path)) return; gameSettings.GameDirectory = path.Substring(0, path.Length - 14); diff --git a/Artemis/Artemis/Profiles/Layers/Animations/GrowAnimation.cs b/Artemis/Artemis/Profiles/Layers/Animations/GrowAnimation.cs index 56cd8958d..0d5144150 100644 --- a/Artemis/Artemis/Profiles/Layers/Animations/GrowAnimation.cs +++ b/Artemis/Artemis/Profiles/Layers/Animations/GrowAnimation.cs @@ -1,5 +1,4 @@ using System; -using System.Windows; using System.Windows.Media; using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; @@ -8,16 +7,16 @@ namespace Artemis.Profiles.Layers.Animations { public class GrowAnimation : ILayerAnimation { - public string Name { get; } = "Grow"; + public string Name => "Grow"; public void Update(LayerModel layerModel, bool updateAnimations) { // TODO: Generic implementation // Reset animation progress if layer wasn't drawn for 100ms if ((new TimeSpan(0, 0, 0, 0, 100) < DateTime.Now - layerModel.LastRender) && updateAnimations) - layerModel.Properties.AnimationProgress = 0; + layerModel.AnimationProgress = 0; - var progress = layerModel.Properties.AnimationProgress; + var progress = layerModel.AnimationProgress; if (MustExpire(layerModel)) progress = 0; @@ -25,43 +24,42 @@ namespace Artemis.Profiles.Layers.Animations // If not previewing, store the animation progress in the actual model for the next frame if (updateAnimations) - layerModel.Properties.AnimationProgress = progress; + layerModel.AnimationProgress = progress; } - public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { - if (applied?.Brush == null) + if (layerModel.Brush == null) return; - const int scale = 4; // Set up variables for this frame - var rect = applied.Contain - ? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale) - : new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale); + var rect = layerModel.Properties.Contain + ? layerModel.LayerRect() + : layerModel.Properties.PropertiesRect(); - var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale); + var clip = layerModel.LayerRect(); // Take an offset of 4 to allow layers to slightly leave their bounds - var progress = (6.0 - props.AnimationProgress)*10.0; + var progress = (6.0 - layerModel.AnimationProgress)*10.0; if (progress < 0) { // Can't meddle with the original brush because it's frozen. - var brush = applied.Brush.Clone(); + var brush = layerModel.Brush.Clone(); brush.Opacity = 1 + 0.025*progress; if (brush.Opacity < 0) brush.Opacity = 0; if (brush.Opacity > 1) brush.Opacity = 1; - applied.Brush = brush; + layerModel.Brush = brush; } rect.Inflate(-rect.Width/100.0*progress, -rect.Height/100.0*progress); clip.Inflate(-clip.Width/100.0*progress, -clip.Height/100.0*progress); c.PushClip(new RectangleGeometry(clip)); - c.DrawRectangle(applied.Brush, null, rect); + c.DrawRectangle(layerModel.Brush, null, rect); c.Pop(); } - public bool MustExpire(LayerModel layer) => layer.Properties.AnimationProgress > 10; + public bool MustExpire(LayerModel layer) => layer.AnimationProgress > 10; } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Animations/NoneAnimation.cs b/Artemis/Artemis/Profiles/Layers/Animations/NoneAnimation.cs index 3bbe7d9d1..0d0e759ea 100644 --- a/Artemis/Artemis/Profiles/Layers/Animations/NoneAnimation.cs +++ b/Artemis/Artemis/Profiles/Layers/Animations/NoneAnimation.cs @@ -6,13 +6,13 @@ namespace Artemis.Profiles.Layers.Animations { public class NoneAnimation : ILayerAnimation { - public string Name { get; } = "None"; + public string Name => "None"; public void Update(LayerModel layerModel, bool updateAnimations) { } - public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { } diff --git a/Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs b/Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs index ee7c0a131..669452134 100644 --- a/Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs +++ b/Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs @@ -1,5 +1,4 @@ using System; -using System.Windows; using System.Windows.Media; using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; @@ -8,16 +7,16 @@ namespace Artemis.Profiles.Layers.Animations { public class PulseAnimation : ILayerAnimation { - public string Name { get; } = "Pulse"; + public string Name => "Pulse"; public void Update(LayerModel layerModel, bool updateAnimations) { // TODO: Generic implementation // Reset animation progress if layer wasn't drawn for 100ms if ((new TimeSpan(0, 0, 0, 0, 100) < DateTime.Now - layerModel.LastRender) && updateAnimations) - layerModel.Properties.AnimationProgress = 0; + layerModel.AnimationProgress = 0; - var progress = layerModel.Properties.AnimationProgress; + var progress = layerModel.AnimationProgress; if (MustExpire(layerModel)) progress = 0; @@ -25,32 +24,31 @@ namespace Artemis.Profiles.Layers.Animations // If not previewing, store the animation progress in the actual model for the next frame if (updateAnimations) - layerModel.Properties.AnimationProgress = progress; + layerModel.AnimationProgress = progress; } - public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { - if (applied.Brush == null) + if (layerModel.Brush == null) return; - const int scale = 4; // Set up variables for this frame - var rect = applied.Contain - ? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale) - : new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale); + var rect = layerModel.Properties.Contain + ? layerModel.LayerRect() + : layerModel.Properties.PropertiesRect(); - var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale); + var clip = layerModel.LayerRect(); // Can't meddle with the original brush because it's frozen. - var brush = applied.Brush.Clone(); - brush.Opacity = (Math.Sin(props.AnimationProgress*Math.PI) + 1)*(props.Opacity/2); - applied.Brush = brush; + var brush = layerModel.Brush.Clone(); + brush.Opacity = (Math.Sin(layerModel.AnimationProgress*Math.PI) + 1)*(layerModel.Opacity/2); + layerModel.Brush = brush; c.PushClip(new RectangleGeometry(clip)); - c.DrawRectangle(applied.Brush, null, rect); + c.DrawRectangle(layerModel.Brush, null, rect); c.Pop(); } - public bool MustExpire(LayerModel layer) => layer.Properties.AnimationProgress > 2; + public bool MustExpire(LayerModel layer) => layer.AnimationProgress > 2; } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Animations/SlideDownAnimation.cs b/Artemis/Artemis/Profiles/Layers/Animations/SlideDownAnimation.cs index 23b176656..81a7cbca8 100644 --- a/Artemis/Artemis/Profiles/Layers/Animations/SlideDownAnimation.cs +++ b/Artemis/Artemis/Profiles/Layers/Animations/SlideDownAnimation.cs @@ -7,45 +7,46 @@ namespace Artemis.Profiles.Layers.Animations { public class SlideDownAnimation : ILayerAnimation { - public string Name { get; } = "Slide down"; + public string Name => "Slide down"; public void Update(LayerModel layerModel, bool updateAnimations) { - var progress = layerModel.Properties.AnimationProgress; + var progress = layerModel.AnimationProgress; if (MustExpire(layerModel)) progress = 0; progress = progress + layerModel.Properties.AnimationSpeed*2; // If not previewing, store the animation progress in the actual model for the next frame if (updateAnimations) - layerModel.Properties.AnimationProgress = progress; + layerModel.AnimationProgress = progress; } - public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { - if (applied.Brush == null) + if (layerModel.Brush == null) return; - const int scale = 4; // Set up variables for this frame - var rect = applied.Contain - ? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale) - : new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale); + var rect = layerModel.Properties.Contain + ? layerModel.LayerRect() + : layerModel.Properties.PropertiesRect(); - var s1 = new Rect(new Point(rect.X, rect.Y + props.AnimationProgress), new Size(rect.Width, rect.Height)); - var s2 = new Rect(new Point(s1.X, s1.Y - rect.Height), new Size(rect.Width, rect.Height + .5)); + var s1 = new Rect(new Point(rect.X, rect.Y + layerModel.AnimationProgress), + new Size(rect.Width, rect.Height)); + var s2 = new Rect(new Point(s1.X, s1.Y - rect.Height), + new Size(rect.Width, rect.Height + .5)); - var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale); + var clip = layerModel.LayerRect(); c.PushClip(new RectangleGeometry(clip)); - c.DrawRectangle(applied.Brush, null, s1); - c.DrawRectangle(applied.Brush, null, s2); + c.DrawRectangle(layerModel.Brush, null, s1); + c.DrawRectangle(layerModel.Brush, null, s2); c.Pop(); } public bool MustExpire(LayerModel layer) { - return layer.Properties.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Height*4; + return layer.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Height*4; } } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Animations/SlideLeftAnimation.cs b/Artemis/Artemis/Profiles/Layers/Animations/SlideLeftAnimation.cs index 7394deee4..8f64ddae0 100644 --- a/Artemis/Artemis/Profiles/Layers/Animations/SlideLeftAnimation.cs +++ b/Artemis/Artemis/Profiles/Layers/Animations/SlideLeftAnimation.cs @@ -7,46 +7,46 @@ namespace Artemis.Profiles.Layers.Animations { public class SlideLeftAnimation : ILayerAnimation { - public string Name { get; } = "Slide left"; + public string Name => "Slide left"; public void Update(LayerModel layerModel, bool updateAnimations) { - var progress = layerModel.Properties.AnimationProgress; + var progress = layerModel.AnimationProgress; if (MustExpire(layerModel)) progress = 0; progress = progress + layerModel.Properties.AnimationSpeed*2; // If not previewing, store the animation progress in the actual model for the next frame if (updateAnimations) - layerModel.Properties.AnimationProgress = progress; + layerModel.AnimationProgress = progress; } - public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { - if (applied.Brush == null) + if (layerModel.Brush == null) return; - const int scale = 4; // Set up variables for this frame - var rect = applied.Contain - ? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale) - : new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale); + var rect = layerModel.Properties.Contain + ? layerModel.LayerRect() + : layerModel.Properties.PropertiesRect(); - var s1 = new Rect(new Point(rect.X - props.AnimationProgress, rect.Y), + var s1 = new Rect(new Point(rect.X - layerModel.AnimationProgress, rect.Y), new Size(rect.Width + .5, rect.Height)); - var s2 = new Rect(new Point(s1.X + rect.Width, rect.Y), new Size(rect.Width, rect.Height)); + var s2 = new Rect(new Point(s1.X + rect.Width, rect.Y), + new Size(rect.Width, rect.Height)); - var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale); + var clip = layerModel.LayerRect(); c.PushClip(new RectangleGeometry(clip)); - c.DrawRectangle(applied.Brush, null, s1); - c.DrawRectangle(applied.Brush, null, s2); + c.DrawRectangle(layerModel.Brush, null, s1); + c.DrawRectangle(layerModel.Brush, null, s2); c.Pop(); } public bool MustExpire(LayerModel layer) { - return layer.Properties.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Width*4; + return layer.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Width*4; } } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Animations/SlideRightAnimation.cs b/Artemis/Artemis/Profiles/Layers/Animations/SlideRightAnimation.cs index 83352d26c..6f99d7b3e 100644 --- a/Artemis/Artemis/Profiles/Layers/Animations/SlideRightAnimation.cs +++ b/Artemis/Artemis/Profiles/Layers/Animations/SlideRightAnimation.cs @@ -7,45 +7,46 @@ namespace Artemis.Profiles.Layers.Animations { public class SlideRightAnimation : ILayerAnimation { - public string Name { get; } = "Slide right"; + public string Name => "Slide right"; public void Update(LayerModel layerModel, bool updateAnimations) { - var progress = layerModel.Properties.AnimationProgress; + var progress = layerModel.AnimationProgress; if (MustExpire(layerModel)) progress = 0; progress = progress + layerModel.Properties.AnimationSpeed*2; // If not previewing, store the animation progress in the actual model for the next frame if (updateAnimations) - layerModel.Properties.AnimationProgress = progress; + layerModel.AnimationProgress = progress; } - public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { - if (applied.Brush == null) + if (layerModel.Brush == null) return; - const int scale = 4; // Set up variables for this frame - var rect = applied.Contain - ? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale) - : new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale); + var rect = layerModel.Properties.Contain + ? layerModel.LayerRect() + : layerModel.Properties.PropertiesRect(); - var s1 = new Rect(new Point(rect.X + props.AnimationProgress, rect.Y), new Size(rect.Width, rect.Height)); - var s2 = new Rect(new Point(s1.X - rect.Width, rect.Y), new Size(rect.Width + .5, rect.Height)); + var s1 = new Rect(new Point(rect.X + layerModel.AnimationProgress, rect.Y), + new Size(rect.Width, rect.Height)); + var s2 = new Rect(new Point(s1.X - rect.Width, rect.Y), + new Size(rect.Width + .5, rect.Height)); - var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale); + var clip = layerModel.LayerRect(); c.PushClip(new RectangleGeometry(clip)); - c.DrawRectangle(applied.Brush, null, s1); - c.DrawRectangle(applied.Brush, null, s2); + c.DrawRectangle(layerModel.Brush, null, s1); + c.DrawRectangle(layerModel.Brush, null, s2); c.Pop(); } public bool MustExpire(LayerModel layer) { - return layer.Properties.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Width*4; + return layer.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Width*4; } } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Animations/SlideUpAnimation.cs b/Artemis/Artemis/Profiles/Layers/Animations/SlideUpAnimation.cs index 651fb88b2..14de66902 100644 --- a/Artemis/Artemis/Profiles/Layers/Animations/SlideUpAnimation.cs +++ b/Artemis/Artemis/Profiles/Layers/Animations/SlideUpAnimation.cs @@ -7,46 +7,45 @@ namespace Artemis.Profiles.Layers.Animations { public class SlideUpAnimation : ILayerAnimation { - public string Name { get; } = "Slide up"; + public string Name => "Slide up"; public void Update(LayerModel layerModel, bool updateAnimations) { - var progress = layerModel.Properties.AnimationProgress; + var progress = layerModel.AnimationProgress; if (MustExpire(layerModel)) progress = 0; progress = progress + layerModel.Properties.AnimationSpeed*2; // If not previewing, store the animation progress in the actual model for the next frame if (updateAnimations) - layerModel.Properties.AnimationProgress = progress; + layerModel.AnimationProgress = progress; } - public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { - if (applied.Brush == null) + if (layerModel.Brush == null) return; - const int scale = 4; // Set up variables for this frame - var rect = applied.Contain - ? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale) - : new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale); + var rect = layerModel.Properties.Contain + ? layerModel.LayerRect() + : layerModel.Properties.PropertiesRect(); - var s1 = new Rect(new Point(rect.X, rect.Y - props.AnimationProgress), + var s1 = new Rect(new Point(rect.X, rect.Y - layerModel.AnimationProgress), new Size(rect.Width, rect.Height + .5)); var s2 = new Rect(new Point(s1.X, s1.Y + rect.Height), new Size(rect.Width, rect.Height)); - var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale); + var clip = layerModel.LayerRect(); c.PushClip(new RectangleGeometry(clip)); - c.DrawRectangle(applied.Brush, null, s1); - c.DrawRectangle(applied.Brush, null, s2); + c.DrawRectangle(layerModel.Brush, null, s1); + c.DrawRectangle(layerModel.Brush, null, s2); c.Pop(); } public bool MustExpire(LayerModel layer) { - return layer.Properties.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Height*4; + return layer.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Height*4; } } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs b/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs index ec73555e0..3572d0e74 100644 --- a/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs +++ b/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs @@ -7,11 +7,11 @@ namespace Artemis.Profiles.Layers.Conditions { public class DataModelCondition : ILayerCondition { - public bool ConditionsMet(LayerModel layer, IDataModel dataModel) + public bool ConditionsMet(LayerModel layerModel, IDataModel dataModel) { - lock (layer.Properties.Conditions) + lock (layerModel.Properties.Conditions) { - return layer.Properties.Conditions.All(cm => cm.ConditionMet(dataModel)); + return layerModel.Properties.Conditions.All(cm => cm.ConditionMet(dataModel)); } } } diff --git a/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs b/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs index 0f2ae4d53..04ea65aa8 100644 --- a/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs +++ b/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs @@ -7,17 +7,17 @@ namespace Artemis.Profiles.Layers.Conditions { public class EventCondition : ILayerCondition { - public bool ConditionsMet(LayerModel layer, IDataModel dataModel) + public bool ConditionsMet(LayerModel layerModel, IDataModel dataModel) { - lock (layer.Properties.Conditions) + lock (layerModel.Properties.Conditions) { - var conditionsMet = layer.Properties.Conditions.All(cm => cm.ConditionMet(dataModel)); - layer.EventProperties.Update(layer, conditionsMet); + var conditionsMet = layerModel.Properties.Conditions.All(cm => cm.ConditionMet(dataModel)); + layerModel.EventProperties.Update(layerModel, conditionsMet); - if (conditionsMet && layer.EventProperties.CanTrigger) - layer.EventProperties.TriggerEvent(layer); + if (conditionsMet && layerModel.EventProperties.CanTrigger) + layerModel.EventProperties.TriggerEvent(layerModel); - return layer.EventProperties.MustDraw; + return layerModel.EventProperties.MustDraw; } } } diff --git a/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerAnimation.cs b/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerAnimation.cs index e5554a8d3..f5d1c45c0 100644 --- a/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerAnimation.cs +++ b/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerAnimation.cs @@ -10,7 +10,7 @@ namespace Artemis.Profiles.Layers.Interfaces string Name { get; } void Update(LayerModel layerModel, bool updateAnimations); - void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c); - bool MustExpire(LayerModel layer); + void Draw(LayerModel layerModel, DrawingContext c); + bool MustExpire(LayerModel layerModel); } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerCondition.cs b/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerCondition.cs index 56588ad8d..8fd7422ae 100644 --- a/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerCondition.cs +++ b/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerCondition.cs @@ -5,6 +5,6 @@ namespace Artemis.Profiles.Layers.Interfaces { public interface ILayerCondition { - bool ConditionsMet(LayerModel layer, IDataModel dataModel); + bool ConditionsMet(LayerModel layerModel, IDataModel dataModel); } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerType.cs b/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerType.cs index ee840be41..4b38d1a6d 100644 --- a/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerType.cs +++ b/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerType.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Windows.Media; +using System.Windows.Media; using Artemis.Models.Interfaces; using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Models; @@ -38,9 +37,9 @@ namespace Artemis.Profiles.Layers.Interfaces /// /// Draws the layer /// - /// The layer to draw + /// The layer to draw /// The drawing context to draw with - void Draw(LayerModel layer, DrawingContext c); + void Draw(LayerModel layerModel, DrawingContext c); /// /// Updates the provided layer layerModel according to this type @@ -61,7 +60,8 @@ namespace Artemis.Profiles.Layers.Interfaces /// /// The layer editor VM this type resides in /// The current viewmodel - LayerPropertiesViewModel SetupViewModel(LayerEditorViewModel layerEditorViewModel, LayerPropertiesViewModel layerPropertiesViewModel); + LayerPropertiesViewModel SetupViewModel(LayerEditorViewModel layerEditorViewModel, + LayerPropertiesViewModel layerPropertiesViewModel); } public enum DrawType diff --git a/Artemis/Artemis/Profiles/Layers/Models/DynamicPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Models/DynamicPropertiesModel.cs index 8cbf2ca6c..1063f71aa 100644 --- a/Artemis/Artemis/Profiles/Layers/Models/DynamicPropertiesModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Models/DynamicPropertiesModel.cs @@ -37,15 +37,15 @@ namespace Artemis.Profiles.Layers.Models /// public LayerPropertyOptions LayerPropertyOptions { get; set; } - internal void ApplyProperty(IDataModel dataModel, LayerPropertiesModel properties) + internal void ApplyProperty(IDataModel dataModel, LayerModel layerModel) { if (LayerPropertyType == LayerPropertyType.PercentageOf) - ApplyPercentageOf(dataModel, properties, PercentageSource); + ApplyPercentageOf(dataModel, layerModel, PercentageSource); if (LayerPropertyType == LayerPropertyType.PercentageOfProperty) - ApplyPercentageOfProperty(dataModel, properties); + ApplyPercentageOfProperty(dataModel, layerModel); } - private void ApplyPercentageOf(IDataModel dataModel, LayerPropertiesModel properties, float src) + private void ApplyPercentageOf(IDataModel dataModel, LayerModel layerModel, float src) { if (GameProperty == null) return; @@ -54,61 +54,61 @@ namespace Artemis.Profiles.Layers.Models var percentage = gameProperty/src; if (LayerProperty == "Width") - ApplyWidth(properties, percentage); + ApplyWidth(layerModel, percentage); else if (LayerProperty == "Height") - ApplyHeight(properties, percentage); + ApplyHeight(layerModel, percentage); else if (LayerProperty == "Opacity") - ApplyOpacity(properties, percentage); + ApplyOpacity(layerModel, percentage); } - private void ApplyWidth(LayerPropertiesModel properties, float percentage) + private void ApplyWidth(LayerModel layerModel, float percentage) { - var newWidth = Math.Round(percentage*(float) properties.Width, 2); - var difference = properties.Width - newWidth; + var newWidth = Math.Round(percentage*(float) layerModel.Width, 2); + var difference = layerModel.Width - newWidth; if (newWidth < 0) newWidth = 0; - properties.Width = newWidth; + layerModel.Width = newWidth; // Apply the right to left option if (LayerPropertyOptions == LayerPropertyOptions.RightToLeft) - properties.X = properties.X + difference; + layerModel.X = layerModel.X + difference; } - private void ApplyHeight(LayerPropertiesModel properties, float percentage) + private void ApplyHeight(LayerModel layerModel, float percentage) { - var newHeight = Math.Round(percentage*(float) properties.Height, 2); - var difference = properties.Height - newHeight; + var newHeight = Math.Round(percentage*(float) layerModel.Height, 2); + var difference = layerModel.Height - newHeight; if (newHeight < 0) newHeight = 0; - properties.Height = newHeight; + layerModel.Height = newHeight; if (LayerPropertyOptions == LayerPropertyOptions.Downwards) - properties.Y = properties.Y + difference; + layerModel.Y = layerModel.Y + difference; } - private void ApplyOpacity(LayerPropertiesModel properties, float percentage) + private void ApplyOpacity(LayerModel layerModel, float percentage) { - properties.Opacity = percentage*(float) properties.Opacity; - if (properties.Opacity < 0.0) - properties.Opacity = 0.0; - if (properties.Opacity > 1.0) - properties.Opacity = 1.0; + layerModel.Opacity = percentage*(float) layerModel.Opacity; + if (layerModel.Opacity < 0.0) + layerModel.Opacity = 0.0; + if (layerModel.Opacity > 1.0) + layerModel.Opacity = 1.0; // Apply the inverse/decrease option if (LayerPropertyOptions == LayerPropertyOptions.Decrease) - properties.Opacity = 1.0 - properties.Opacity; + layerModel.Opacity = 1.0 - layerModel.Opacity; - var brush = properties.Brush.Clone(); - brush.Opacity = properties.Opacity; - properties.Brush = brush; + var brush = layerModel.Brush.Clone(); + brush.Opacity = layerModel.Opacity; + layerModel.Brush = brush; } - private void ApplyPercentageOfProperty(IDataModel dataModel, LayerPropertiesModel properties) + private void ApplyPercentageOfProperty(IDataModel dataModel, LayerModel layerModel) { var value = dataModel.GetPropValue(PercentageProperty); - ApplyPercentageOf(dataModel, properties, value); + ApplyPercentageOf(dataModel, layerModel, value); } } diff --git a/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs index b13f3487a..d145bf7ae 100644 --- a/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs @@ -1,6 +1,4 @@ using System; -using System.Threading; -using System.Threading.Tasks; using Newtonsoft.Json; namespace Artemis.Profiles.Layers.Models @@ -20,6 +18,8 @@ namespace Artemis.Profiles.Layers.Models [JsonIgnore] public bool MustDraw { get; set; } + public DateTime EventCanTriggerTime { get; set; } + /// /// Resets the event's properties and triggers it /// @@ -42,11 +42,9 @@ namespace Artemis.Profiles.Layers.Models CanTrigger = false; MustDraw = true; EventTriggerTime = DateTime.Now; - layer.Properties.AnimationProgress = 0.0; + layer.AnimationProgress = 0.0; } - public DateTime EventCanTriggerTime { get; set; } - /// /// Gets whether the event should stop diff --git a/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs b/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs index e3bd0b529..53cee288d 100644 --- a/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Windows; using System.Windows.Media; using Artemis.Models.Interfaces; using Artemis.Profiles.Layers.Animations; @@ -18,43 +19,18 @@ namespace Artemis.Profiles.Layers.Models public LayerModel() { Children = new ChildItemCollection(this); + TweenModel = new TweenModel(this); var model = Properties as KeyboardPropertiesModel; if (model != null) GifImage = new GifImage(model.GifFile); } - public ILayerType LayerType { get; set; } - public ILayerCondition LayerCondition { get; set; } - public ILayerAnimation LayerAnimation { get; set; } - - public string Name { get; set; } - public int Order { get; set; } - - public bool Enabled { get; set; } - public bool Expanded { get; set; } - public bool IsEvent { get; set; } - public LayerPropertiesModel Properties { get; set; } - public EventPropertiesModel EventProperties { get; set; } - public ChildItemCollection Children { get; } - - [JsonIgnore] - public LayerPropertiesModel AppliedProperties { get; set; } - [JsonIgnore] public ImageSource LayerImage => LayerType.DrawThumbnail(this); [JsonIgnore] - public LayerModel Parent { get; internal set; } - - [JsonIgnore] - public ProfileModel Profile { get; internal set; } - - [JsonIgnore] - public GifImage GifImage { get; set; } - - [JsonIgnore] - public DateTime LastRender { get; set; } + public TweenModel TweenModel { get; set; } /// /// Checks whether this layers conditions are met. @@ -68,19 +44,59 @@ namespace Artemis.Profiles.Layers.Models return Enabled && LayerCondition.ConditionsMet(this, dataModel); } + /// + /// Update the layer + /// + /// + /// + /// public void Update(IDataModel dataModel, bool preview, bool updateAnimations) { LayerType.Update(this, dataModel, preview); LayerAnimation?.Update(this, updateAnimations); - + + if (!preview && updateAnimations) + TweenModel.Update(); + LastRender = DateTime.Now; } + /// + /// Applies the saved properties to the current properties + /// + /// Include advanced properties (opacity, brush) + public void ApplyProperties(bool advanced) + { + X = Properties.X; + Y = Properties.Y; + Width = Properties.Width; + Height = Properties.Height; + + if (!advanced) + return; + + Opacity = Properties.Opacity; + Brush = Properties.Brush; + } + + /// + /// Draw the layer using the provided context + /// + /// + /// + /// + /// public void Draw(IDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations) { + if (Brush == null) + return; + LayerType.Draw(this, c); } + /// + /// Tells the current layer type to setup the layer's LayerProperties + /// public void SetupProperties() { LayerType.SetupProperties(this); @@ -97,6 +113,9 @@ namespace Artemis.Profiles.Layers.Models } } + /// + /// Ensures all child layers have a unique order + /// public void FixOrder() { Children.Sort(l => l.Order); @@ -158,23 +177,41 @@ namespace Artemis.Profiles.Layers.Models Width = 1, X = 0, Y = 0, - Opacity = 1 + Opacity = 1, + HeightEaseTime = 0, + HeightEase = "Linear", + WidthEaseTime = 0, + WidthEase = "Linear", + OpacityEaseTime = 0, + OpacityEase = "Linear" } }; } + /// + /// Insert this layer before the given layer + /// + /// public void InsertBefore(LayerModel source) { source.Order = Order; Insert(source); } + /// + /// Insert this layer after the given layer + /// + /// public void InsertAfter(LayerModel source) { source.Order = Order + 1; Insert(source); } + /// + /// Insert the layer as a sibling + /// + /// private void Insert(LayerModel source) { if (Parent != null) @@ -197,11 +234,22 @@ namespace Artemis.Profiles.Layers.Models } } + public Rect LayerRect(int scale = 4) + { + var width = Width; + var height = Height; + if (width < 0) + width = 0; + if (height < 0) + height = 0; + + return new Rect(X*scale, Y*scale, width*scale, height*scale); + } + /// /// 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 /// @@ -227,6 +275,105 @@ namespace Artemis.Profiles.Layers.Models return layers; } + public void SetupCondition() + { + if (IsEvent && !(LayerCondition is EventCondition)) + LayerCondition = new EventCondition(); + else if (!IsEvent && !(LayerCondition is DataModelCondition)) + LayerCondition = new DataModelCondition(); + } + + #region Properties + + #region Layer type properties + + public ILayerType LayerType { get; set; } + public ILayerCondition LayerCondition { get; set; } + public ILayerAnimation LayerAnimation { get; set; } + + #endregion + + #region Generic properties + + public string Name { get; set; } + public int Order { get; set; } + public bool Enabled { get; set; } + public bool Expanded { get; set; } + public bool IsEvent { get; set; } + public LayerPropertiesModel Properties { get; set; } + public EventPropertiesModel EventProperties { get; set; } + + #endregion + + #region Relational properties + + public ChildItemCollection Children { get; } + + [JsonIgnore] + public LayerModel Parent { get; internal set; } + + [JsonIgnore] + public ProfileModel Profile { get; internal set; } + + #endregion + + #region Render properties + + [JsonIgnore] private Brush _brush; + + [JsonIgnore] + public double X { get; set; } + + [JsonIgnore] + public double Y { get; set; } + + [JsonIgnore] + public double Width { get; set; } + + [JsonIgnore] + public double Height { get; set; } + + [JsonIgnore] + public double Opacity { get; set; } + + [JsonIgnore] + public Brush Brush + { + get { return _brush; } + set + { + if (value == null) + { + _brush = null; + return; + } + + if (value.IsFrozen) + { + _brush = value; + return; + } + + // Clone the brush off of the UI thread and freeze it + var cloned = value.Dispatcher.Invoke(value.CloneCurrentValue); + cloned.Freeze(); + _brush = cloned; + } + } + + [JsonIgnore] + public double AnimationProgress { get; set; } + + [JsonIgnore] + public GifImage GifImage { get; set; } + + [JsonIgnore] + public DateTime LastRender { get; set; } + + #endregion + + #endregion + #region IChildItem Members LayerModel IChildItem.Parent @@ -242,13 +389,5 @@ namespace Artemis.Profiles.Layers.Models } #endregion - - public void SetupCondition() - { - if (IsEvent && !(LayerCondition is EventCondition)) - LayerCondition = new EventCondition(); - else if (!IsEvent && !(LayerCondition is DataModelCondition)) - LayerCondition = new DataModelCondition(); - } } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Models/LayerPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Models/LayerPropertiesModel.cs index a6eb1ea34..ccf0d77c5 100644 --- a/Artemis/Artemis/Profiles/Layers/Models/LayerPropertiesModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Models/LayerPropertiesModel.cs @@ -26,6 +26,12 @@ namespace Artemis.Profiles.Layers.Models Conditions = source.Conditions; DynamicProperties = source.DynamicProperties; Brush = source.Brush; + HeightEase = source.HeightEase; + WidthEase = source.WidthEase; + OpacityEase = source.OpacityEase; + HeightEaseTime = source.HeightEaseTime; + WidthEaseTime = source.WidthEaseTime; + OpacityEaseTime = source.OpacityEaseTime; } public double X { get; set; } @@ -35,12 +41,15 @@ namespace Artemis.Profiles.Layers.Models public bool Contain { get; set; } public double Opacity { get; set; } public double AnimationSpeed { get; set; } + public double OpacityEaseTime { get; set; } + public double HeightEaseTime { get; set; } + public double WidthEaseTime { get; set; } + public string WidthEase { set; get; } + public string HeightEase { get; set; } + public string OpacityEase { get; set; } public List Conditions { get; set; } = new List(); public List DynamicProperties { get; set; } = new List(); - [JsonIgnore] - public double AnimationProgress { get; set; } - [JsonConverter(typeof(BrushJsonConverter))] public Brush Brush { @@ -66,7 +75,7 @@ namespace Artemis.Profiles.Layers.Models } } - public Rect GetRect(int scale = 4) + public Rect PropertiesRect(int scale = 4) { return new Rect(X*scale, Y*scale, Width*scale, Height*scale); } diff --git a/Artemis/Artemis/Profiles/Layers/Models/TweenModel.cs b/Artemis/Artemis/Profiles/Layers/Models/TweenModel.cs new file mode 100644 index 000000000..29e679164 --- /dev/null +++ b/Artemis/Artemis/Profiles/Layers/Models/TweenModel.cs @@ -0,0 +1,99 @@ +using System; +using Betwixt; + +namespace Artemis.Profiles.Layers.Models +{ + public class TweenModel + { + private readonly LayerModel _layerModel; + private Tweener _xTweener; + private Tweener _yTweener; + private float _width; + private Tweener _widthTweener; + private float _height; + private Tweener _heightTweener; + private float _opacity; + private Tweener _opacityTweener; + private float _x; + private float _y; + + public TweenModel(LayerModel layerModel) + { + _layerModel = layerModel; + _xTweener = new Tweener((float) layerModel.X, (float) layerModel.X, 0); + _yTweener = new Tweener((float) layerModel.Y, (float) layerModel.Y, 0); + _widthTweener = new Tweener((float) layerModel.Width, (float) layerModel.Width, 0); + _heightTweener = new Tweener((float) layerModel.Height, (float) layerModel.Height, 0); + _opacityTweener = new Tweener((float) layerModel.Opacity, (float) layerModel.Opacity, 0); + + StoreCurrentValues(); + } + + public void Update() + { + // Width + if (Math.Abs(_layerModel.Width - _width) > 0.001) + { + var widthFunc = GetEaseFunction(_layerModel.Properties.WidthEase); + var widthSpeed = _layerModel.Properties.WidthEaseTime; + + _xTweener = new Tweener(_xTweener.Value, (float) _layerModel.X, widthSpeed, widthFunc); + _widthTweener = new Tweener(_widthTweener.Value, (float) _layerModel.Width, widthSpeed, widthFunc); + } + + // Height + if (Math.Abs(_layerModel.Height - _height) > 0.001) + { + var heightFunc = GetEaseFunction(_layerModel.Properties.HeightEase); + var heightSpeed = _layerModel.Properties.HeightEaseTime; + _yTweener = new Tweener(_y, (float) _layerModel.Y, heightSpeed, heightFunc); + _heightTweener = new Tweener(_height, (float) _layerModel.Height, heightSpeed, heightFunc); + } + + // Opacity + if (Math.Abs(_layerModel.Opacity - _opacity) > 0.001) + { + _opacityTweener = new Tweener(_opacity, (float) _layerModel.Opacity, + _layerModel.Properties.OpacityEaseTime, GetEaseFunction(_layerModel.Properties.OpacityEase)); + } + + _xTweener.Update(40); + _yTweener.Update(40); + _widthTweener.Update(40); + _heightTweener.Update(40); + _opacityTweener.Update(40); + + StoreCurrentValues(); + + _layerModel.X = _xTweener.Value; + _layerModel.Y = _yTweener.Value; + _layerModel.Width = _widthTweener.Value; + _layerModel.Height = _heightTweener.Value; + _layerModel.Opacity = _opacityTweener.Value; + } + + private void StoreCurrentValues() + { + _x = (float) _layerModel.X; + _y = (float) _layerModel.Y; + _width = (float) _layerModel.Width; + _height = (float) _layerModel.Height; + _opacity = (float) _layerModel.Opacity; + } + + private static EaseFunc GetEaseFunction(string functionName) + { + switch (functionName) + { + case "In": + return Ease.Quint.In; + case "Out": + return Ease.Quint.Out; + case "In/out": + return Ease.Quint.InOut; + default: + return Ease.Linear; + } + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/AmbienceCreatorExtend.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/AmbienceCreatorExtend.cs index c8abd06b7..eecff9753 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/AmbienceCreatorExtend.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/AmbienceCreatorExtend.cs @@ -9,34 +9,40 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.AmbienceCreator #region Methods public byte[] GetAmbience(byte[] pixels, int sourceWidth, int sourceHeight, - int targetWidth, int targetHeight, - AmbientLightPropertiesModel settings) + int targetWidth, int targetHeight, + AmbientLightPropertiesModel settings) { - AvgColor[] colors = new AvgColor[targetWidth]; - for (int i = 0; i < colors.Length; i++) + var colors = new AvgColor[targetWidth]; + for (var i = 0; i < colors.Length; i++) colors[i] = new AvgColor(); - int offsetLeft = settings.OffsetLeft + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Left) - ? pixels.DetectBlackBarLeft(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) + var offsetLeft = settings.OffsetLeft + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Left) + ? pixels.DetectBlackBarLeft(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, + settings.OffsetTop, settings.OffsetBottom) : 0); - int offsetRight = settings.OffsetRight + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Right) - ? pixels.DetectBlackBarRight(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) - : 0); - int offsetTop = settings.OffsetTop + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Top) - ? pixels.DetectBlackBarTop(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) - : 0); - int offsetBottom = settings.OffsetBottom + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Bottom) - ? pixels.DetectBlackBarBottom(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) + var offsetRight = settings.OffsetRight + + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Right) + ? pixels.DetectBlackBarRight(sourceWidth, sourceHeight, settings.OffsetLeft, + settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) + : 0); + var offsetTop = settings.OffsetTop + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Top) + ? pixels.DetectBlackBarTop(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, + settings.OffsetTop, settings.OffsetBottom) : 0); + var offsetBottom = settings.OffsetBottom + + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Bottom) + ? pixels.DetectBlackBarBottom(sourceWidth, sourceHeight, settings.OffsetLeft, + settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) + : 0); - int effectiveSourceWidth = sourceWidth - offsetLeft - offsetRight; - int effectiveSourceHeight = sourceHeight - offsetTop - offsetBottom; + var effectiveSourceWidth = sourceWidth - offsetLeft - offsetRight; + var effectiveSourceHeight = sourceHeight - offsetTop - offsetBottom; - int relevantSourceHeight = (int)Math.Round(effectiveSourceHeight * (settings.MirroredAmount / 100.0)); - int relevantOffsetTop = sourceHeight - offsetBottom - relevantSourceHeight; + var relevantSourceHeight = (int) Math.Round(effectiveSourceHeight*(settings.MirroredAmount/100.0)); + var relevantOffsetTop = sourceHeight - offsetBottom - relevantSourceHeight; - double widthPixels = effectiveSourceWidth / (double)targetWidth; - double heightPixels = relevantSourceHeight / (double)targetHeight; + var widthPixels = effectiveSourceWidth/(double) targetWidth; + var heightPixels = relevantSourceHeight/(double) targetHeight; if (widthPixels <= 0 || heightPixels <= 0 || (relevantSourceHeight + relevantOffsetTop > sourceHeight) || effectiveSourceWidth > sourceWidth) @@ -45,13 +51,13 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.AmbienceCreator return colors.ToBGRArray(); } - int increment = Math.Max(1, Math.Min(20, settings.Downsampling)); - for (int y = 0; y < relevantSourceHeight; y += increment) + var increment = Math.Max(1, Math.Min(20, settings.Downsampling)); + for (var y = 0; y < relevantSourceHeight; y += increment) { - int targetWidthIndex = 0; - double widthCounter = widthPixels; + var targetWidthIndex = 0; + var widthCounter = widthPixels; - for (int x = 0; x < effectiveSourceWidth; x += increment) + for (var x = 0; x < effectiveSourceWidth; x += increment) { if (x >= widthCounter) { @@ -59,10 +65,10 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.AmbienceCreator targetWidthIndex++; } - int colorsOffset = targetWidthIndex; - int sourceOffset = ((((relevantOffsetTop + y) * sourceWidth) + offsetLeft + x) * 4); + var colorsOffset = targetWidthIndex; + var sourceOffset = ((relevantOffsetTop + y)*sourceWidth + offsetLeft + x)*4; - AvgColor color = colors[colorsOffset]; + var color = colors[colorsOffset]; color.AddB(pixels[sourceOffset]); color.AddG(pixels[sourceOffset + 1]); color.AddR(pixels[sourceOffset + 2]); @@ -76,4 +82,4 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.AmbienceCreator #endregion } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/AmbienceCreatorMirror.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/AmbienceCreatorMirror.cs index 3d4569eed..a659eb9a6 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/AmbienceCreatorMirror.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/AmbienceCreatorMirror.cs @@ -9,43 +9,50 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.AmbienceCreator #region Methods public byte[] GetAmbience(byte[] pixels, int sourceWidth, int sourceHeight, - int targetWidth, int targetHeight, - AmbientLightPropertiesModel settings) + int targetWidth, int targetHeight, + AmbientLightPropertiesModel settings) { - AvgColor[] colors = new AvgColor[targetWidth * targetHeight]; - for (int i = 0; i < colors.Length; i++) + var colors = new AvgColor[targetWidth*targetHeight]; + for (var i = 0; i < colors.Length; i++) colors[i] = new AvgColor(); - int offsetLeft = settings.OffsetLeft + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Left) - ? pixels.DetectBlackBarLeft(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) + var offsetLeft = settings.OffsetLeft + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Left) + ? pixels.DetectBlackBarLeft(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, + settings.OffsetTop, settings.OffsetBottom) : 0); - int offsetRight = settings.OffsetRight + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Right) - ? pixels.DetectBlackBarRight(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) - : 0); - int offsetTop = settings.OffsetTop + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Top) - ? pixels.DetectBlackBarTop(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) - : 0); - int offsetBottom = settings.OffsetBottom + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Bottom) - ? pixels.DetectBlackBarBottom(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) + var offsetRight = settings.OffsetRight + + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Right) + ? pixels.DetectBlackBarRight(sourceWidth, sourceHeight, settings.OffsetLeft, + settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) + : 0); + var offsetTop = settings.OffsetTop + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Top) + ? pixels.DetectBlackBarTop(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, + settings.OffsetTop, settings.OffsetBottom) : 0); + var offsetBottom = settings.OffsetBottom + + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Bottom) + ? pixels.DetectBlackBarBottom(sourceWidth, sourceHeight, settings.OffsetLeft, + settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) + : 0); - int effectiveSourceWidth = sourceWidth - offsetLeft - offsetRight; - int effectiveSourceHeight = sourceHeight - offsetTop - offsetBottom; + var effectiveSourceWidth = sourceWidth - offsetLeft - offsetRight; + var effectiveSourceHeight = sourceHeight - offsetTop - offsetBottom; - int relevantSourceHeight = (int)Math.Round(effectiveSourceHeight * (settings.MirroredAmount / 100.0)); - int relevantOffsetTop = sourceHeight - offsetBottom - relevantSourceHeight; + var relevantSourceHeight = (int) Math.Round(effectiveSourceHeight*(settings.MirroredAmount/100.0)); + var relevantOffsetTop = sourceHeight - offsetBottom - relevantSourceHeight; - double widthPixels = effectiveSourceWidth / (double)targetWidth; - double heightPixels = relevantSourceHeight / (double)targetHeight; + var widthPixels = effectiveSourceWidth/(double) targetWidth; + var heightPixels = relevantSourceHeight/(double) targetHeight; - if (widthPixels <= 0 || heightPixels <= 0 || (relevantSourceHeight + relevantOffsetTop > sourceHeight) || effectiveSourceWidth > sourceWidth) + if (widthPixels <= 0 || heightPixels <= 0 || (relevantSourceHeight + relevantOffsetTop > sourceHeight) || + effectiveSourceWidth > sourceWidth) return colors.ToBGRArray(); - int targetHeightIndex = 0; - double heightCounter = heightPixels; + var targetHeightIndex = 0; + var heightCounter = heightPixels; - int increment = Math.Max(1, Math.Min(20, settings.Downsampling)); - for (int y = 0; y < relevantSourceHeight; y += increment) + var increment = Math.Max(1, Math.Min(20, settings.Downsampling)); + for (var y = 0; y < relevantSourceHeight; y += increment) { if (y >= heightCounter) { @@ -53,10 +60,10 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.AmbienceCreator targetHeightIndex++; } - int targetWidthIndex = 0; - double widthCounter = widthPixels; + var targetWidthIndex = 0; + var widthCounter = widthPixels; - for (int x = 0; x < effectiveSourceWidth; x += increment) + for (var x = 0; x < effectiveSourceWidth; x += increment) { if (x >= widthCounter) { @@ -64,10 +71,10 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.AmbienceCreator targetWidthIndex++; } - int colorsOffset = (targetHeightIndex * targetWidth) + targetWidthIndex; - int sourceOffset = ((((relevantOffsetTop + y) * sourceWidth) + offsetLeft + x) * 4); + var colorsOffset = targetHeightIndex*targetWidth + targetWidthIndex; + var sourceOffset = ((relevantOffsetTop + y)*sourceWidth + offsetLeft + x)*4; - AvgColor color = colors[colorsOffset]; + var color = colors[colorsOffset]; color.AddB(pixels[sourceOffset]); color.AddG(pixels[sourceOffset + 1]); color.AddR(pixels[sourceOffset + 2]); @@ -80,4 +87,4 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.AmbienceCreator #endregion } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/AvgColor.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/AvgColor.cs index 9cef78a27..8c6a60e9b 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/AvgColor.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/AvgColor.cs @@ -4,16 +4,16 @@ { #region Properties & Fields - private int _rCount = 0; - private int _r = 0; - private int _gCount = 0; - private int _g = 0; - private int _bCount = 0; - private int _b = 0; + private int _rCount; + private int _r; + private int _gCount; + private int _g; + private int _bCount; + private int _b; - public byte R => (byte)(_rCount > 0 ? (_r / _rCount) : 0); - public byte G => (byte)(_gCount > 0 ? (_g / _gCount) : 0); - public byte B => (byte)(_bCount > 0 ? (_b / _bCount) : 0); + public byte R => (byte) (_rCount > 0 ? _r/_rCount : 0); + public byte G => (byte) (_gCount > 0 ? _g/_gCount : 0); + public byte B => (byte) (_bCount > 0 ? _b/_bCount : 0); #endregion @@ -39,4 +39,4 @@ #endregion } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/IAmbienceCreator.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/IAmbienceCreator.cs index df84941bd..8492a0ea2 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/IAmbienceCreator.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/IAmbienceCreator.cs @@ -2,6 +2,7 @@ { public interface IAmbienceCreator { - byte[] GetAmbience(byte[] pixels, int sourceWidth, int sourceHeight, int targetWidth, int targetHeight, AmbientLightPropertiesModel settings); + byte[] GetAmbience(byte[] pixels, int sourceWidth, int sourceHeight, int targetWidth, int targetHeight, + AmbientLightPropertiesModel settings); } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesModel.cs index 5579ae504..c548b3077 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesModel.cs @@ -7,6 +7,16 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight { public class AmbientLightPropertiesModel : LayerPropertiesModel { + #region Constructors + + public AmbientLightPropertiesModel(LayerPropertiesModel properties) + : base(properties) + { + Brush = new SolidColorBrush(Color.FromRgb(0, 0, 0)); + } + + #endregion + #region Properties & Fields //HACK DarthAffe 30.10.2016: The 'normal' Brush-Property destoys the profile since Drawing-Brushes cannot be deserialized. @@ -28,15 +38,5 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight public FlipMode FlipMode { get; set; } = FlipMode.Vertical; #endregion - - #region Constructors - - public AmbientLightPropertiesModel(LayerPropertiesModel properties) - : base(properties) - { - Brush = new SolidColorBrush(Color.FromRgb(0, 0, 0)); - } - - #endregion } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesView.xaml index 78a0e2118..8201fe8d9 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesView.xaml +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesView.xaml @@ -1,14 +1,14 @@  @@ -51,7 +51,8 @@ - @@ -65,12 +66,14 @@ - + Value="{Binding Path=LayerModel.Properties.MirroredAmount, Mode=TwoWay}" + Margin="10,12,10,2" Height="24" /> + + Value="{Binding Path=LayerModel.Properties.Downsampling, Mode=TwoWay}" + Margin="10,12,10,2" Height="24" /> + Value="{Binding Path=LayerModel.Properties.OffsetLeft, Mode=TwoWay}" + Margin="10,12,10,2" Height="24" /> + Value="{Binding Path=LayerModel.Properties.OffsetRight, Mode=TwoWay}" + Margin="10,12,10,2" Height="24" /> + Value="{Binding Path=LayerModel.Properties.OffsetTop, Mode=TwoWay}" Margin="10,12,10,2" + Height="24" /> + Value="{Binding Path=LayerModel.Properties.OffsetBottom, Mode=TwoWay}" + Margin="10,12,10,2" Height="24" /> - + \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesView.xaml.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesView.xaml.cs index f85eca5c2..a7539b649 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesView.xaml.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesView.xaml.cs @@ -9,4 +9,4 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight InitializeComponent(); } } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesViewModel.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesViewModel.cs index 4926ff2c4..7e71757d0 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesViewModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesViewModel.cs @@ -9,15 +9,17 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight public AmbientLightPropertiesViewModel(LayerEditorViewModel editorVm) : base(editorVm) - { } + { + } #endregion #region Methods public override void ApplyProperties() - { } + { + } #endregion } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightType.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightType.cs index 6e75cd928..c176040f9 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightType.cs @@ -26,13 +26,11 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight public bool ShowInEdtor => true; public DrawType DrawType => DrawType.Keyboard; - [JsonIgnore] - private AmbienceCreatorType? _lastAmbienceCreatorType = null; - [JsonIgnore] - private IAmbienceCreator _lastAmbienceCreator; + [JsonIgnore] private AmbienceCreatorType? _lastAmbienceCreatorType; - [JsonIgnore] - private byte[] _lastData; + [JsonIgnore] private IAmbienceCreator _lastAmbienceCreator; + + [JsonIgnore] private byte[] _lastData; #endregion @@ -56,36 +54,39 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) { - AmbientLightPropertiesModel properties = layerModel?.Properties as AmbientLightPropertiesModel; + var properties = layerModel?.Properties as AmbientLightPropertiesModel; if (properties == null) return; - int width = (int)Math.Round(properties.Width); - int height = (int)Math.Round(properties.Height); + var width = (int) Math.Round(properties.Width); + var height = (int) Math.Round(properties.Height); - byte[] data = ScreenCaptureManager.GetLastScreenCapture(); - byte[] newData = GetAmbienceCreator(properties).GetAmbience(data, ScreenCaptureManager.LastCaptureWidth, ScreenCaptureManager.LastCaptureHeight, width, height, properties); + var data = ScreenCaptureManager.GetLastScreenCapture(); + var newData = GetAmbienceCreator(properties) + .GetAmbience(data, ScreenCaptureManager.LastCaptureWidth, ScreenCaptureManager.LastCaptureHeight, width, + height, properties); _lastData = _lastData?.Blend(newData, properties.SmoothMode) ?? newData; - int stride = (width * ScreenCaptureManager.LastCapturePixelFormat.BitsPerPixel + 7) / 8; + var stride = (width*ScreenCaptureManager.LastCapturePixelFormat.BitsPerPixel + 7)/8; properties.AmbientLightBrush = new DrawingBrush(new ImageDrawing - (BitmapSource.Create(width, height, 96, 96, ScreenCaptureManager.LastCapturePixelFormat, null, _lastData, stride), new Rect(0, 0, width, height))); + (BitmapSource.Create(width, height, 96, 96, ScreenCaptureManager.LastCapturePixelFormat, null, _lastData, + stride), new Rect(0, 0, width, height))); } - public void Draw(LayerModel layer, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { - Rect rect = new Rect(layer.Properties.X * 4, - layer.Properties.Y * 4, - layer.Properties.Width * 4, - layer.Properties.Height * 4); + var rect = new Rect(layerModel.Properties.X*4, + layerModel.Properties.Y*4, + layerModel.Properties.Width*4, + layerModel.Properties.Height*4); - c.DrawRectangle(((AmbientLightPropertiesModel)layer.Properties).AmbientLightBrush, null, rect); + c.DrawRectangle(((AmbientLightPropertiesModel) layerModel.Properties).AmbientLightBrush, null, rect); } public ImageSource DrawThumbnail(LayerModel layer) { - Rect thumbnailRect = new Rect(0, 0, 18, 18); - DrawingVisual visual = new DrawingVisual(); - using (DrawingContext c = visual.RenderOpen()) + var thumbnailRect = new Rect(0, 0, 18, 18); + var visual = new DrawingVisual(); + using (var c = visual.RenderOpen()) c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.ambilight), thumbnailRect); return new DrawingImage(visual.Drawing); @@ -99,12 +100,15 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight _lastAmbienceCreatorType = properties.AmbienceCreatorType; switch (properties.AmbienceCreatorType) { - case AmbienceCreatorType.Mirror: return _lastAmbienceCreator = new AmbienceCreatorMirror(); - case AmbienceCreatorType.Extend: return _lastAmbienceCreator = new AmbienceCreatorExtend(); - default: throw new InvalidEnumArgumentException(); + case AmbienceCreatorType.Mirror: + return _lastAmbienceCreator = new AmbienceCreatorMirror(); + case AmbienceCreatorType.Extend: + return _lastAmbienceCreator = new AmbienceCreatorExtend(); + default: + throw new InvalidEnumArgumentException(); } } #endregion } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Helper/CheckboxEnumFlagHelper.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Helper/CheckboxEnumFlagHelper.cs index 6ba6a423c..b6157ad68 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Helper/CheckboxEnumFlagHelper.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Helper/CheckboxEnumFlagHelper.cs @@ -8,10 +8,13 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Helper public class CheckboxEnumFlagHelper { #region DependencyProperties + // ReSharper disable InconsistentNaming public static readonly DependencyProperty FlagsProperty = DependencyProperty.RegisterAttached( - "Flags", typeof(Enum), typeof(CheckboxEnumFlagHelper), new FrameworkPropertyMetadata(default(Enum), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, FlagsChanged)); + "Flags", typeof(Enum), typeof(CheckboxEnumFlagHelper), + new FrameworkPropertyMetadata(default(Enum), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, + FlagsChanged)); public static void SetFlags(DependencyObject element, Enum value) { @@ -20,7 +23,7 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Helper public static Enum GetFlags(DependencyObject element) { - return (Enum)element.GetValue(FlagsProperty); + return (Enum) element.GetValue(FlagsProperty); } public static readonly DependencyProperty ValueProperty = DependencyProperty.RegisterAttached( @@ -33,10 +36,11 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Helper public static Enum GetValue(DependencyObject element) { - return (Enum)element.GetValue(ValueProperty); + return (Enum) element.GetValue(ValueProperty); } // ReSharper restore InconsistentNaming + #endregion #region Methods @@ -50,7 +54,7 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Helper private static void ValueChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) { - CheckBox checkbox = dependencyObject as CheckBox; + var checkbox = dependencyObject as CheckBox; if (checkbox == null) return; checkbox.Checked -= UpdateSource; @@ -69,17 +73,17 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Helper { if (checkbox == null) return; - Enum value = GetValue(checkbox); + var value = GetValue(checkbox); checkbox.IsChecked = value != null && (flags?.HasFlag(value) ?? false); } private static void UpdateSource(object sender, RoutedEventArgs routedEventArgs) { - CheckBox checkbox = sender as CheckBox; + var checkbox = sender as CheckBox; if (checkbox == null) return; - Enum flags = GetFlags(checkbox); - Enum value = GetValue(checkbox); + var flags = GetFlags(checkbox); + var value = GetValue(checkbox); if (value == null) return; if (checkbox.IsChecked ?? false) @@ -90,4 +94,4 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Helper #endregion } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/AmbienceCreatorType.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/AmbienceCreatorType.cs index 8f7f389e4..209d8c785 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/AmbienceCreatorType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/AmbienceCreatorType.cs @@ -4,10 +4,8 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model { public enum AmbienceCreatorType { - [Description("Mirror")] - Mirror, + [Description("Mirror")] Mirror, - [Description("Extend")] - Extend + [Description("Extend")] Extend } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/BlackBarDetectionMode.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/BlackBarDetectionMode.cs index 31a3cfbfc..905c58d23 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/BlackBarDetectionMode.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/BlackBarDetectionMode.cs @@ -9,6 +9,6 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model Left = 1 << 0, Right = 1 << 1, Top = 1 << 2, - Bottom = 1 << 3, + Bottom = 1 << 3 } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/AvgColorExtension.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/AvgColorExtension.cs index 449072211..225b118b7 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/AvgColorExtension.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/AvgColorExtension.cs @@ -23,10 +23,10 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model.Extensions public static AvgColor[] ExtendHeight(this AvgColor[] colors, int height) { - AvgColor[] extended = new AvgColor[colors.Length * height]; + var extended = new AvgColor[colors.Length*height]; - for (int i = 0; i < height; i++) - Array.Copy(colors, 0, extended, i * colors.Length, colors.Length); + for (var i = 0; i < height; i++) + Array.Copy(colors, 0, extended, i*colors.Length, colors.Length); return extended; } @@ -35,9 +35,9 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model.Extensions { if (colors == null || width <= 0) return colors; - AvgColor[] flipped = new AvgColor[colors.Length]; + var flipped = new AvgColor[colors.Length]; for (int i = 0, j = colors.Length - width; i < colors.Length; i += width, j -= width) - for (int k = 0; k < width; ++k) + for (var k = 0; k < width; ++k) flipped[i + k] = colors[j + k]; return flipped; @@ -47,8 +47,8 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model.Extensions { if (colors == null || width <= 0) return colors; - AvgColor[] flipped = new AvgColor[colors.Length]; - for (int i = 0; i < colors.Length; i += width) + var flipped = new AvgColor[colors.Length]; + for (var i = 0; i < colors.Length; i += width) for (int j = 0, k = width - 1; j < width; ++j, --k) flipped[i + j] = colors[i + k]; @@ -57,9 +57,9 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model.Extensions public static byte[] ToBGRArray(this AvgColor[] colors) { - byte[] newData = new byte[colors.Length * 3]; - int counter = 0; - foreach (AvgColor color in colors) + var newData = new byte[colors.Length*3]; + var counter = 0; + foreach (var color in colors) { newData[counter++] = color.B; newData[counter++] = color.G; @@ -71,4 +71,4 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model.Extensions #endregion } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/EnumExtension.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/EnumExtension.cs index 65f1ea6f9..e39c2a03d 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/EnumExtension.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/EnumExtension.cs @@ -10,17 +10,17 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model.Extensions { if (e == null || value == null || t == null) return e; - int eValue = Convert.ToInt32(e); - int valueValue = Convert.ToInt32(value); + var eValue = Convert.ToInt32(e); + var valueValue = Convert.ToInt32(value); if (set) eValue |= valueValue; else eValue &= ~valueValue; - return (Enum)Enum.ToObject(t, eValue); + return (Enum) Enum.ToObject(t, eValue); } #endregion } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/PixelDataExtension.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/PixelDataExtension.cs index 5fa442669..a315a3965 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/PixelDataExtension.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/PixelDataExtension.cs @@ -6,17 +6,18 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model.Extensions { #region Methods - public static int DetectBlackBarLeft(this byte[] pixels, int width, int height, int offsetLeft, int offsetRight, int offsetTop, int offsetBottom) + public static int DetectBlackBarLeft(this byte[] pixels, int width, int height, int offsetLeft, int offsetRight, + int offsetTop, int offsetBottom) { - int bottomBorder = height - offsetBottom; - int rightBorder = width - offsetRight; + var bottomBorder = height - offsetBottom; + var rightBorder = width - offsetRight; - int blackBarWidth = 0; - for (int x = rightBorder - 1; x >= offsetLeft; x--) + var blackBarWidth = 0; + for (var x = rightBorder - 1; x >= offsetLeft; x--) { - for (int y = offsetTop; y < bottomBorder; y++) + for (var y = offsetTop; y < bottomBorder; y++) { - int offset = ((y * width) + x) * 4; + var offset = (y*width + x)*4; if (pixels[offset] > 15 || pixels[offset + 1] > 15 || pixels[offset + 2] > 15) return blackBarWidth; } @@ -26,17 +27,18 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model.Extensions return width; } - public static int DetectBlackBarRight(this byte[] pixels, int width, int height, int offsetLeft, int offsetRight, int offsetTop, int offsetBottom) + public static int DetectBlackBarRight(this byte[] pixels, int width, int height, int offsetLeft, int offsetRight, + int offsetTop, int offsetBottom) { - int bottomBorder = height - offsetBottom; - int rightBorder = width - offsetRight; + var bottomBorder = height - offsetBottom; + var rightBorder = width - offsetRight; - int blackBarWidth = 0; - for (int x = offsetLeft; x < rightBorder; x++) + var blackBarWidth = 0; + for (var x = offsetLeft; x < rightBorder; x++) { - for (int y = offsetTop; y < bottomBorder; y++) + for (var y = offsetTop; y < bottomBorder; y++) { - int offset = ((y * width) + x) * 4; + var offset = (y*width + x)*4; if (pixels[offset] > 15 || pixels[offset + 1] > 15 || pixels[offset + 2] > 15) return blackBarWidth; } @@ -46,17 +48,18 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model.Extensions return width; } - public static int DetectBlackBarTop(this byte[] pixels, int width, int height, int offsetLeft, int offsetRight, int offsetTop, int offsetBottom) + public static int DetectBlackBarTop(this byte[] pixels, int width, int height, int offsetLeft, int offsetRight, + int offsetTop, int offsetBottom) { - int bottomBorder = height - offsetBottom; - int rightBorder = width - offsetRight; + var bottomBorder = height - offsetBottom; + var rightBorder = width - offsetRight; - int blackBarHeight = 0; - for (int y = offsetTop; y < bottomBorder; y++) + var blackBarHeight = 0; + for (var y = offsetTop; y < bottomBorder; y++) { - for (int x = offsetLeft; x < rightBorder; x++) + for (var x = offsetLeft; x < rightBorder; x++) { - int offset = ((y * width) + x) * 4; + var offset = (y*width + x)*4; if (pixels[offset] > 15 || pixels[offset + 1] > 15 || pixels[offset + 2] > 15) return blackBarHeight; } @@ -66,17 +69,18 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model.Extensions return height; } - public static int DetectBlackBarBottom(this byte[] pixels, int width, int height, int offsetLeft, int offsetRight, int offsetTop, int offsetBottom) + public static int DetectBlackBarBottom(this byte[] pixels, int width, int height, int offsetLeft, + int offsetRight, int offsetTop, int offsetBottom) { - int bottomBorder = height - offsetBottom; - int rightBorder = width - offsetRight; + var bottomBorder = height - offsetBottom; + var rightBorder = width - offsetRight; - int blackBarHeight = 0; - for (int y = bottomBorder - 1; y >= offsetTop; y--) + var blackBarHeight = 0; + for (var y = bottomBorder - 1; y >= offsetTop; y--) { - for (int x = offsetLeft; x < rightBorder; x++) + for (var x = offsetLeft; x < rightBorder; x++) { - int offset = ((y * width) + x) * 4; + var offset = (y*width + x)*4; if (pixels[offset] > 15 || pixels[offset + 1] > 15 || pixels[offset + 2] > 15) return blackBarHeight; } @@ -89,23 +93,25 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model.Extensions public static byte[] Blend(this byte[] pixels, byte[] blendPixels, SmoothMode smoothMode) { if (smoothMode == SmoothMode.None || pixels.Length != blendPixels.Length) return blendPixels; - - double percentage = smoothMode == SmoothMode.Low? 0.25: (smoothMode == SmoothMode.Medium ? 0.075 : 0.025 /*high*/); - byte[] blended = new byte[pixels.Length]; + var percentage = smoothMode == SmoothMode.Low + ? 0.25 + : (smoothMode == SmoothMode.Medium ? 0.075 : 0.025 /*high*/); - for (int i = 0; i < blended.Length; i++) - blended[i] = GetIntColor((blendPixels[i] / 255.0) * percentage + (pixels[i] / 255.0) * (1 - percentage)); + var blended = new byte[pixels.Length]; + + for (var i = 0; i < blended.Length; i++) + blended[i] = GetIntColor(blendPixels[i]/255.0*percentage + pixels[i]/255.0*(1 - percentage)); return blended; } private static byte GetIntColor(double d) { - double calcF = Math.Max(0, Math.Min(1, d)); - return (byte)(calcF.Equals(1) ? 255 : calcF * 256); + var calcF = Math.Max(0, Math.Min(1, d)); + return (byte) (calcF.Equals(1) ? 255 : calcF*256); } #endregion } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/FlipMode.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/FlipMode.cs index 540617a5e..eee9666b2 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/FlipMode.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/FlipMode.cs @@ -9,4 +9,4 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model Vertical = 1 << 0, Horizontal = 1 << 1 } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/ScreenCaptureMode.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/ScreenCaptureMode.cs index 23213b13e..dd37f813e 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/ScreenCaptureMode.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/ScreenCaptureMode.cs @@ -4,7 +4,6 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model { public enum ScreenCaptureMode { - [Description("DirectX 9")] - DirectX9 + [Description("DirectX 9")] DirectX9 } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/SmoothMode.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/SmoothMode.cs index 19c2bd3fd..222bf0037 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/SmoothMode.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/SmoothMode.cs @@ -4,16 +4,12 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model { public enum SmoothMode { - [Description("None")] - None, + [Description("None")] None, - [Description("Low")] - Low, + [Description("Low")] Low, - [Description("Medium")] - Medium, + [Description("Medium")] Medium, - [Description("High")] - High + [Description("High")] High } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/ScreenCapturing/DX9ScreenCapture.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/ScreenCapturing/DX9ScreenCapture.cs index 5833fda07..13c8c02c3 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/ScreenCapturing/DX9ScreenCapture.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/ScreenCapturing/DX9ScreenCapture.cs @@ -2,25 +2,12 @@ using System.Runtime.InteropServices; using System.Windows.Forms; using System.Windows.Media; -using SharpDX; using SharpDX.Direct3D9; namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing { public class DX9ScreenCapture : IScreenCapture { - #region Properties & Fields - - private Device _device; - private Surface _surface; - private byte[] _buffer; - - public int Width { get; } - public int Height { get; } - public PixelFormat PixelFormat => PixelFormats.Bgr24; - - #endregion - #region Constructors public DX9ScreenCapture() @@ -28,26 +15,39 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing Width = Screen.PrimaryScreen.Bounds.Width; Height = Screen.PrimaryScreen.Bounds.Height; - PresentParameters presentParams = new PresentParameters(Width, Height) + var presentParams = new PresentParameters(Width, Height) { Windowed = true, SwapEffect = SwapEffect.Discard }; - _device = new Device(new Direct3D(), 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.SoftwareVertexProcessing, presentParams); + _device = new Device(new Direct3D(), 0, DeviceType.Hardware, IntPtr.Zero, + CreateFlags.SoftwareVertexProcessing, presentParams); _surface = Surface.CreateOffscreenPlain(_device, Width, Height, Format.A8R8G8B8, Pool.Scratch); - _buffer = new byte[Width * Height * 4]; + _buffer = new byte[Width*Height*4]; } #endregion + #region Properties & Fields + + private readonly Device _device; + private readonly Surface _surface; + private readonly byte[] _buffer; + + public int Width { get; } + public int Height { get; } + public PixelFormat PixelFormat => PixelFormats.Bgr24; + + #endregion + #region Methods public byte[] CaptureScreen() { _device.GetFrontBufferData(0, _surface); - DataRectangle dr = _surface.LockRectangle(LockFlags.None); + var dr = _surface.LockRectangle(LockFlags.None); Marshal.Copy(dr.DataPointer, _buffer, 0, _buffer.Length); _surface.UnlockRectangle(); @@ -62,4 +62,4 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing #endregion } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/ScreenCapturing/IScreenCapture.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/ScreenCapturing/IScreenCapture.cs index 343d1c2ba..1acdfbadb 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/ScreenCapturing/IScreenCapture.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/ScreenCapturing/IScreenCapture.cs @@ -10,9 +10,9 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing PixelFormat PixelFormat { get; } /// - /// As Pixel-Data BGRA + /// As Pixel-Data BGRA /// /// The Pixel-Data byte[] CaptureScreen(); } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/ScreenCapturing/ScreenCaptureManager.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/ScreenCapturing/ScreenCaptureManager.cs index 92fe05ef5..35182634e 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/ScreenCapturing/ScreenCaptureManager.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/ScreenCapturing/ScreenCaptureManager.cs @@ -14,13 +14,14 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing private static Thread _worker; private static DateTime _lastCaptureAccess; private static volatile byte[] _lastScreenCapture; - private static volatile bool _isRunning = false; + private static volatile bool _isRunning; - private static ScreenCaptureMode? _lastScreenCaptureMode = null; + private static ScreenCaptureMode? _lastScreenCaptureMode; private static IScreenCapture _screenCapture; public static double StandByTime { get; set; } = 3; - public static double UpdateRate { get; set; } = 1.0 / 20.0; // DarthAffe 29.10.2016: I think 20 FPS should be enough as default + public static double UpdateRate { get; set; } = 1.0/20.0; + // DarthAffe 29.10.2016: I think 20 FPS should be enough as default public static ScreenCaptureMode ScreenCaptureMode { get; set; } = ScreenCaptureMode.DirectX9; public static int LastCaptureWidth { get; private set; } @@ -41,8 +42,10 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing _lastScreenCaptureMode = ScreenCaptureMode; switch (ScreenCaptureMode) { - case ScreenCaptureMode.DirectX9: return _screenCapture = new DX9ScreenCapture(); - default: throw new InvalidEnumArgumentException(); + case ScreenCaptureMode.DirectX9: + return _screenCapture = new DX9ScreenCapture(); + default: + throw new InvalidEnumArgumentException(); } } @@ -59,7 +62,7 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing { while ((DateTime.Now - _lastCaptureAccess).TotalSeconds < StandByTime) { - DateTime lastCapture = DateTime.Now; + var lastCapture = DateTime.Now; try { CaptureScreen(); @@ -69,7 +72,7 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing Debug.WriteLine("[CaptureLoop]: " + ex.Message); } - int sleep = (int)((UpdateRate - (DateTime.Now - lastCapture).TotalSeconds) * 1000); + var sleep = (int) ((UpdateRate - (DateTime.Now - lastCapture).TotalSeconds)*1000); if (sleep > 0) Thread.Sleep(sleep); } @@ -83,7 +86,7 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing private static void CaptureScreen() { - IScreenCapture screenCapture = GetScreenCapture(); + var screenCapture = GetScreenCapture(); _lastScreenCapture = screenCapture.CaptureScreen(); LastCaptureWidth = screenCapture.Width; @@ -113,4 +116,4 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing #endregion } -} +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCaptureManager.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCaptureManager.cs new file mode 100644 index 000000000..8d1df47a1 --- /dev/null +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCaptureManager.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Artemis.Modules.Effects.AudioVisualizer.Utilities; +using NAudio.CoreAudioApi; +using NAudio.Dsp; +using NAudio.Wave; +using Ninject.Extensions.Logging; + +namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing +{ + public class AudioCaptureManager + { + private readonly SampleAggregator _sampleAggregator = new SampleAggregator(1024); + private readonly WasapiLoopbackCapture _waveIn; + private Complex[] _fft; + private DateTime _lastAudioUpdate; + private DateTime _lastRequest; + + public AudioCaptureManager(ILogger logger) + { + Logger = logger; + Device = new MMDeviceEnumerator().EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active).FirstOrDefault(); + + _sampleAggregator.FftCalculated += FftCalculated; + _sampleAggregator.PerformFFT = true; + + // Start listening for sound data + _waveIn = new WasapiLoopbackCapture(); + _waveIn.DataAvailable += OnDataAvailable; + } + + public ILogger Logger { get; set; } + public MMDevice Device { get; set; } + + public bool Running { get; set; } + + public void Start() + { + if (Running) + return; + + try + { + _waveIn.StartRecording(); + Running = true; + } + catch (Exception e) + { + Logger.Warn(e, "Failed to start WASAPI audio capture"); + } + } + + public void Stop() + { + if (!Running) + return; + + try + { + _waveIn.StopRecording(); + Running = false; + } + catch (Exception e) + { + Logger.Warn(e, "Failed to start WASAPI audio capture"); + } + } + + private void FftCalculated(object sender, FftEventArgs e) + { + _fft = e.Result; + } + + private void OnDataAvailable(object sender, WaveInEventArgs e) + { + if (DateTime.Now - _lastAudioUpdate < TimeSpan.FromMilliseconds(40)) + return; + if (DateTime.Now - _lastRequest > TimeSpan.FromSeconds(5)) + { + Stop(); + return; + } + + _lastAudioUpdate = DateTime.Now; + + var buffer = e.Buffer; + var bytesRecorded = e.BytesRecorded; + var bufferIncrement = _waveIn.WaveFormat.BlockAlign; + + for (var index = 0; index < bytesRecorded; index += bufferIncrement) + { + var sample32 = BitConverter.ToSingle(buffer, index); + _sampleAggregator.Add(sample32); + } + } + + public List GetSpectrumData(int lines) + { + _lastRequest = DateTime.Now; + if (!Running) + Start(); + + var spectrumData = new List(); + + if (_fft == null) + return spectrumData; + + int x; + var b0 = 0; + + for (x = 0; x < lines; x++) + { + float peak = 0; + var b1 = (int) Math.Pow(2, x*10.0/(lines - 1)); + if (b1 > 1023) + b1 = 1023; + if (b1 <= b0) + b1 = b0 + 1; + for (; b0 < b1; b0++) + if (peak < _fft[1 + b0].X) + peak = _fft[1 + b0].X; + var y = (int) (Math.Sqrt(peak)*3*255 - 4); + if (y > 255) + y = 255; + if (y < 0) + y = 0; + spectrumData.Add((byte) y); + } + + return spectrumData; + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesView.xaml index a400d2b0a..e6bfb99ef 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesView.xaml +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesView.xaml @@ -34,37 +34,58 @@ + + + + + + + + + + + + + + - - - - - + - - - diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesViewModel.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesViewModel.cs index cc502a220..ca276c666 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesViewModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesViewModel.cs @@ -1,17 +1,40 @@ -using Artemis.Profiles.Layers.Abstract; +using System.Linq; +using Artemis.Profiles.Layers.Abstract; +using Artemis.Profiles.Layers.Interfaces; using Artemis.ViewModels.Profiles; +using Caliburn.Micro; namespace Artemis.Profiles.Layers.Types.Audio { public class AudioPropertiesViewModel : LayerPropertiesViewModel { + private ILayerAnimation _selectedLayerAnimation; + public AudioPropertiesViewModel(LayerEditorViewModel editorVm) : base(editorVm) { + LayerAnimations = new BindableCollection(editorVm.LayerAnimations); + SelectedLayerAnimation = + LayerAnimations.FirstOrDefault(l => l.Name == editorVm.ProposedLayer.LayerAnimation?.Name) ?? + LayerAnimations.First(l => l.Name == "None"); + } + + public BindableCollection LayerAnimations { get; set; } + + public ILayerAnimation SelectedLayerAnimation + { + get { return _selectedLayerAnimation; } + set + { + if (Equals(value, _selectedLayerAnimation)) return; + _selectedLayerAnimation = value; + NotifyOfPropertyChange(() => SelectedLayerAnimation); + } } public override void ApplyProperties() { LayerModel.Properties.Brush = Brush; + LayerModel.LayerAnimation = SelectedLayerAnimation; } } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs index a3de34dbf..02e0ec205 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs @@ -4,56 +4,35 @@ using System.Linq; using System.Windows; using System.Windows.Media; using Artemis.Models.Interfaces; -using Artemis.Modules.Effects.AudioVisualizer.Utilities; using Artemis.Profiles.Layers.Abstract; -using Artemis.Profiles.Layers.Animations; using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; +using Artemis.Profiles.Layers.Types.Audio.AudioCapturing; using Artemis.Properties; using Artemis.Utilities; using Artemis.ViewModels.Profiles; -using NAudio.CoreAudioApi; -using NAudio.Wave; using Newtonsoft.Json; -using NLog; +using Ninject; namespace Artemis.Profiles.Layers.Types.Audio { internal class AudioType : ILayerType { private readonly List _audioLayers = new List(); - private readonly MMDevice _device; - private readonly SampleAggregator _sampleAggregator = new SampleAggregator(1024); - private readonly WasapiLoopbackCapture _waveIn; - private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + private readonly IKernel _kernel; + + private DateTime _lastUpdate; private int _lines; - private AudioPropertiesModel _previousSettings; + private string _previousSettings; - public AudioType() + public AudioType(IKernel kernel, AudioCaptureManager audioCaptureManager) { - _device = new MMDeviceEnumerator() - .EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active).FirstOrDefault(); - - _sampleAggregator.FftCalculated += FftCalculated; - _sampleAggregator.PerformFFT = true; - - // Start listening for sound data - _waveIn = new WasapiLoopbackCapture(); - _waveIn.DataAvailable += OnDataAvailable; - - try - { - _waveIn.StartRecording(); - } - catch (Exception e) - { - Logger.Warn(e, "Failed to start WASAPI audio capture"); - throw; - } + _kernel = kernel; + AudioCaptureManager = audioCaptureManager; } [JsonIgnore] - public List SpectrumData { get; set; } = new List(); + public AudioCaptureManager AudioCaptureManager { get; set; } public string Name => "Keyboard - Audio visualization"; public bool ShowInEdtor => true; @@ -72,9 +51,9 @@ namespace Artemis.Profiles.Layers.Types.Audio return image; } - public void Draw(LayerModel layer, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { - lock (SpectrumData) + lock (_audioLayers) { foreach (var audioLayer in _audioLayers) { @@ -84,10 +63,10 @@ namespace Artemis.Profiles.Layers.Types.Audio var oldX = audioLayer.Properties.X; var oldY = audioLayer.Properties.Y; - audioLayer.Properties.Width = layer.Properties.Width; - audioLayer.Properties.Height = layer.Properties.Height; - audioLayer.Properties.X = layer.Properties.X; - audioLayer.Properties.Y = layer.Properties.Y; + audioLayer.Properties.Width = layerModel.Properties.Width; + audioLayer.Properties.Height = layerModel.Properties.Height; + audioLayer.Properties.X = layerModel.Properties.X; + audioLayer.Properties.Y = layerModel.Properties.Y; audioLayer.LayerType.Draw(audioLayer, c); audioLayer.Properties.Width = oldWidth; @@ -100,21 +79,29 @@ namespace Artemis.Profiles.Layers.Types.Audio public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) { - if ((_device == null) || isPreview) + layerModel.ApplyProperties(true); + if (isPreview) return; - lock (SpectrumData) + lock (_audioLayers) { - UpdateLayers(layerModel); - - if (!SpectrumData.Any()) + SetupLayers(layerModel); + var spectrumData = AudioCaptureManager.GetSpectrumData(_lines); + if (!spectrumData.Any()) return; var settings = (AudioPropertiesModel) layerModel.Properties; - if ((settings.Direction == Direction.TopToBottom) || (settings.Direction == Direction.BottomToTop)) - ApplyVertical(settings); - else if ((settings.Direction == Direction.LeftToRight) || (settings.Direction == Direction.RightToLeft)) - ApplyHorizontal(settings); + switch (settings.Direction) + { + case Direction.TopToBottom: + case Direction.BottomToTop: + ApplyVertical(spectrumData, settings); + break; + case Direction.LeftToRight: + case Direction.RightToLeft: + ApplyHorizontal(spectrumData, settings); + break; + } } } @@ -138,14 +125,14 @@ namespace Artemis.Profiles.Layers.Types.Audio return new AudioPropertiesViewModel(layerEditorViewModel); } - private void ApplyVertical(AudioPropertiesModel settings) + private void ApplyVertical(List spectrumData, AudioPropertiesModel settings) { var index = 0; foreach (var audioLayer in _audioLayers) { int height; - if (SpectrumData.Count > index) - height = (int) Math.Round(SpectrumData[index]/2.55); + if (spectrumData.Count > index) + height = (int) Math.Round(spectrumData[index]/2.55); else height = 0; @@ -169,14 +156,14 @@ namespace Artemis.Profiles.Layers.Types.Audio } } - private void ApplyHorizontal(AudioPropertiesModel settings) + private void ApplyHorizontal(List spectrumData, AudioPropertiesModel settings) { var index = 0; foreach (var audioLayer in _audioLayers) { int width; - if (SpectrumData.Count > index) - width = (int) Math.Round(SpectrumData[index]/2.55); + if (spectrumData.Count > index) + width = (int) Math.Round(spectrumData[index]/2.55); else width = 0; @@ -220,6 +207,7 @@ namespace Artemis.Profiles.Layers.Types.Audio // Fake the height and width and update the animation audioLayer.Properties.Width = settings.Width; audioLayer.Properties.Height = settings.Height; + audioLayer.LastRender = DateTime.Now; audioLayer.LayerAnimation?.Update(audioLayer, true); // Restore the height and width @@ -228,112 +216,79 @@ namespace Artemis.Profiles.Layers.Types.Audio } /// - /// Updates the inner layers when the settings have changed + /// Sets up the inner layers when the settings have changed /// /// - private void UpdateLayers(LayerModel layerModel) + private void SetupLayers(LayerModel layerModel) { - // TODO: Animation + // Checking on settings update is expensive, only do it every second + if (DateTime.Now - _lastUpdate < TimeSpan.FromSeconds(1)) + return; + _lastUpdate = DateTime.Now; + var settings = (AudioPropertiesModel) layerModel.Properties; - if ((settings.Direction == _previousSettings?.Direction) && - (settings.Sensitivity == _previousSettings.Sensitivity) && - (Math.Abs(settings.FadeSpeed - _previousSettings.FadeSpeed) < 0.001)) + var currentSettings = JsonConvert.SerializeObject(settings, Formatting.Indented); + var currentType = _audioLayers.FirstOrDefault()?.LayerAnimation?.GetType(); + + if (currentSettings == _previousSettings && (layerModel.LayerAnimation.GetType() == currentType)) return; - _previousSettings = GeneralHelpers.Clone((AudioPropertiesModel) layerModel.Properties); + _previousSettings = JsonConvert.SerializeObject(settings, Formatting.Indented); _audioLayers.Clear(); - if ((settings.Direction == Direction.TopToBottom) || (settings.Direction == Direction.BottomToTop)) - SetupVertical(settings); - else if ((settings.Direction == Direction.LeftToRight) || (settings.Direction == Direction.RightToLeft)) - SetupHorizontal(settings); + switch (settings.Direction) + { + case Direction.TopToBottom: + case Direction.BottomToTop: + SetupVertical(layerModel); + break; + case Direction.LeftToRight: + case Direction.RightToLeft: + SetupHorizontal(layerModel); + break; + default: + throw new ArgumentOutOfRangeException(); + } } - private void SetupVertical(AudioPropertiesModel settings) + private void SetupVertical(LayerModel layerModel) { - _lines = (int) settings.Width; + _lines = (int) layerModel.Properties.Width; for (var i = 0; i < _lines; i++) { var layer = LayerModel.CreateLayer(); - layer.Properties.X = settings.X + i; - layer.Properties.Y = settings.Y; + layer.Properties.X = layerModel.Properties.X + i; + layer.Properties.Y = layerModel.Properties.Y; layer.Properties.Width = 1; layer.Properties.Height = 0; - // TODO: Setup animation - layer.LayerAnimation = new NoneAnimation(); - layer.Properties.Brush = settings.Brush; + layer.Properties.AnimationSpeed = layerModel.Properties.AnimationSpeed; + layer.Properties.Brush = layerModel.Properties.Brush; layer.Properties.Contain = false; + layer.LayerAnimation = (ILayerAnimation) _kernel.Get(layerModel.LayerAnimation.GetType()); _audioLayers.Add(layer); layer.Update(null, false, true); } } - private void SetupHorizontal(AudioPropertiesModel settings) + private void SetupHorizontal(LayerModel layerModel) { - _lines = (int) settings.Height; + _lines = (int) layerModel.Properties.Height; for (var i = 0; i < _lines; i++) { var layer = LayerModel.CreateLayer(); - layer.Properties.X = settings.X; - layer.Properties.Y = settings.Y + i; + layer.Properties.X = layerModel.Properties.X; + layer.Properties.Y = layerModel.Properties.Y + i; layer.Properties.Width = 0; layer.Properties.Height = 1; - // TODO: Setup animation - layer.LayerAnimation = new NoneAnimation(); - layer.Properties.Brush = settings.Brush; + layer.Properties.AnimationSpeed = layerModel.Properties.AnimationSpeed; + layer.Properties.Brush = layerModel.Properties.Brush; layer.Properties.Contain = false; + layer.LayerAnimation = (ILayerAnimation) _kernel.Get(layerModel.LayerAnimation.GetType()); _audioLayers.Add(layer); layer.Update(null, false, true); } } - - - private void FftCalculated(object sender, FftEventArgs e) - { - if (_lines == 0) - return; - - lock (SpectrumData) - { - int x; - var b0 = 0; - - SpectrumData.Clear(); - for (x = 0; x < _lines; x++) - { - float peak = 0; - var b1 = (int) Math.Pow(2, x*10.0/(_lines - 1)); - if (b1 > 1023) - b1 = 1023; - if (b1 <= b0) - b1 = b0 + 1; - for (; b0 < b1; b0++) - if (peak < e.Result[1 + b0].X) - peak = e.Result[1 + b0].X; - var y = (int) (Math.Sqrt(peak)*3*255 - 4); - if (y > 255) - y = 255; - if (y < 0) - y = 0; - SpectrumData.Add((byte) y); - } - } - } - - // TODO: Check how often this is called - private void OnDataAvailable(object sender, WaveInEventArgs e) - { - var buffer = e.Buffer; - var bytesRecorded = e.BytesRecorded; - var bufferIncrement = _waveIn.WaveFormat.BlockAlign; - - for (var index = 0; index < bytesRecorded; index += bufferIncrement) - { - var sample32 = BitConverter.ToSingle(buffer, index); - _sampleAggregator.Add(sample32); - } - } } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/Folder/FolderType.cs b/Artemis/Artemis/Profiles/Layers/Types/Folder/FolderType.cs index 7856f0e40..c9f289373 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Folder/FolderType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Folder/FolderType.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Windows; +using System.Windows; using System.Windows.Media; using Artemis.Models.Interfaces; using Artemis.Profiles.Layers.Abstract; @@ -13,7 +12,7 @@ namespace Artemis.Profiles.Layers.Types.Folder { public class FolderType : ILayerType { - public string Name { get; } = "Folder"; + public string Name => "Folder"; public bool ShowInEdtor { get; } = false; // FolderType pretents to be a keyboard so it's children get drawn public DrawType DrawType { get; } = DrawType.Keyboard; @@ -29,7 +28,7 @@ namespace Artemis.Profiles.Layers.Types.Folder return image; } - public void Draw(LayerModel layer, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { } diff --git a/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesView.xaml index c31f063c2..7745310f3 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesView.xaml +++ b/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesView.xaml @@ -1,12 +1,13 @@  + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:ncore="http://schemas.ncore.com/wpf/xaml/colorbox" + xmlns:ObjectModel="clr-namespace:System.Collections.ObjectModel;assembly=System" + x:Class="Artemis.Profiles.Layers.Types.Generic.GenericPropertiesView" + mc:Ignorable="d" + d:DesignHeight="600" d:DesignWidth="500"> @@ -24,10 +25,10 @@ + VerticalAlignment="Center" + Height="18" /> + Height="22"> @@ -37,33 +38,42 @@ + VerticalAlignment="Center" Height="18" /> + TickPlacement="None" TickFrequency="0.05" + Value="{Binding LayerModel.Properties.AnimationSpeed, Mode=TwoWay}" Minimum="0.05" Maximum="3" + SmallChange="0" IsSnapToTickEnabled="True" Margin="10,12,10,2" Height="24" /> + VerticalAlignment="Top" Height="18" Width="130" /> - + BorderThickness="1" SnapsToDevicePixels="True" ToolTip="Click to edit"> + \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericType.cs b/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericType.cs index f2c5a880c..77ccd3b69 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericType.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Windows; using System.Windows.Media; using Artemis.Models.Interfaces; @@ -15,7 +14,7 @@ namespace Artemis.Profiles.Layers.Types.Generic { public class GenericType : ILayerType { - public string Name { get; } = "Generic (Logitech)"; + public string Name => "Generic (Logitech)"; public bool ShowInEdtor { get; } = false; public DrawType DrawType { get; } = DrawType.Generic; @@ -32,24 +31,21 @@ namespace Artemis.Profiles.Layers.Types.Generic return image; } - public void Draw(LayerModel layer, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { // If an animation is present, let it handle the drawing - if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation)) + if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation)) { - layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, c); + layerModel.LayerAnimation.Draw(layerModel, c); return; } // Otherwise draw the rectangle with its applied dimensions and brush - var rect = new Rect(layer.AppliedProperties.X*4, - layer.AppliedProperties.Y*4, - layer.AppliedProperties.Width*4, - layer.AppliedProperties.Height*4); + var rect = layerModel.LayerRect(); // Can't meddle with the original brush because it's frozen. - var brush = layer.AppliedProperties.Brush.Clone(); - brush.Opacity = layer.AppliedProperties.Opacity; + var brush = layerModel.Brush.Clone(); + brush.Opacity = layerModel.Opacity; c.PushClip(new RectangleGeometry(rect)); c.DrawRectangle(brush, null, rect); @@ -65,15 +61,14 @@ namespace Artemis.Profiles.Layers.Types.Generic layerModel.Properties.Y = 0; layerModel.Properties.Contain = true; - layerModel.AppliedProperties = new SimplePropertiesModel(layerModel.Properties); + layerModel.ApplyProperties(false); if (isPreview || dataModel == null) return; // If not previewing, apply dynamic properties according to datamodel - var props = (SimplePropertiesModel) layerModel.AppliedProperties; - foreach (var dynamicProperty in props.DynamicProperties) - dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties); + foreach (var dynamicProperty in layerModel.Properties.DynamicProperties) + dynamicProperty.ApplyProperty(dataModel, layerModel); } public void SetupProperties(LayerModel layerModel) diff --git a/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetPropertiesView.xaml index a9f29d4e0..c6189cbb0 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetPropertiesView.xaml +++ b/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetPropertiesView.xaml @@ -48,7 +48,8 @@ VerticalAlignment="Top" Height="18" Width="130" /> - + diff --git a/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs b/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs index 4ac2c43b7..cbf75c0d4 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Windows; using System.Windows.Media; using Artemis.Models.Interfaces; @@ -15,7 +14,7 @@ namespace Artemis.Profiles.Layers.Types.Headset { public class HeadsetType : ILayerType { - public string Name { get; } = "Headset"; + public string Name => "Headset"; public bool ShowInEdtor { get; } = false; public DrawType DrawType { get; } = DrawType.Headset; @@ -30,24 +29,21 @@ namespace Artemis.Profiles.Layers.Types.Headset return image; } - public void Draw(LayerModel layer, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { // If an animation is present, let it handle the drawing - if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation)) + if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation)) { - layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, c); + layerModel.LayerAnimation.Draw(layerModel, c); return; } // Otherwise draw the rectangle with its applied dimensions and brush - var rect = new Rect(layer.AppliedProperties.X*4, - layer.AppliedProperties.Y*4, - layer.AppliedProperties.Width*4, - layer.AppliedProperties.Height*4); + var rect = layerModel.LayerRect(); // Can't meddle with the original brush because it's frozen. - var brush = layer.AppliedProperties.Brush.Clone(); - brush.Opacity = layer.AppliedProperties.Opacity; + var brush = layerModel.Brush.Clone(); + brush.Opacity = layerModel.Opacity; c.PushClip(new RectangleGeometry(rect)); c.DrawRectangle(brush, null, rect); @@ -63,15 +59,14 @@ namespace Artemis.Profiles.Layers.Types.Headset layerModel.Properties.Y = 0; layerModel.Properties.Contain = true; - layerModel.AppliedProperties = new SimplePropertiesModel(layerModel.Properties); + layerModel.ApplyProperties(true); if (isPreview || dataModel == null) return; // If not previewing, apply dynamic properties according to datamodel - var props = (SimplePropertiesModel) layerModel.AppliedProperties; - foreach (var dynamicProperty in props.DynamicProperties) - dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties); + foreach (var dynamicProperty in layerModel.Properties.DynamicProperties) + dynamicProperty.ApplyProperty(dataModel, layerModel); } public void SetupProperties(LayerModel layerModel) diff --git a/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressPropertiesView.xaml index 52df04289..0c484ef95 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressPropertiesView.xaml +++ b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressPropertiesView.xaml @@ -44,7 +44,7 @@ VerticalAlignment="Top" Height="18" Width="130" /> - diff --git a/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs index dfbf75ac8..0bed586e0 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs @@ -32,7 +32,7 @@ namespace Artemis.Profiles.Layers.Types.KeyPress public RadialGradientBrush TempBrush { get; set; } - public string Name { get; } = "Keyboard - Key press"; + public string Name => "Keyboard - Key press"; public bool ShowInEdtor { get; } = false; public DrawType DrawType { get; } = DrawType.Keyboard; @@ -49,7 +49,7 @@ namespace Artemis.Profiles.Layers.Types.KeyPress return image; } - public void Draw(LayerModel layer, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { lock (_keyPressLayers) { @@ -67,7 +67,7 @@ namespace Artemis.Profiles.Layers.Types.KeyPress layerModel.Properties.Y = 0; layerModel.Properties.Contain = true; - layerModel.AppliedProperties = new KeyPressPropertiesModel(layerModel.Properties); + layerModel.ApplyProperties(true); _layerModel = layerModel; diff --git a/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesView.xaml index 85ee67746..64b806c84 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesView.xaml +++ b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesView.xaml @@ -23,6 +23,7 @@ + - + @@ -86,8 +88,7 @@ + VerticalAlignment="Top" Height="Auto" TextWrapping="Wrap" > @@ -98,5 +99,7 @@ + + \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesViewModel.cs b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesViewModel.cs index 478b482b9..c84b3c3aa 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesViewModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesViewModel.cs @@ -20,6 +20,7 @@ namespace Artemis.Profiles.Layers.Types.Keyboard HeightProperties = new LayerDynamicPropertiesViewModel("Height", editorVm); WidthProperties = new LayerDynamicPropertiesViewModel("Width", editorVm); OpacityProperties = new LayerDynamicPropertiesViewModel("Opacity", editorVm); + LayerTweenViewModel = new LayerTweenViewModel(editorVm); SelectedLayerAnimation = LayerAnimations.FirstOrDefault(l => l.Name == editorVm.ProposedLayer.LayerAnimation?.Name) ?? @@ -33,6 +34,7 @@ namespace Artemis.Profiles.Layers.Types.Keyboard public LayerDynamicPropertiesViewModel HeightProperties { get; set; } public LayerDynamicPropertiesViewModel WidthProperties { get; set; } public LayerDynamicPropertiesViewModel OpacityProperties { get; set; } + public LayerTweenViewModel LayerTweenViewModel { get; set; } public bool IsGif { diff --git a/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardType.cs b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardType.cs index 4be6789ee..8fbc1ddf7 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardType.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Windows; +using System.Windows; using System.Windows.Media; using Artemis.Models.Interfaces; using Artemis.Profiles.Layers.Abstract; @@ -12,7 +11,7 @@ namespace Artemis.Profiles.Layers.Types.Keyboard { public class KeyboardType : ILayerType { - public string Name { get; } = "Keyboard"; + public string Name => "Keyboard"; public bool ShowInEdtor { get; } = true; public DrawType DrawType { get; } = DrawType.Keyboard; @@ -34,32 +33,26 @@ namespace Artemis.Profiles.Layers.Types.Keyboard return image; } - public void Draw(LayerModel layer, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { // If an animation is present, let it handle the drawing - if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation)) + if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation)) { - layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, c); + layerModel.LayerAnimation.Draw(layerModel, c); return; } // Otherwise draw the rectangle with its layer.AppliedProperties dimensions and brush - var rect = layer.AppliedProperties.Contain - ? new Rect(layer.AppliedProperties.X*4, - layer.AppliedProperties.Y*4, - layer.AppliedProperties.Width*4, - layer.AppliedProperties.Height*4) - : new Rect(layer.Properties.X*4, - layer.Properties.Y*4, - layer.Properties.Width*4, - layer.Properties.Height*4); + var rect = layerModel.Properties.Contain + ? layerModel.LayerRect() + : new Rect(layerModel.Properties.X*4, layerModel.Properties.Y*4, + layerModel.Properties.Width*4, layerModel.Properties.Height*4); - var clip = new Rect(layer.AppliedProperties.X*4, layer.AppliedProperties.Y*4, - layer.AppliedProperties.Width*4, layer.AppliedProperties.Height*4); + var clip = layerModel.LayerRect(); // Can't meddle with the original brush because it's frozen. - var brush = layer.AppliedProperties.Brush.Clone(); - brush.Opacity = layer.AppliedProperties.Opacity; + var brush = layerModel.Brush.Clone(); + brush.Opacity = layerModel.Opacity; c.PushClip(new RectangleGeometry(clip)); c.DrawRectangle(brush, null, rect); @@ -68,14 +61,13 @@ namespace Artemis.Profiles.Layers.Types.Keyboard public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) { - layerModel.AppliedProperties = new KeyboardPropertiesModel(layerModel.Properties); + layerModel.ApplyProperties(true); if (isPreview || dataModel == null) return; // If not previewing, apply dynamic properties according to datamodel - var keyboardProps = (KeyboardPropertiesModel) layerModel.AppliedProperties; - foreach (var dynamicProperty in keyboardProps.DynamicProperties) - dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties); + foreach (var dynamicProperty in layerModel.Properties.DynamicProperties) + dynamicProperty.ApplyProperty(dataModel, layerModel); } public void SetupProperties(LayerModel layerModel) diff --git a/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs b/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs index dc44e356c..dd524577b 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Drawing; +using System.Drawing; using System.IO; using System.Windows; using System.Windows.Media; @@ -16,7 +15,7 @@ namespace Artemis.Profiles.Layers.Types.KeyboardGif { internal class KeyboardGifType : ILayerType { - public string Name { get; } = "Keyboard - GIF"; + public string Name => "Keyboard - GIF"; public bool ShowInEdtor { get; } = true; public DrawType DrawType { get; } = DrawType.Keyboard; @@ -31,28 +30,25 @@ namespace Artemis.Profiles.Layers.Types.KeyboardGif return image; } - public void Draw(LayerModel layer, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { - var props = (KeyboardPropertiesModel) layer.Properties; + var props = (KeyboardPropertiesModel) layerModel.Properties; if (string.IsNullOrEmpty(props.GifFile)) return; if (!File.Exists(props.GifFile)) return; // Only reconstruct GifImage if the underlying source has changed - if (layer.GifImage == null) - layer.GifImage = new GifImage(props.GifFile); - if (layer.GifImage.Source != props.GifFile) - layer.GifImage = new GifImage(props.GifFile); + if (layerModel.GifImage == null) + layerModel.GifImage = new GifImage(props.GifFile); + if (layerModel.GifImage.Source != props.GifFile) + layerModel.GifImage = new GifImage(props.GifFile); - var rect = new Rect(layer.AppliedProperties.X*4, - layer.AppliedProperties.Y*4, - layer.AppliedProperties.Width*4, - layer.AppliedProperties.Height*4); + var rect = new Rect(layerModel.X*4, layerModel.Y*4, layerModel.Width*4, layerModel.Height*4); - lock (layer.GifImage) + lock (layerModel.GifImage) { - var draw = layer.GifImage.GetNextFrame(); + var draw = layerModel.GifImage.GetNextFrame(); using (var drawBitmap = new Bitmap(draw)) { c.DrawImage(ImageUtilities.BitmapToBitmapImage(drawBitmap), rect); @@ -62,14 +58,13 @@ namespace Artemis.Profiles.Layers.Types.KeyboardGif public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) { - layerModel.AppliedProperties = new KeyboardPropertiesModel(layerModel.Properties); + layerModel.ApplyProperties(true); if (isPreview) return; // If not previewing, apply dynamic properties according to datamodel - var keyboardProps = (KeyboardPropertiesModel) layerModel.AppliedProperties; - foreach (var dynamicProperty in keyboardProps.DynamicProperties) - dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties); + foreach (var dynamicProperty in layerModel.Properties.DynamicProperties) + dynamicProperty.ApplyProperty(dataModel, layerModel); } public void SetupProperties(LayerModel layerModel) diff --git a/Artemis/Artemis/Profiles/Layers/Types/Mouse/MousePropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/Mouse/MousePropertiesView.xaml index 55d238e0d..66aa011a1 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Mouse/MousePropertiesView.xaml +++ b/Artemis/Artemis/Profiles/Layers/Types/Mouse/MousePropertiesView.xaml @@ -48,7 +48,8 @@ VerticalAlignment="Top" Height="18" Width="130" /> - + diff --git a/Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs b/Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs index f6267e5e4..b8a58f535 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Windows; using System.Windows.Media; using Artemis.Models.Interfaces; @@ -15,7 +14,7 @@ namespace Artemis.Profiles.Layers.Types.Mouse { public class MouseType : ILayerType { - public string Name { get; } = "Mouse"; + public string Name => "Mouse"; public bool ShowInEdtor { get; } = false; public DrawType DrawType { get; } = DrawType.Mouse; @@ -32,24 +31,21 @@ namespace Artemis.Profiles.Layers.Types.Mouse return image; } - public void Draw(LayerModel layer, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { // If an animation is present, let it handle the drawing - if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation)) + if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation)) { - layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, c); + layerModel.LayerAnimation.Draw(layerModel, c); return; } // Otherwise draw the rectangle with its applied dimensions and brush - var rect = new Rect(layer.AppliedProperties.X*4, - layer.AppliedProperties.Y*4, - layer.AppliedProperties.Width*4, - layer.AppliedProperties.Height*4); + var rect = layerModel.LayerRect(); // Can't meddle with the original brush because it's frozen. - var brush = layer.AppliedProperties.Brush.Clone(); - brush.Opacity = layer.AppliedProperties.Opacity; + var brush = layerModel.Brush.Clone(); + brush.Opacity = layerModel.Opacity; c.PushClip(new RectangleGeometry(rect)); c.DrawRectangle(brush, null, rect); @@ -65,15 +61,14 @@ namespace Artemis.Profiles.Layers.Types.Mouse layerModel.Properties.Y = 0; layerModel.Properties.Contain = true; - layerModel.AppliedProperties = new SimplePropertiesModel(layerModel.Properties); + layerModel.ApplyProperties(true); if (isPreview || dataModel == null) return; // If not previewing, apply dynamic properties according to datamodel - var props = (SimplePropertiesModel) layerModel.AppliedProperties; - foreach (var dynamicProperty in props.DynamicProperties) - dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties); + foreach (var dynamicProperty in layerModel.Properties.DynamicProperties) + dynamicProperty.ApplyProperty(dataModel, layerModel); } public void SetupProperties(LayerModel layerModel) diff --git a/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematPropertiesView.xaml index 6af2267bc..13c490273 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematPropertiesView.xaml +++ b/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematPropertiesView.xaml @@ -48,7 +48,8 @@ VerticalAlignment="Top" Height="18" Width="130" /> - + diff --git a/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematType.cs b/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematType.cs index adba069f8..e9b24af82 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematType.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Windows; using System.Windows.Media; using Artemis.Models.Interfaces; @@ -15,7 +14,7 @@ namespace Artemis.Profiles.Layers.Types.Mousemat { public class MousematType : ILayerType { - public string Name { get; } = "Mousemat"; + public string Name => "Mousemat"; public bool ShowInEdtor { get; } = false; public DrawType DrawType { get; } = DrawType.Mousemat; @@ -30,24 +29,21 @@ namespace Artemis.Profiles.Layers.Types.Mousemat return image; } - public void Draw(LayerModel layer, DrawingContext c) + public void Draw(LayerModel layerModel, DrawingContext c) { // If an animation is present, let it handle the drawing - if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation)) + if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation)) { - layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, c); + layerModel.LayerAnimation.Draw(layerModel, c); return; } // Otherwise draw the rectangle with its applied dimensions and brush - var rect = new Rect(layer.AppliedProperties.X*4, - layer.AppliedProperties.Y*4, - layer.AppliedProperties.Width*4, - layer.AppliedProperties.Height*4); + var rect = layerModel.LayerRect(); // Can't meddle with the original brush because it's frozen. - var brush = layer.AppliedProperties.Brush.Clone(); - brush.Opacity = layer.AppliedProperties.Opacity; + var brush = layerModel.Brush.Clone(); + brush.Opacity = layerModel.Opacity; c.PushClip(new RectangleGeometry(rect)); c.DrawRectangle(brush, null, rect); @@ -63,15 +59,14 @@ namespace Artemis.Profiles.Layers.Types.Mousemat layerModel.Properties.Y = 0; layerModel.Properties.Contain = true; - layerModel.AppliedProperties = new SimplePropertiesModel(layerModel.Properties); + layerModel.ApplyProperties(true); if (isPreview || dataModel == null) return; // If not previewing, apply dynamic properties according to datamodel - var props = (SimplePropertiesModel) layerModel.AppliedProperties; - foreach (var dynamicProperty in props.DynamicProperties) - dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties); + foreach (var dynamicProperty in layerModel.Properties.DynamicProperties) + dynamicProperty.ApplyProperty(dataModel, layerModel); } public void SetupProperties(LayerModel layerModel) diff --git a/Artemis/Artemis/Profiles/Lua/LuaLayerWrapper.cs b/Artemis/Artemis/Profiles/Lua/LuaLayerWrapper.cs index 661bf928f..f9d9dffc5 100644 --- a/Artemis/Artemis/Profiles/Lua/LuaLayerWrapper.cs +++ b/Artemis/Artemis/Profiles/Lua/LuaLayerWrapper.cs @@ -19,8 +19,9 @@ namespace Artemis.Profiles.Lua public LuaLayerWrapper(LayerModel layerModel) { _layerModel = layerModel; + SavedProperties = new LuaLayerProperties(layerModel); - // Triger an update to fill up the AppliedProperties + // Triger an update to fill up the Properties _layerModel.Update(new ProfilePreviewDataModel(), true, false); } @@ -63,73 +64,120 @@ namespace Artemis.Profiles.Lua #endregion - #region Advanced layer properties + #region Render layer properties public double X { - get { return _layerModel.AppliedProperties.X; } - set { _layerModel.AppliedProperties.X = value; } + get { return _layerModel.X; } + set { _layerModel.X = value; } } public double Y { - get { return _layerModel.AppliedProperties.Y; } - set { _layerModel.AppliedProperties.Y = value; } + get { return _layerModel.Y; } + set { _layerModel.Y = value; } } public double Width { - get { return _layerModel.AppliedProperties.Width; } - set { _layerModel.AppliedProperties.Width = value; } + get { return _layerModel.Width; } + set { _layerModel.Width = value; } } public double Height { - get { return _layerModel.AppliedProperties.Height; } - set { _layerModel.AppliedProperties.Height = value; } - } - - public bool Contain - { - get { return _layerModel.AppliedProperties.Contain; } - set { _layerModel.AppliedProperties.Contain = value; } + get { return _layerModel.Height; } + set { _layerModel.Height = value; } } public double Opacity { - get { return _layerModel.AppliedProperties.Opacity; } - set { _layerModel.AppliedProperties.Opacity = value; } - } - - public double AnimationSpeed - { - get { return _layerModel.AppliedProperties.AnimationSpeed; } - set { _layerModel.AppliedProperties.AnimationSpeed = value; } + get { return _layerModel.Opacity; } + set { _layerModel.Opacity = value; } } public double AnimationProgress { - get { return _layerModel.AppliedProperties.AnimationProgress; } - set { _layerModel.AppliedProperties.AnimationProgress = value; } + get { return _layerModel.AnimationProgress; } + set { _layerModel.AnimationProgress = value; } } - public string BrushType => _layerModel.AppliedProperties.Brush?.GetType().Name; + #endregion + + #region Advanced layer properties + + public LuaLayerProperties SavedProperties { get; set; } + + public string BrushType => _layerModel.Properties.Brush?.GetType().Name; public LuaBrush Brush { get { - if (_layerModel.AppliedProperties.Brush is SolidColorBrush) - return new LuaSolidColorBrush(_layerModel.AppliedProperties.Brush); - if (_layerModel.AppliedProperties.Brush is LinearGradientBrush) - return new LuaLinearGradientBrush(_layerModel.AppliedProperties.Brush); - if (_layerModel.AppliedProperties.Brush is RadialGradientBrush) - return new LuaRadialGradientBrush(_layerModel.AppliedProperties.Brush); + if (_layerModel.Properties.Brush is SolidColorBrush) + return new LuaSolidColorBrush(_layerModel.Properties.Brush); + if (_layerModel.Properties.Brush is LinearGradientBrush) + return new LuaLinearGradientBrush(_layerModel.Properties.Brush); + if (_layerModel.Properties.Brush is RadialGradientBrush) + return new LuaRadialGradientBrush(_layerModel.Properties.Brush); return null; } - set { _layerModel.AppliedProperties.Brush = value?.Brush; } + set { _layerModel.Properties.Brush = value?.Brush; } } #endregion } + + [MoonSharpUserData] + public class LuaLayerProperties + { + private readonly LayerModel _layerModel; + + public LuaLayerProperties(LayerModel layerModel) + { + _layerModel = layerModel; + } + + public double X + { + get { return _layerModel.Properties.X; } + set { _layerModel.Properties.X = value; } + } + + public double Y + { + get { return _layerModel.Properties.Y; } + set { _layerModel.Properties.Y = value; } + } + + public double Width + { + get { return _layerModel.Properties.Width; } + set { _layerModel.Properties.Width = value; } + } + + public double Height + { + get { return _layerModel.Properties.Height; } + set { _layerModel.Properties.Height = value; } + } + + public bool Contain + { + get { return _layerModel.Properties.Contain; } + set { _layerModel.Properties.Contain = value; } + } + + public double Opacity + { + get { return _layerModel.Properties.Opacity; } + set { _layerModel.Properties.Opacity = value; } + } + + public double AnimationSpeed + { + get { return _layerModel.Properties.AnimationSpeed; } + set { _layerModel.Properties.AnimationSpeed = value; } + } + } } \ No newline at end of file diff --git a/Artemis/Artemis/Properties/AssemblyInfo.cs b/Artemis/Artemis/Properties/AssemblyInfo.cs index dfbd5b140..b8b3bc15f 100644 --- a/Artemis/Artemis/Properties/AssemblyInfo.cs +++ b/Artemis/Artemis/Properties/AssemblyInfo.cs @@ -53,8 +53,7 @@ using System.Windows; // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.5.0.2")] -[assembly: AssemblyFileVersion("1.5.0.2")] -[assembly: InternalsVisibleTo("Artemis.Tests")] +[assembly: AssemblyVersion("1.6.0.0")] +[assembly: AssemblyFileVersion("1.6.0.0")] [assembly: InternalsVisibleTo("Artemis.Explorables")] diff --git a/Artemis/Artemis/Properties/Resources.Designer.cs b/Artemis/Artemis/Properties/Resources.Designer.cs index 318b52e6b..467d52c81 100644 --- a/Artemis/Artemis/Properties/Resources.Designer.cs +++ b/Artemis/Artemis/Properties/Resources.Designer.cs @@ -338,6 +338,16 @@ namespace Artemis.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap masterkeys_pro_s { + get { + object obj = ResourceManager.GetObject("masterkeys_pro_s", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/Artemis/Artemis/Properties/Resources.resx b/Artemis/Artemis/Properties/Resources.resx index b2b934454..fe9b237c2 100644 --- a/Artemis/Artemis/Properties/Resources.resx +++ b/Artemis/Artemis/Properties/Resources.resx @@ -217,4 +217,7 @@ ..\Resources\Keyboards\masterkeys-pro-l.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Keyboards\masterkeys-pro-s.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/Artemis/Artemis/Resources/Keyboards/default-profiles.zip b/Artemis/Artemis/Resources/Keyboards/default-profiles.zip index 669be9f1b..c31d8020a 100644 Binary files a/Artemis/Artemis/Resources/Keyboards/default-profiles.zip and b/Artemis/Artemis/Resources/Keyboards/default-profiles.zip differ diff --git a/Artemis/Artemis/Resources/Keyboards/masterkeys-pro-s.png b/Artemis/Artemis/Resources/Keyboards/masterkeys-pro-s.png new file mode 100644 index 000000000..12ebf9a47 Binary files /dev/null and b/Artemis/Artemis/Resources/Keyboards/masterkeys-pro-s.png differ diff --git a/Artemis/Artemis/Services/MetroDialogService.cs b/Artemis/Artemis/Services/MetroDialogService.cs index 2591e7a0a..ea3ad5686 100644 --- a/Artemis/Artemis/Services/MetroDialogService.cs +++ b/Artemis/Artemis/Services/MetroDialogService.cs @@ -60,13 +60,15 @@ namespace Artemis.Services if (window == null) return; - var dialog = new MarkdownDialog(window) + window.Dispatcher.Invoke(() => { - Markdown = markdown, - Title = title - }; - - window.Dispatcher.Invoke(() => window.ShowMetroDialogAsync(dialog)); + var dialog = new MarkdownDialog(window) + { + Markdown = markdown, + Title = title + }; + return window.ShowMetroDialogAsync(dialog); + }); } public override async Task ShowQuestionMessageBox(string title, string message) diff --git a/Artemis/Artemis/Utilities/DataReaders/DllManager.cs b/Artemis/Artemis/Utilities/DataReaders/DllManager.cs index bc64062a4..e803449c6 100644 --- a/Artemis/Artemis/Utilities/DataReaders/DllManager.cs +++ b/Artemis/Artemis/Utilities/DataReaders/DllManager.cs @@ -33,7 +33,7 @@ namespace Artemis.Utilities.DataReaders public static bool RestoreLogitechDll() { - if (!File.Exists(LogitechPath + @"\LogitechLed.dll") || !File.Exists(LogitechPath + @"\artemis.txt")) + if (!DllPlaced()) return false; try diff --git a/Artemis/Artemis/Utilities/GameState/GameStateWebServer.cs b/Artemis/Artemis/Utilities/GameState/GameStateWebServer.cs index 85dd34ed5..f8b4e5bae 100644 --- a/Artemis/Artemis/Utilities/GameState/GameStateWebServer.cs +++ b/Artemis/Artemis/Utilities/GameState/GameStateWebServer.cs @@ -49,9 +49,9 @@ namespace Artemis.Utilities.GameState { _listener.Start(); } - catch (HttpListenerException e) + catch (Exception e) { - _logger.Error(e, "Couldn't start the webserver on port {0}.", Port); + _logger.Error(e, "Couldn't start the webserver on port {0}. Try selecting a different port", Port); Running = false; return; } diff --git a/Artemis/Artemis/Utilities/ImageUtilities.cs b/Artemis/Artemis/Utilities/ImageUtilities.cs index 2984b1a6c..3326e3253 100644 --- a/Artemis/Artemis/Utilities/ImageUtilities.cs +++ b/Artemis/Artemis/Utilities/ImageUtilities.cs @@ -1,12 +1,9 @@ using System.Drawing; using System.Drawing.Imaging; using System.IO; -using System.Runtime.InteropServices; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; -using PixelFormat = System.Drawing.Imaging.PixelFormat; -using Point = System.Drawing.Point; namespace Artemis.Utilities { diff --git a/Artemis/Artemis/ViewModels/Profiles/LayerTweenViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/LayerTweenViewModel.cs new file mode 100644 index 000000000..9d9379a63 --- /dev/null +++ b/Artemis/Artemis/ViewModels/Profiles/LayerTweenViewModel.cs @@ -0,0 +1,18 @@ +using Artemis.Profiles.Layers.Models; +using Caliburn.Micro; + +namespace Artemis.ViewModels.Profiles +{ + public class LayerTweenViewModel : Screen + { + public LayerModel LayerModel { get; set; } + + public LayerTweenViewModel(LayerEditorViewModel editorViewModel) + { + LayerModel = editorViewModel.ProposedLayer; + EaseFunctions = new BindableCollection {"Linear", "In", "Out", "In/out"}; + } + + public BindableCollection EaseFunctions { get; set; } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs index fe7fdc0c5..47605c4f7 100644 --- a/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs +++ b/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs @@ -97,7 +97,7 @@ namespace Artemis.ViewModels.Profiles // Draw the selection outline and resize indicator if (SelectedLayer != null && SelectedLayer.MustDraw()) { - var layerRect = SelectedLayer.Properties.GetRect(); + var layerRect = SelectedLayer.Properties.PropertiesRect(); // Deflate the rect so that the border is drawn on the inside layerRect.Inflate(-0.2, -0.2); @@ -227,7 +227,7 @@ namespace Artemis.ViewModels.Profiles var y = pos.Y/((double) keyboard.PreviewSettings.Height/keyboard.Height); var hoverLayer = GetLayers().Where(l => l.MustDraw()) - .FirstOrDefault(l => l.Properties.GetRect(1).Contains(x, y)); + .FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(x, y)); if (hoverLayer != null) SelectedLayer = hoverLayer; @@ -247,7 +247,7 @@ namespace Artemis.ViewModels.Profiles var x = pos.X/((double) keyboard.PreviewSettings.Width/keyboard.Width); var y = pos.Y/((double) keyboard.PreviewSettings.Height/keyboard.Height); var hoverLayer = GetLayers().Where(l => l.MustDraw()) - .FirstOrDefault(l => l.Properties.GetRect(1).Contains(x, y)); + .FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(x, y)); HandleDragging(e, x, y, hoverLayer); @@ -260,7 +260,7 @@ namespace Artemis.ViewModels.Profiles // Turn the mouse pointer into a hand if hovering over an active layer if (hoverLayer == SelectedLayer) { - var rect = hoverLayer.Properties.GetRect(1); + var rect = hoverLayer.Properties.PropertiesRect(1); KeyboardPreviewCursor = Math.Sqrt(Math.Pow(x - rect.BottomRight.X, 2) + Math.Pow(y - rect.BottomRight.Y, 2)) < 0.6 ? Cursors.SizeNWSE @@ -305,7 +305,7 @@ namespace Artemis.ViewModels.Profiles // Setup the dragging state on mouse press if (_draggingLayerOffset == null && hoverLayer != null && e.LeftButton == MouseButtonState.Pressed) { - var layerRect = hoverLayer.Properties.GetRect(1); + var layerRect = hoverLayer.Properties.PropertiesRect(1); _draggingLayerOffset = new Point(x - SelectedLayer.Properties.X, y - SelectedLayer.Properties.Y); _draggingLayer = hoverLayer; diff --git a/Artemis/Artemis/Views/Profiles/LayerEditorView.xaml b/Artemis/Artemis/Views/Profiles/LayerEditorView.xaml index c29ada817..da882c4d0 100644 --- a/Artemis/Artemis/Views/Profiles/LayerEditorView.xaml +++ b/Artemis/Artemis/Views/Profiles/LayerEditorView.xaml @@ -11,99 +11,100 @@ xmlns:cal="http://www.caliburnproject.org" GlowBrush="{DynamicResource AccentColorBrush}" Icon="../../Resources/bow.png" ResizeMode="NoResize"> - - - - - - - - - - - - - - - - - - - - - - + + - + + + + + + + -