diff --git a/Artemis/Artemis/App.config b/Artemis/Artemis/App.config
index 6ad4f906d..7f7bc23d9 100644
--- a/Artemis/Artemis/App.config
+++ b/Artemis/Artemis/App.config
@@ -52,38 +52,11 @@
True
-
-
-
-
- True
-
-
- True
-
-
- True
-
-
- True
-
-
- True
-
-
- #FFFF0000
-
-
- #FF0000FF
-
-
+
Default
-
- #FF00FF00
-
-
- #FF6A5ACD
+
+
@@ -145,33 +118,12 @@
True
-
-
-
-
- True
-
-
- #FFFF2900
-
-
- #FF26F600
-
-
- True
-
-
- True
-
-
- True
-
-
- True
-
Default
+
+
+
@@ -344,6 +296,10 @@
+
+
+
+
diff --git a/Artemis/Artemis/App.xaml b/Artemis/Artemis/App.xaml
index 7acc3be4c..e13bd017f 100644
--- a/Artemis/Artemis/App.xaml
+++ b/Artemis/Artemis/App.xaml
@@ -2,6 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:artemis="clr-namespace:Artemis"
+ xmlns:converters="clr-namespace:Artemis.Utilities.Converters"
DispatcherUnhandledException="Application_DispatcherUnhandledException"
ShutdownMode="OnExplicitShutdown">
@@ -21,6 +22,7 @@
+
\ No newline at end of file
diff --git a/Artemis/Artemis/App.xaml.cs b/Artemis/Artemis/App.xaml.cs
index 5ca4b1c47..008f21c59 100644
--- a/Artemis/Artemis/App.xaml.cs
+++ b/Artemis/Artemis/App.xaml.cs
@@ -2,6 +2,7 @@
using System.Security.Principal;
using System.Windows;
using System.Windows.Threading;
+using Artemis.Utilities;
using NLog;
using WpfExceptionViewer;
@@ -14,8 +15,8 @@ namespace Artemis
{
public App()
{
- //if (!IsRunAsAdministrator())
- // GeneralHelpers.RunAsAdministrator();
+ if (!IsRunAsAdministrator())
+ GeneralHelpers.RunAsAdministrator();
InitializeComponent();
}
diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj
index 83e85ee8a..909e2e886 100644
--- a/Artemis/Artemis/Artemis.csproj
+++ b/Artemis/Artemis/Artemis.csproj
@@ -38,8 +38,8 @@
https://github.com/SpoinkyNL/Artemis/wiki/Frequently-Asked-Questions-%28FAQ%29
Artemis
Artemis
- 2
- 1.1.3.2
+ 3
+ 1.1.3.3
false
true
true
@@ -276,9 +276,9 @@
+
-
@@ -301,15 +301,14 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
AudioVisualization.settings
True
@@ -420,6 +419,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
True
@@ -442,6 +461,8 @@
+
+
@@ -450,8 +471,6 @@
-
-
@@ -467,11 +486,11 @@
-
+
@@ -482,21 +501,25 @@
+
-
+
-
-
-
-
+
+
+
+
+
+ DebugView.xaml
+
EffectsView.xaml
@@ -524,13 +547,16 @@
Witcher3View.xaml
-
+
+ EventPropertiesView.xaml
+
+
FolderPropertiesView.xaml
-
+
HeadsetPropertiesView.xaml
-
+
KeyboardPropertiesView.xaml
@@ -542,7 +568,7 @@
LayerEditorView.xaml
-
+
MousePropertiesView.xaml
@@ -660,7 +686,9 @@
-
+
+ Designer
+
@@ -695,6 +723,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -731,15 +763,19 @@
Designer
MSBuild:Compile
-
+
Designer
MSBuild:Compile
-
+
Designer
MSBuild:Compile
-
+
+ Designer
+ MSBuild:Compile
+
+
Designer
MSBuild:Compile
@@ -755,7 +791,7 @@
MSBuild:Compile
Designer
-
+
Designer
MSBuild:Compile
@@ -802,7 +838,9 @@
false
-
+
+
+
diff --git a/Artemis/Artemis/ArtemisBootstrapper.cs b/Artemis/Artemis/ArtemisBootstrapper.cs
index f4137ab37..b4376a51d 100644
--- a/Artemis/Artemis/ArtemisBootstrapper.cs
+++ b/Artemis/Artemis/ArtemisBootstrapper.cs
@@ -5,9 +5,11 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using Artemis.InjectionModules;
+using Artemis.Settings;
using Artemis.Utilities;
using Artemis.ViewModels;
using Caliburn.Micro;
+using Newtonsoft.Json;
using Ninject;
using Application = System.Windows.Application;
using MessageBox = System.Windows.Forms.MessageBox;
@@ -22,7 +24,7 @@ namespace Artemis
public ArtemisBootstrapper()
{
// Start logging before anything else
- Logging.SetupLogging(Settings.General.Default.LogLevel);
+ Logging.SetupLogging(General.Default.LogLevel);
CheckDuplicateInstances();
Initialize();
@@ -77,6 +79,7 @@ namespace Artemis
protected override void Configure()
{
+ JsonConvert.DefaultSettings = () => new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.Auto};
_kernel = new StandardKernel(new BaseModules(), new ArtemisModules(), new ManagerModules());
_kernel.Bind().To().InSingletonScope();
_kernel.Bind().To().InSingletonScope();
@@ -114,7 +117,7 @@ namespace Artemis
private void CheckDuplicateInstances()
{
bool aIsNewInstance;
- Mutex = new Mutex(true, "ArtemisMutex", out aIsNewInstance);
+ Mutex = new Mutex(true, "ArtemisMutex2", out aIsNewInstance);
if (aIsNewInstance)
return;
diff --git a/Artemis/Artemis/DAL/ProfileProvider.cs b/Artemis/Artemis/DAL/ProfileProvider.cs
index 0c764b95e..3babec07f 100644
--- a/Artemis/Artemis/DAL/ProfileProvider.cs
+++ b/Artemis/Artemis/DAL/ProfileProvider.cs
@@ -4,13 +4,13 @@ using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
-using System.Xml.Serialization;
using Artemis.DeviceProviders;
using Artemis.Models;
-using Artemis.Models.Profiles;
-using Artemis.Models.Profiles.Properties;
+using Artemis.Profiles;
+using Artemis.Profiles.Layers.Types.Keyboard;
using Artemis.Properties;
using Artemis.Utilities;
+using Newtonsoft.Json;
using NLog;
namespace Artemis.DAL
@@ -65,14 +65,8 @@ namespace Artemis.DAL
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
- var serializer = new XmlSerializer(typeof(ProfileModel));
-
- // Could use a StreamWriter but should serializing fail this method doesn't ruin the existing XML file
- using (var xml = new StringWriter())
- {
- serializer.Serialize(xml, prof);
- File.WriteAllText(path + $@"\{prof.Name}.xml", xml.ToString());
- }
+ var json = JsonConvert.SerializeObject(prof, Formatting.Indented);
+ File.WriteAllText(path + $@"\{prof.Name}.json", json);
}
private static List ReadProfiles()
@@ -82,22 +76,18 @@ namespace Artemis.DAL
var profiles = new List();
// Create the directory structure
- var profilePaths = Directory.GetFiles(ProfileFolder, "*.xml", SearchOption.AllDirectories);
+ var profilePaths = Directory.GetFiles(ProfileFolder, "*.json", SearchOption.AllDirectories);
// Parse the JSON files into objects and add them if they are valid
- var deserializer = new XmlSerializer(typeof(ProfileModel));
foreach (var path in profilePaths)
{
try
{
- using (var file = new StreamReader(path))
- {
- var prof = (ProfileModel) deserializer.Deserialize(file);
- if (prof.GameName?.Length > 1 && prof.KeyboardSlug?.Length > 1 && prof.Name?.Length > 1)
- profiles.Add(prof);
- }
+ var prof = LoadProfileIfValid(path);
+ if (prof != null)
+ profiles.Add(prof);
}
- catch (InvalidOperationException e)
+ catch (Exception e)
{
Logger.Error("Failed to load profile: {0} - {1}", path, e.InnerException.Message);
}
@@ -144,7 +134,6 @@ namespace Artemis.DAL
((KeyboardPropertiesModel) gifLayer.Properties).GifFile = gifPath;
AddOrUpdate(demoProfile);
}
-
}
///
@@ -166,18 +155,17 @@ namespace Artemis.DAL
/// The loaded profile, or null if invalid
public static ProfileModel LoadProfileIfValid(string path)
{
+ // TODO: What exception on load failure?
try
{
- var deserializer = new XmlSerializer(typeof(ProfileModel));
- using (var file = new StreamReader(path))
- {
- var prof = (ProfileModel) deserializer.Deserialize(file);
- if (!(prof.GameName?.Length > 1) || !(prof.KeyboardSlug?.Length > 1) || !(prof.Name?.Length > 1))
- return null;
- return prof;
- }
+ var prof = JsonConvert.DeserializeObject(File.ReadAllText(path));
+ if (prof == null)
+ return null;
+ if (prof.GameName.Length < 1 || prof.KeyboardSlug.Length < 1 || prof.Name.Length < 1)
+ return null;
+ return prof;
}
- catch (InvalidOperationException)
+ catch (Exception)
{
return null;
}
@@ -186,15 +174,12 @@ namespace Artemis.DAL
///
/// Exports the given profile to the provided path in XML
///
- /// The profile to export
+ /// The profile to export
/// The path to save the profile to
- public static void ExportProfile(ProfileModel selectedProfile, string path)
+ public static void ExportProfile(ProfileModel prof, string path)
{
- var serializer = new XmlSerializer(typeof(ProfileModel));
- using (var file = new StreamWriter(path))
- {
- serializer.Serialize(file, selectedProfile);
- }
+ var json = JsonConvert.SerializeObject(prof);
+ File.WriteAllText(path, json);
}
///
@@ -208,7 +193,7 @@ namespace Artemis.DAL
return;
// Remove the old file
- var path = ProfileFolder + $@"\{profile.KeyboardSlug}\{profile.GameName}\{profile.Name}.xml";
+ var path = ProfileFolder + $@"\{profile.KeyboardSlug}\{profile.GameName}\{profile.Name}.json";
if (File.Exists(path))
File.Delete(path);
@@ -220,7 +205,7 @@ namespace Artemis.DAL
public static void DeleteProfile(ProfileModel profile)
{
// Remove the file
- var path = ProfileFolder + $@"\{profile.KeyboardSlug}\{profile.GameName}\{profile.Name}.xml";
+ var path = ProfileFolder + $@"\{profile.KeyboardSlug}\{profile.GameName}\{profile.Name}.json";
if (File.Exists(path))
File.Delete(path);
}
diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadsets.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadsets.cs
index fdedd3c49..db45cd5ab 100644
--- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadsets.cs
+++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadsets.cs
@@ -1,8 +1,7 @@
-using System.Linq;
+using System;
+using System.Drawing;
+using System.Linq;
using System.Threading;
-using System.Windows;
-using System.Windows.Media;
-using Artemis.Utilities;
using CUE.NET;
using CUE.NET.Devices.Generic.Enums;
using Ninject.Extensions.Logging;
@@ -35,33 +34,30 @@ namespace Artemis.DeviceProviders.Corsair
CueSDK.Reinitialize();
}
- public override void UpdateDevice(Brush brush)
+ public override void UpdateDevice(Bitmap bitmap)
{
- if (!CanUse || brush == null)
+ if (!CanUse || bitmap == null)
return;
+ if (bitmap.Width != bitmap.Height)
+ throw new ArgumentException("Bitmap must be a perfect square");
var leds = CueSDK.HeadsetSDK.Leds.Count();
- var rect = new Rect(new Size(leds*20, leds*20));
-
- var visual = new DrawingVisual();
- using (var c = visual.RenderOpen())
- c.DrawRectangle(brush, null, rect);
-
- using (var img = ImageUtilities.DrawinVisualToBitmap(visual, rect))
+ var step = (double) bitmap.Width/leds;
+ using (bitmap)
{
-
var ledIndex = 0;
// Color each LED according to one of the pixels
foreach (var corsairLed in CueSDK.HeadsetSDK.Leds)
{
- corsairLed.Color = ledIndex == 0
- ? img.GetPixel(0, 0)
- : img.GetPixel((ledIndex + 1)*20 - 1, (ledIndex + 1)*20 - 1);
+ if (ledIndex == 0)
+ corsairLed.Color = bitmap.GetPixel(0, 0);
+ else
+ corsairLed.Color = bitmap.GetPixel((int) ((ledIndex + 1)*step - 1),
+ (int) ((ledIndex + 1)*step - 1));
ledIndex++;
}
}
- // Flush is required for headset to work reliably on CUE2 for some reason
- CueSDK.HeadsetSDK.Update(true);
+ CueSDK.HeadsetSDK.Update();
}
private static bool CanInitializeSdk()
diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs
index 3e08f941c..4fc70ce84 100644
--- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs
+++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMice.cs
@@ -1,8 +1,7 @@
-using System.Linq;
+using System;
+using System.Drawing;
+using System.Linq;
using System.Threading;
-using System.Windows;
-using System.Windows.Media;
-using Artemis.Utilities;
using CUE.NET;
using CUE.NET.Devices.Generic.Enums;
using Ninject.Extensions.Logging;
@@ -35,27 +34,26 @@ namespace Artemis.DeviceProviders.Corsair
CueSDK.Reinitialize();
}
- public override void UpdateDevice(Brush brush)
+ public override void UpdateDevice(Bitmap bitmap)
{
- if (!CanUse || brush == null)
+ if (!CanUse || bitmap == null)
return;
+ if (bitmap.Width != bitmap.Height)
+ throw new ArgumentException("Bitmap must be a perfect square");
var leds = CueSDK.MouseSDK.Leds.Count();
- var rect = new Rect(new Size(leds*20, leds*20));
-
- var visual = new DrawingVisual();
- using (var c = visual.RenderOpen())
- c.DrawRectangle(brush, null, rect);
-
- using (var img = ImageUtilities.DrawinVisualToBitmap(visual, rect))
+ var step = (double) bitmap.Width/leds;
+ using (bitmap)
{
var ledIndex = 0;
// Color each LED according to one of the pixels
foreach (var corsairLed in CueSDK.MouseSDK.Leds)
{
- corsairLed.Color = ledIndex == 0
- ? img.GetPixel(0, 0)
- : img.GetPixel((ledIndex + 1)*20 - 1, (ledIndex + 1)*20 - 1);
+ if (ledIndex == 0)
+ corsairLed.Color = bitmap.GetPixel(0, 0);
+ else
+ corsairLed.Color = bitmap.GetPixel((int) ((ledIndex + 1)*step - 1),
+ (int) ((ledIndex + 1)*step - 1));
ledIndex++;
}
}
diff --git a/Artemis/Artemis/DeviceProviders/DeviceProvider.cs b/Artemis/Artemis/DeviceProviders/DeviceProvider.cs
index c244eb73a..f68bc3dbf 100644
--- a/Artemis/Artemis/DeviceProviders/DeviceProvider.cs
+++ b/Artemis/Artemis/DeviceProviders/DeviceProvider.cs
@@ -1,5 +1,5 @@
-using System.Threading.Tasks;
-using System.Windows.Media;
+using System.Drawing;
+using System.Threading.Tasks;
namespace Artemis.DeviceProviders
{
@@ -16,10 +16,10 @@ namespace Artemis.DeviceProviders
public bool CanUse { get; set; }
///
- /// Updates a non-keyboard to take the colours of the provided brush
+ /// Updates a non-keyboard to take the colours found in the provided bitmap
///
- ///
- public abstract void UpdateDevice(Brush brush);
+ ///
+ public abstract void UpdateDevice(Bitmap bitmap);
///
/// Tries to enable the device and updates CanUse accordingly
@@ -32,7 +32,7 @@ namespace Artemis.DeviceProviders
public abstract void Disable();
///
- /// Tries to enable the device and updates CanUse accordingly asynchronously
+ /// Tries to enable the device and updates CanUse accordingly asynchronously
///
///
public Task TryEnableAsync()
diff --git a/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs b/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs
index ab0984904..887f4be74 100644
--- a/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs
+++ b/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs
@@ -4,7 +4,6 @@ using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using MahApps.Metro.Controls.Dialogs;
-using Brush = System.Windows.Media.Brush;
using Size = System.Windows.Size;
namespace Artemis.DeviceProviders
@@ -87,7 +86,7 @@ namespace Artemis.DeviceProviders
return Task.Run(() => Enable());
}
- public override void UpdateDevice(Brush brush)
+ public override void UpdateDevice(Bitmap bitmap)
{
throw new NotImplementedException("KeyboardProvider doesn't implement UpdateDevice, use DrawBitmap instead.");
}
diff --git a/Artemis/Artemis/Events/ChangeBitmap.cs b/Artemis/Artemis/Events/ChangeBitmap.cs
deleted file mode 100644
index 4f72e82b8..000000000
--- a/Artemis/Artemis/Events/ChangeBitmap.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System.Drawing;
-
-namespace Artemis.Events
-{
- public class ChangeBitmap
- {
- public ChangeBitmap(Bitmap bitmap)
- {
- Bitmap = bitmap;
- }
-
- public Bitmap Bitmap { get; private set; }
-
- public void ChangeTextMessage(Bitmap bitmap)
- {
- Bitmap = bitmap;
- }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/Events/RazerColorArrayChanged.cs b/Artemis/Artemis/Events/RazerColorArrayChanged.cs
new file mode 100644
index 000000000..23d1ae192
--- /dev/null
+++ b/Artemis/Artemis/Events/RazerColorArrayChanged.cs
@@ -0,0 +1,14 @@
+using System.Windows.Media;
+
+namespace Artemis.Events
+{
+ public class RazerColorArrayChanged
+ {
+ public RazerColorArrayChanged(Color[,] colors)
+ {
+ Colors = colors;
+ }
+
+ public Color[,] Colors { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/InjectionFactories/ILayerEditorVmFactory.cs b/Artemis/Artemis/InjectionFactories/ILayerEditorVmFactory.cs
index a33a3416b..0f3e0609f 100644
--- a/Artemis/Artemis/InjectionFactories/ILayerEditorVmFactory.cs
+++ b/Artemis/Artemis/InjectionFactories/ILayerEditorVmFactory.cs
@@ -1,5 +1,5 @@
using Artemis.Models.Interfaces;
-using Artemis.Models.Profiles;
+using Artemis.Profiles.Layers.Models;
using Artemis.ViewModels.Profiles;
namespace Artemis.InjectionFactories
diff --git a/Artemis/Artemis/InjectionModules/ArtemisModules.cs b/Artemis/Artemis/InjectionModules/ArtemisModules.cs
index 2ec4602f1..4aa41678d 100644
--- a/Artemis/Artemis/InjectionModules/ArtemisModules.cs
+++ b/Artemis/Artemis/InjectionModules/ArtemisModules.cs
@@ -13,6 +13,14 @@ using Artemis.Modules.Games.RocketLeague;
using Artemis.Modules.Games.TheDivision;
using Artemis.Modules.Games.Witcher3;
using Artemis.Modules.Overlays.VolumeDisplay;
+using Artemis.Profiles.Layers.Animations;
+using Artemis.Profiles.Layers.Conditions;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Types.Folder;
+using Artemis.Profiles.Layers.Types.Headset;
+using Artemis.Profiles.Layers.Types.Keyboard;
+using Artemis.Profiles.Layers.Types.KeyboardGif;
+using Artemis.Profiles.Layers.Types.Mouse;
using Artemis.ViewModels.Abstract;
using Ninject.Modules;
@@ -55,6 +63,28 @@ namespace Artemis.InjectionModules
Bind().To().InSingletonScope();
#endregion
+
+ #region Layers
+
+ // Animations
+ Bind().To();
+ Bind().To();
+ Bind().To();
+ Bind().To();
+ Bind().To();
+ Bind().To();
+ Bind().To();
+ // Conditions
+ Bind().To();
+ Bind().To();
+ // Types
+ Bind().To();
+ Bind().To();
+ Bind().To();
+ Bind().To();
+ Bind().To();
+
+ #endregion
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/InjectionModules/BaseModules.cs b/Artemis/Artemis/InjectionModules/BaseModules.cs
index 05805579a..0c5a73936 100644
--- a/Artemis/Artemis/InjectionModules/BaseModules.cs
+++ b/Artemis/Artemis/InjectionModules/BaseModules.cs
@@ -19,6 +19,7 @@ namespace Artemis.InjectionModules
Bind().ToFactory();
Bind().ToFactory();
Bind().ToSelf();
+ Bind().ToSelf().InSingletonScope();
Bind().To().InSingletonScope();
Bind().To().InSingletonScope();
diff --git a/Artemis/Artemis/Managers/LoopManager.cs b/Artemis/Artemis/Managers/LoopManager.cs
index 73aa62ab3..32abd3fba 100644
--- a/Artemis/Artemis/Managers/LoopManager.cs
+++ b/Artemis/Artemis/Managers/LoopManager.cs
@@ -6,7 +6,6 @@ using System.Timers;
using Artemis.Events;
using Caliburn.Micro;
using Ninject.Extensions.Logging;
-using Brush = System.Windows.Media.Brush;
namespace Artemis.Managers
{
@@ -21,7 +20,8 @@ namespace Artemis.Managers
private readonly Timer _loopTimer;
private Bitmap _keyboardBitmap;
- public LoopManager(IEventAggregator events, ILogger logger, EffectManager effectManager, DeviceManager deviceManager)
+ public LoopManager(IEventAggregator events, ILogger logger, EffectManager effectManager,
+ DeviceManager deviceManager)
{
events.Subscribe(this);
_logger = logger;
@@ -48,6 +48,18 @@ namespace Artemis.Managers
_keyboardBitmap?.Dispose();
}
+ public void Handle(ActiveEffectChanged message)
+ {
+ if (_deviceManager.ActiveKeyboard != null && _effectManager.ActiveEffect != null)
+ _keyboardBitmap = _deviceManager.ActiveKeyboard.KeyboardBitmap(_effectManager.ActiveEffect.KeyboardScale);
+ }
+
+ public void Handle(ActiveKeyboardChanged message)
+ {
+ if (_deviceManager.ActiveKeyboard != null && _effectManager.ActiveEffect != null)
+ _keyboardBitmap = _deviceManager.ActiveKeyboard.KeyboardBitmap(_effectManager.ActiveEffect.KeyboardScale);
+ }
+
public Task StartAsync()
{
return Task.Run(() => Start());
@@ -132,50 +144,31 @@ namespace Artemis.Managers
renderEffect.Update();
// Get ActiveEffect's bitmap
- Brush mouseBrush = null;
- Brush headsetBrush = null;
+ Bitmap mouseBitmap = null;
+ Bitmap headsetBitmap = null;
var mice = _deviceManager.MiceProviders.Where(m => m.CanUse).ToList();
var headsets = _deviceManager.HeadsetProviders.Where(m => m.CanUse).ToList();
- using (Graphics keyboardGraphics = Graphics.FromImage(_keyboardBitmap))
+ if (renderEffect.Initialized)
+ renderEffect.Render(_keyboardBitmap, out mouseBitmap, out headsetBitmap, mice.Any(), headsets.Any());
+
+ // Draw enabled overlays on top of the renderEffect
+ foreach (var overlayModel in _effectManager.EnabledOverlays)
{
- // Fill the bitmap's background with black to avoid trailing colors on some keyboards
- keyboardGraphics.Clear(Color.Black);
-
- if (renderEffect.Initialized)
- renderEffect.Render(keyboardGraphics, out mouseBrush, out headsetBrush, mice.Any(),
- headsets.Any());
-
- // Draw enabled overlays on top of the renderEffect
- foreach (var overlayModel in _effectManager.EnabledOverlays)
- {
- overlayModel.Update();
- overlayModel.RenderOverlay(keyboardGraphics, ref mouseBrush, ref headsetBrush, mice.Any(),
- headsets.Any());
- }
-
- // Update mice and headsets
- foreach (var mouse in mice)
- mouse.UpdateDevice(mouseBrush);
- foreach (var headset in headsets)
- headset.UpdateDevice(headsetBrush);
+ overlayModel.Update();
+ overlayModel.RenderOverlay(_keyboardBitmap, ref mouseBitmap, ref headsetBitmap, mice.Any(),
+ headsets.Any());
}
+ // Update mice and headsets
+ foreach (var mouse in mice)
+ mouse.UpdateDevice(mouseBitmap);
+ foreach (var headset in headsets)
+ headset.UpdateDevice(headsetBitmap);
+
// Update the keyboard
_deviceManager.ActiveKeyboard?.DrawBitmap(_keyboardBitmap);
}
}
-
- public void Handle(ActiveKeyboardChanged message)
- {
- if (_deviceManager.ActiveKeyboard != null &&_effectManager.ActiveEffect != null)
- _keyboardBitmap = _deviceManager.ActiveKeyboard.KeyboardBitmap(_effectManager.ActiveEffect.KeyboardScale);
- }
-
- public void Handle(ActiveEffectChanged message)
- {
- if (_deviceManager.ActiveKeyboard != null && _effectManager.ActiveEffect != null)
- _keyboardBitmap = _deviceManager.ActiveKeyboard.KeyboardBitmap(_effectManager.ActiveEffect.KeyboardScale);
- }
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Models/EffectModel.cs b/Artemis/Artemis/Models/EffectModel.cs
index 962d4cf90..67423ef6d 100644
--- a/Artemis/Artemis/Models/EffectModel.cs
+++ b/Artemis/Artemis/Models/EffectModel.cs
@@ -2,12 +2,14 @@
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
+using System.Windows;
using Artemis.Managers;
using Artemis.Models.Interfaces;
-using Artemis.Models.Profiles;
+using Artemis.Profiles;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Profiles.Layers.Types.Headset;
+using Artemis.Profiles.Layers.Types.Mouse;
using Newtonsoft.Json;
-using NLog;
-using Brush = System.Windows.Media.Brush;
namespace Artemis.Models
{
@@ -15,12 +17,7 @@ namespace Artemis.Models
{
public delegate void SettingsUpdateHandler(EffectSettings settings);
- public bool Initialized { get; set; }
- public MainManager MainManager { get; set; }
- public string Name { get; set; }
- public int KeyboardScale { get; set; } = 4;
-
- private DateTime _lastTrace;
+ protected DateTime LastTrace;
protected EffectModel(MainManager mainManager, IDataModel dataModel)
{
@@ -28,6 +25,11 @@ namespace Artemis.Models
DataModel = dataModel;
}
+ public bool Initialized { get; set; }
+ public MainManager MainManager { get; set; }
+ public string Name { get; set; }
+ public int KeyboardScale { get; set; } = 4;
+
// Used by profile system
public IDataModel DataModel { get; set; }
public ProfileModel Profile { get; set; }
@@ -41,7 +43,8 @@ namespace Artemis.Models
public abstract void Update();
// Called after every update
- public virtual void Render(Graphics keyboard, out Brush mouse, out Brush headset, bool renderMice, bool renderHeadsets)
+ public virtual void Render(Bitmap keyboard, out Bitmap mouse, out Bitmap headset, bool renderMice,
+ bool renderHeadsets)
{
mouse = null;
headset = null;
@@ -52,24 +55,41 @@ namespace Artemis.Models
// Get all enabled layers who's conditions are met
var renderLayers = GetRenderLayers(renderMice, renderHeadsets);
- // Trace debugging
- if (DateTime.Now.AddSeconds(-2) > _lastTrace)
+ // Render the keyboard layer-by-layer
+ var keyboardRect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
+ using (var g = Graphics.FromImage(keyboard))
{
- _lastTrace = DateTime.Now;
- MainManager.Logger.Trace("Effect datamodel as JSON: \r\n{0}",
- JsonConvert.SerializeObject(DataModel, Formatting.Indented));
- MainManager.Logger.Trace("Effect {0} has to render {1} layers", Name, renderLayers.Count);
- foreach (var renderLayer in renderLayers)
- MainManager.Logger.Trace(" Layer name: {0}, layer type: {1}", renderLayer.Name,
- renderLayer.LayerType);
+ // Fill the bitmap's background with black to avoid trailing colors on some keyboards
+ g.Clear(Color.Black);
+ Profile.DrawLayers(g, renderLayers.Where(rl => rl.MustDraw()), DataModel, keyboardRect, false, true);
}
- // Render the keyboard layer-by-layer
- Profile.DrawProfile(keyboard, renderLayers, DataModel, MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale), false, true);
- // Render the first enabled mouse (will default to null if renderMice was false)
- mouse = Profile.GenerateBrush(renderLayers.LastOrDefault(l => l.LayerType == LayerType.Mouse), DataModel);
- // Render the first enabled headset (will default to null if renderHeadsets was false)
- headset = Profile.GenerateBrush(renderLayers.LastOrDefault(l => l.LayerType == LayerType.Headset), DataModel);
+ // Render the mouse layer-by-layer
+ var smallRect = new Rect(0, 0, 40, 40);
+ mouse = new Bitmap(40, 40);
+ using (var g = Graphics.FromImage(mouse))
+ {
+ Profile.DrawLayers(g, renderLayers.Where(rl => rl.LayerType is MouseType), DataModel, smallRect,
+ false, true);
+ }
+
+ // Render the headset layer-by-layer
+ headset = new Bitmap(40, 40);
+ using (var g = Graphics.FromImage(headset))
+ {
+ Profile.DrawLayers(g, renderLayers.Where(rl => rl.LayerType is HeadsetType), DataModel, smallRect,
+ false, true);
+ }
+
+ // Trace debugging
+ if (DateTime.Now.AddSeconds(-2) <= LastTrace)
+ return;
+ LastTrace = DateTime.Now;
+ MainManager.Logger.Trace("Effect datamodel as JSON: \r\n{0}",
+ JsonConvert.SerializeObject(DataModel, Formatting.Indented));
+ MainManager.Logger.Trace("Effect {0} has to render {1} layers", Name, renderLayers.Count);
+ foreach (var renderLayer in renderLayers)
+ MainManager.Logger.Trace("- Layer name: {0}, layer type: {1}", renderLayer.Name, renderLayer.LayerType);
}
public abstract List GetRenderLayers(bool renderMice, bool renderHeadsets);
diff --git a/Artemis/Artemis/Models/OverlayModel.cs b/Artemis/Artemis/Models/OverlayModel.cs
index 5dac1f475..8d4ac2335 100644
--- a/Artemis/Artemis/Models/OverlayModel.cs
+++ b/Artemis/Artemis/Models/OverlayModel.cs
@@ -1,6 +1,5 @@
using System.Drawing;
using Artemis.Managers;
-using Brush = System.Windows.Media.Brush;
namespace Artemis.Models
{
@@ -29,7 +28,7 @@ namespace Artemis.Models
}
}
- public abstract void RenderOverlay(Graphics keyboard, ref Brush mouse, ref Brush headset, bool renderMice,
+ public abstract void RenderOverlay(Bitmap keyboard, ref Bitmap mouse, ref Bitmap headset, bool renderMice,
bool renderHeadsets);
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Models/Profiles/Properties/FolderPropertiesModel.cs b/Artemis/Artemis/Models/Profiles/Properties/FolderPropertiesModel.cs
deleted file mode 100644
index dc36491c4..000000000
--- a/Artemis/Artemis/Models/Profiles/Properties/FolderPropertiesModel.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using Artemis.Models.Interfaces;
-
-namespace Artemis.Models.Profiles.Properties
-{
- public class FolderPropertiesModel : LayerPropertiesModel
- {
- public override AppliedProperties GetAppliedProperties(IDataModel dataModel, bool ignoreDynamic = false)
- {
- return new AppliedProperties();
- }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/Models/Profiles/Properties/HeadsetPropertiesModel.cs b/Artemis/Artemis/Models/Profiles/Properties/HeadsetPropertiesModel.cs
deleted file mode 100644
index c44226e99..000000000
--- a/Artemis/Artemis/Models/Profiles/Properties/HeadsetPropertiesModel.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using Artemis.Models.Interfaces;
-
-namespace Artemis.Models.Profiles.Properties
-{
- public class HeadsetPropertiesModel : LayerPropertiesModel
- {
- public override AppliedProperties GetAppliedProperties(IDataModel dataModel, bool ignoreDynamic = false)
- {
- return new AppliedProperties {Brush = Brush};
- }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/Models/Profiles/Properties/KeyboardPropertiesModel.cs b/Artemis/Artemis/Models/Profiles/Properties/KeyboardPropertiesModel.cs
deleted file mode 100644
index 197fdccae..000000000
--- a/Artemis/Artemis/Models/Profiles/Properties/KeyboardPropertiesModel.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Windows;
-using System.Xml.Serialization;
-using Artemis.Models.Interfaces;
-
-namespace Artemis.Models.Profiles.Properties
-{
- public class KeyboardPropertiesModel : LayerPropertiesModel
- {
- public KeyboardPropertiesModel()
- {
- DynamicProperties = new List();
- }
-
- public double X { get; set; }
- public double Y { get; set; }
- public double Width { get; set; }
- public double Height { get; set; }
- public double Opacity { get; set; }
- public bool Contain { get; set; }
- public LayerAnimation Animation { get; set; }
- public double AnimationSpeed { get; set; }
- public string GifFile { get; set; }
- public List DynamicProperties { get; set; }
-
- [XmlIgnore]
- public double AnimationProgress { get; set; }
-
- public Rect GetRect(int scale = 4)
- {
- return new Rect(X*scale, Y*scale, Width*scale, Height*scale);
- }
-
- public override AppliedProperties GetAppliedProperties(IDataModel dataModel, bool ignoreDynamic = false)
- {
- var applied = new AppliedProperties
- {
- X = X,
- Y = Y,
- Width = Width,
- Height = Height,
- Opacity = Opacity,
- Brush = Brush.CloneCurrentValue()
- };
-
- if (ignoreDynamic)
- return applied;
-
- foreach (var dynamicProperty in DynamicProperties)
- dynamicProperty.ApplyProperty(dataModel, ref applied);
-
- if (Math.Abs(applied.Opacity - 1) > 0.001)
- {
- applied.Brush = Brush.CloneCurrentValue();
- applied.Brush.Opacity = applied.Opacity;
- }
-
- return applied;
- }
- }
-
- public enum LayerAnimation
- {
- [Description("None")] None,
- [Description("Slide left")] SlideLeft,
- [Description("Slide right")] SlideRight,
- [Description("Slide up")] SlideUp,
- [Description("Slide down")] SlideDown,
- [Description("Grow")] Grow,
- [Description("Pulse")] Pulse
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/Models/Profiles/Properties/LayerPropertiesModel.cs b/Artemis/Artemis/Models/Profiles/Properties/LayerPropertiesModel.cs
deleted file mode 100644
index 0cd18e38c..000000000
--- a/Artemis/Artemis/Models/Profiles/Properties/LayerPropertiesModel.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using System.Collections.Generic;
-using System.Windows.Media;
-using System.Xml.Serialization;
-using Artemis.Models.Interfaces;
-
-namespace Artemis.Models.Profiles.Properties
-{
- [XmlInclude(typeof(SolidColorBrush))]
- [XmlInclude(typeof(LinearGradientBrush))]
- [XmlInclude(typeof(RadialGradientBrush))]
- [XmlInclude(typeof(MatrixTransform))]
- [XmlInclude(typeof(KeyboardPropertiesModel))]
- [XmlInclude(typeof(MousePropertiesModel))]
- [XmlInclude(typeof(HeadsetPropertiesModel))]
- [XmlInclude(typeof(FolderPropertiesModel))]
- public abstract class LayerPropertiesModel
- {
- private Brush _brush;
-
- protected LayerPropertiesModel()
- {
- Conditions = new List();
- }
-
- public List Conditions { get; set; }
-
- 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;
- }
- }
-
- public abstract AppliedProperties GetAppliedProperties(IDataModel dataModel, bool ignoreDynamic = false);
- }
-
- public struct AppliedProperties
- {
- public double X { get; set; }
- public double Y { get; set; }
- public double Width { get; set; }
- public double Height { get; set; }
- public double Opacity { get; set; }
- public Brush Brush { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/Models/Profiles/Properties/MousePropertiesModel.cs b/Artemis/Artemis/Models/Profiles/Properties/MousePropertiesModel.cs
deleted file mode 100644
index 2bebe3c5b..000000000
--- a/Artemis/Artemis/Models/Profiles/Properties/MousePropertiesModel.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using Artemis.Models.Interfaces;
-
-namespace Artemis.Models.Profiles.Properties
-{
- public class MousePropertiesModel : LayerPropertiesModel
- {
- public override AppliedProperties GetAppliedProperties(IDataModel dataModel, bool ignoreDynamic = false)
- {
- return new AppliedProperties {Brush = Brush};
- }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualization.cs b/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualization.cs
new file mode 100644
index 000000000..a3db59c01
--- /dev/null
+++ b/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualization.cs
@@ -0,0 +1,28 @@
+namespace Artemis.Modules.Effects.AudioVisualizer {
+
+
+ // This class allows you to handle specific events on the settings class:
+ // The SettingChanging event is raised before a setting's value is changed.
+ // The PropertyChanged event is raised after a setting's value is changed.
+ // The SettingsLoaded event is raised after the setting values are loaded.
+ // The SettingsSaving event is raised before the setting values are saved.
+ internal sealed partial class AudioVisualization {
+
+ public AudioVisualization() {
+ // // To add event handlers for saving and changing settings, uncomment the lines below:
+ //
+ // this.SettingChanging += this.SettingChangingEventHandler;
+ //
+ // this.SettingsSaving += this.SettingsSavingEventHandler;
+ //
+ }
+
+ private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
+ // Add code to handle the SettingChangingEvent event here.
+ }
+
+ private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
+ // Add code to handle the SettingsSaving event here.
+ }
+ }
+}
diff --git a/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualizerModel.cs b/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualizerModel.cs
index dc215cfe4..aa103501f 100644
--- a/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualizerModel.cs
+++ b/Artemis/Artemis/Modules/Effects/AudioVisualizer/AudioVisualizerModel.cs
@@ -5,13 +5,12 @@ using System.Drawing.Drawing2D;
using System.Linq;
using Artemis.Managers;
using Artemis.Models;
-using Artemis.Models.Profiles;
using Artemis.Modules.Effects.AudioVisualizer.Utilities;
+using Artemis.Profiles.Layers.Models;
using Artemis.Utilities;
using Artemis.Utilities.Keyboard;
using NAudio.CoreAudioApi;
using NAudio.Wave;
-using Brush = System.Windows.Media.Brush;
namespace Artemis.Modules.Effects.AudioVisualizer
{
@@ -78,7 +77,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer
ColorHelpers.ToDrawingColor(Settings.BottomColor)
},
LinearGradientMode.Vertical)
- { ContainedBrush = false, Height = 0 });
+ {ContainedBrush = false, Height = 0});
}
_sensitivity = Settings.Sensitivity;
_fromBottom = Settings.FromBottom;
@@ -118,22 +117,22 @@ namespace Artemis.Modules.Effects.AudioVisualizer
if (SpectrumData.Count - 1 < i || SpectrumData[i] == 0)
height = 0;
else
- height = (int)Math.Round(SpectrumData[i] / 2.55);
+ height = (int) Math.Round(SpectrumData[i]/2.55);
// Apply Sensitivity setting
- height = height * _sensitivity;
+ height = height*_sensitivity;
var keyboardHeight =
- (int)Math.Round(MainManager.DeviceManager.ActiveKeyboard.Height / 100.00 * height * KeyboardScale);
+ (int) Math.Round(MainManager.DeviceManager.ActiveKeyboard.Height/100.00*height*KeyboardScale);
if (keyboardHeight > SoundRectangles[i].Height)
SoundRectangles[i].Height = keyboardHeight;
else
SoundRectangles[i].Height = SoundRectangles[i].Height - Settings.FadeSpeed;
// Apply Bars setting
- SoundRectangles[i].X = i * KeyboardScale;
+ SoundRectangles[i].X = i*KeyboardScale;
SoundRectangles[i].Width = KeyboardScale;
if (_fromBottom)
- SoundRectangles[i].Y = MainManager.DeviceManager.ActiveKeyboard.Height * KeyboardScale -
+ SoundRectangles[i].Y = MainManager.DeviceManager.ActiveKeyboard.Height*KeyboardScale -
SoundRectangles[i].Height;
}
_generating = false;
@@ -164,7 +163,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer
for (x = 0; x < Lines; x++)
{
float peak = 0;
- var b1 = (int)Math.Pow(2, x * 10.0 / (Lines - 1));
+ var b1 = (int) Math.Pow(2, x*10.0/(Lines - 1));
if (b1 > 2047)
b1 = 2047;
if (b1 <= b0)
@@ -174,12 +173,12 @@ namespace Artemis.Modules.Effects.AudioVisualizer
if (peak < e.Result[1 + b0].X)
peak = e.Result[1 + b0].X;
}
- var y = (int)(Math.Sqrt(peak) * 3 * 255 - 4);
+ var y = (int) (Math.Sqrt(peak)*3*255 - 4);
if (y > 255)
y = 255;
if (y < 0)
y = 0;
- SpectrumData.Add((byte)y);
+ SpectrumData.Add((byte) y);
}
}
@@ -188,7 +187,7 @@ namespace Artemis.Modules.Effects.AudioVisualizer
return null;
}
- public override void Render(Graphics keyboard, out Brush mouse, out Brush headset, bool renderMice,
+ public override void Render(Bitmap keyboard, out Bitmap mouse, out Bitmap headset, bool renderMice,
bool renderHeadsets)
{
mouse = null;
@@ -200,8 +199,11 @@ namespace Artemis.Modules.Effects.AudioVisualizer
// Lock the _spectrumData array while busy with it
_generating = true;
- foreach (var soundRectangle in SoundRectangles)
- soundRectangle.Draw(keyboard);
+ using (var g = Graphics.FromImage(keyboard))
+ {
+ foreach (var soundRectangle in SoundRectangles)
+ soundRectangle.Draw(g);
+ }
_generating = false;
}
diff --git a/Artemis/Artemis/Modules/Effects/Bubbles/Bubble.cs b/Artemis/Artemis/Modules/Effects/Bubbles/Bubble.cs
index 535e03428..3e9755968 100644
--- a/Artemis/Artemis/Modules/Effects/Bubbles/Bubble.cs
+++ b/Artemis/Artemis/Modules/Effects/Bubbles/Bubble.cs
@@ -6,11 +6,24 @@ namespace Artemis.Modules.Effects.Bubbles
{
public class Bubble
{
+ #region Constructors
+
+ public Bubble(Color color, int radius, Point position, Vector direction)
+ {
+ Color = color;
+ Radius = radius;
+ Position = position;
+ Direction = direction;
+ }
+
+ #endregion
+
#region Properties & Fields
private Brush _brush;
private Color _color;
+
public Color Color
{
get { return _color; }
@@ -27,27 +40,15 @@ namespace Artemis.Modules.Effects.Bubbles
#endregion
- #region Constructors
-
- public Bubble(Color color, int radius, Point position, Vector direction)
- {
- this.Color = color;
- this.Radius = radius;
- this.Position = position;
- this.Direction = direction;
- }
-
- #endregion
-
#region Methods
public void CheckCollision(Rect border)
{
if (Position.X - Radius < border.X || Position.X + Radius > border.X + border.Width)
- Direction = new Vector(Direction.X * -1, Direction.Y);
+ Direction = new Vector(Direction.X*-1, Direction.Y);
if (Position.Y - Radius < border.Y || Position.Y + Radius > border.Y + border.Height)
- Direction = new Vector(Direction.X, Direction.Y * -1);
+ Direction = new Vector(Direction.X, Direction.Y*-1);
}
public void Move()
@@ -57,9 +58,9 @@ namespace Artemis.Modules.Effects.Bubbles
public void Draw(Graphics g)
{
- g.FillEllipse(_brush, (float)Position.X - Radius, (float)Position.Y - Radius, Radius * 2, Radius * 2);
+ g.FillEllipse(_brush, (float) Position.X - Radius, (float) Position.Y - Radius, Radius*2, Radius*2);
}
#endregion
}
-}
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Effects/Bubbles/Bubbles.cs b/Artemis/Artemis/Modules/Effects/Bubbles/Bubbles.cs
new file mode 100644
index 000000000..bf183261a
--- /dev/null
+++ b/Artemis/Artemis/Modules/Effects/Bubbles/Bubbles.cs
@@ -0,0 +1,28 @@
+namespace Artemis.Modules.Effects.Bubbles {
+
+
+ // This class allows you to handle specific events on the settings class:
+ // The SettingChanging event is raised before a setting's value is changed.
+ // The PropertyChanged event is raised after a setting's value is changed.
+ // The SettingsLoaded event is raised after the setting values are loaded.
+ // The SettingsSaving event is raised before the setting values are saved.
+ internal sealed partial class Bubbles {
+
+ public Bubbles() {
+ // // To add event handlers for saving and changing settings, uncomment the lines below:
+ //
+ // this.SettingChanging += this.SettingChangingEventHandler;
+ //
+ // this.SettingsSaving += this.SettingsSavingEventHandler;
+ //
+ }
+
+ private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
+ // Add code to handle the SettingChangingEvent event here.
+ }
+
+ private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
+ // Add code to handle the SettingsSaving event here.
+ }
+ }
+}
diff --git a/Artemis/Artemis/Modules/Effects/Bubbles/Bubbles.settings b/Artemis/Artemis/Modules/Effects/Bubbles/Bubbles.settings
index 98fa04416..748dada51 100644
--- a/Artemis/Artemis/Modules/Effects/Bubbles/Bubbles.settings
+++ b/Artemis/Artemis/Modules/Effects/Bubbles/Bubbles.settings
@@ -1,5 +1,7 @@
-
+
+
diff --git a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesModel.cs b/Artemis/Artemis/Modules/Effects/Bubbles/BubblesModel.cs
index 66ecd0ea2..0ec3ecb48 100644
--- a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesModel.cs
+++ b/Artemis/Artemis/Modules/Effects/Bubbles/BubblesModel.cs
@@ -4,24 +4,14 @@ using System.Drawing;
using System.Windows;
using Artemis.Managers;
using Artemis.Models;
-using Artemis.Models.Profiles;
+using Artemis.Profiles.Layers.Models;
using Artemis.Utilities;
-using Brush = System.Windows.Media.Brush;
+using Point = System.Windows.Point;
namespace Artemis.Modules.Effects.Bubbles
{
public class BubblesModel : EffectModel
{
- #region Properties & Fields
-
- private static readonly Random _random = new Random();
-
- private readonly List _bubbles = new List();
-
- public BubblesSettings Settings { get; }
-
- #endregion
-
#region Constructors
public BubblesModel(MainManager mainManager, BubblesSettings settings)
@@ -34,27 +24,43 @@ namespace Artemis.Modules.Effects.Bubbles
#endregion
+ #region Properties & Fields
+
+ private static readonly Random _random = new Random();
+
+ private readonly List _bubbles = new List();
+
+ public BubblesSettings Settings { get; }
+
+ #endregion
+
#region Methods
public override void Enable()
{
KeyboardScale = Settings.Smoothness;
- Rect rect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
+ var rect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
- double scaleFactor = Settings.Smoothness / 25.0;
+ var scaleFactor = Settings.Smoothness/25.0;
- for (int i = 0; i < Settings.BubbleCount; i++)
+ for (var i = 0; i < Settings.BubbleCount; i++)
{
- Color color = Settings.IsRandomColors ? ColorHelpers.GetRandomRainbowColor() : ColorHelpers.ToDrawingColor(Settings.BubbleColor);
+ var color = Settings.IsRandomColors
+ ? ColorHelpers.GetRandomRainbowColor()
+ : ColorHelpers.ToDrawingColor(Settings.BubbleColor);
// -Settings.MoveSpeed because we want to spawn at least one move away from borders
- double initialPositionX = ((rect.Width - (Settings.BubbleSize * scaleFactor * 2) - Settings.MoveSpeed * scaleFactor) * _random.NextDouble()) + Settings.BubbleSize * scaleFactor;
- double initialPositionY = ((rect.Height - (Settings.BubbleSize * scaleFactor * 2) - Settings.MoveSpeed * scaleFactor) * _random.NextDouble()) + Settings.BubbleSize * scaleFactor;
- double initialDirectionX = (Settings.MoveSpeed * scaleFactor * _random.NextDouble()) * (_random.Next(1) == 0 ? -1 : 1);
- double initialDirectionY = (Settings.MoveSpeed * scaleFactor - Math.Abs(initialDirectionX)) * (_random.Next(1) == 0 ? -1 : 1);
+ var initialPositionX = (rect.Width - Settings.BubbleSize*scaleFactor*2 - Settings.MoveSpeed*scaleFactor)*
+ _random.NextDouble() + Settings.BubbleSize*scaleFactor;
+ var initialPositionY = (rect.Height - Settings.BubbleSize*scaleFactor*2 - Settings.MoveSpeed*scaleFactor)*
+ _random.NextDouble() + Settings.BubbleSize*scaleFactor;
+ var initialDirectionX = Settings.MoveSpeed*scaleFactor*_random.NextDouble()*
+ (_random.Next(1) == 0 ? -1 : 1);
+ var initialDirectionY = (Settings.MoveSpeed*scaleFactor - Math.Abs(initialDirectionX))*
+ (_random.Next(1) == 0 ? -1 : 1);
- _bubbles.Add(new Bubble(color, (int)Math.Round(Settings.BubbleSize * scaleFactor),
- new System.Windows.Point(initialPositionX, initialPositionY), new Vector(initialDirectionX, initialDirectionY)));
+ _bubbles.Add(new Bubble(color, (int) Math.Round(Settings.BubbleSize*scaleFactor),
+ new Point(initialPositionX, initialPositionY), new Vector(initialDirectionX, initialDirectionY)));
}
Initialized = true;
@@ -68,24 +74,31 @@ namespace Artemis.Modules.Effects.Bubbles
public override void Update()
{
- Rect keyboardRectangle = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
- foreach (Bubble bubble in _bubbles)
+ var keyboardRectangle = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
+ foreach (var bubble in _bubbles)
{
if (Settings.IsShiftColors)
- bubble.Color = ColorHelpers.ShiftColor(bubble.Color, Settings.IsRandomColors ? (int)Math.Round(Settings.ShiftColorSpeed * _random.NextDouble()) : Settings.ShiftColorSpeed);
+ bubble.Color = ColorHelpers.ShiftColor(bubble.Color,
+ Settings.IsRandomColors
+ ? (int) Math.Round(Settings.ShiftColorSpeed*_random.NextDouble())
+ : Settings.ShiftColorSpeed);
bubble.CheckCollision(keyboardRectangle);
bubble.Move();
}
}
- public override void Render(Graphics keyboard, out Brush mouse, out Brush headset, bool renderMice, bool renderHeadsets)
+ public override void Render(Bitmap keyboard, out Bitmap mouse, out Bitmap headset, bool renderMice,
+ bool renderHeadsets)
{
mouse = null;
headset = null;
- foreach (Bubble bubble in _bubbles)
- bubble.Draw(keyboard);
+ using (var g = Graphics.FromImage(keyboard))
+ {
+ foreach (var bubble in _bubbles)
+ bubble.Draw(g);
+ }
}
public override List GetRenderLayers(bool renderMice, bool renderHeadsets)
@@ -95,4 +108,4 @@ namespace Artemis.Modules.Effects.Bubbles
#endregion
}
-}
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesSettings.cs b/Artemis/Artemis/Modules/Effects/Bubbles/BubblesSettings.cs
index 149daa6d1..a6f264c67 100644
--- a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesSettings.cs
+++ b/Artemis/Artemis/Modules/Effects/Bubbles/BubblesSettings.cs
@@ -57,4 +57,4 @@ namespace Artemis.Modules.Effects.Bubbles
Smoothness = 25;
}
}
-}
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesView.xaml b/Artemis/Artemis/Modules/Effects/Bubbles/BubblesView.xaml
index 9c40b7792..cb79d8462 100644
--- a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesView.xaml
+++ b/Artemis/Artemis/Modules/Effects/Bubbles/BubblesView.xaml
@@ -120,7 +120,7 @@
HorizontalAlignment="Right" Width="110" TickPlacement="None" TickFrequency="1"
Value="{Binding Path=EffectSettings.MoveSpeed, Mode=TwoWay}" Minimum="1" Maximum="15"
SmallChange="10" IsSnapToTickEnabled="True" />
-
+
diff --git a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesView.xaml.cs b/Artemis/Artemis/Modules/Effects/Bubbles/BubblesView.xaml.cs
index 2392befb1..3a9bf3cca 100644
--- a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesView.xaml.cs
+++ b/Artemis/Artemis/Modules/Effects/Bubbles/BubblesView.xaml.cs
@@ -9,4 +9,4 @@ namespace Artemis.Modules.Effects.Bubbles
InitializeComponent();
}
}
-}
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesViewModel.cs b/Artemis/Artemis/Modules/Effects/Bubbles/BubblesViewModel.cs
index c24f95272..9c2803a0e 100644
--- a/Artemis/Artemis/Modules/Effects/Bubbles/BubblesViewModel.cs
+++ b/Artemis/Artemis/Modules/Effects/Bubbles/BubblesViewModel.cs
@@ -14,7 +14,7 @@ namespace Artemis.Modules.Effects.Bubbles
events.Subscribe(this);
MainManager.EffectManager.EffectModels.Add(EffectModel);
- EffectSettings = ((BubblesModel)EffectModel).Settings;
+ EffectSettings = ((BubblesModel) EffectModel).Settings;
}
public void Handle(ActiveEffectChanged message)
@@ -22,4 +22,4 @@ namespace Artemis.Modules.Effects.Bubbles
NotifyOfPropertyChange(() => EffectEnabled);
}
}
-}
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs b/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs
index aa0819ab9..f66a8b7ad 100644
--- a/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs
+++ b/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs
@@ -1,11 +1,13 @@
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
+using System.Windows;
using Artemis.Managers;
using Artemis.Models;
using Artemis.Models.Interfaces;
-using Artemis.Models.Profiles;
-using Brush = System.Windows.Media.Brush;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Profiles.Layers.Types.Headset;
+using Artemis.Profiles.Layers.Types.Mouse;
namespace Artemis.Modules.Effects.ProfilePreview
{
@@ -32,10 +34,10 @@ namespace Artemis.Modules.Effects.ProfilePreview
public override List GetRenderLayers(bool renderMice, bool renderHeadsets)
{
- return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets, true);
+ return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets, true);
}
- public override void Render(Graphics keyboard, out Brush mouse, out Brush headset, bool renderMice,
+ public override void Render(Bitmap keyboard, out Bitmap mouse, out Bitmap headset, bool renderMice,
bool renderHeadsets)
{
mouse = null;
@@ -48,12 +50,30 @@ namespace Artemis.Modules.Effects.ProfilePreview
var renderLayers = GetRenderLayers(renderMice, renderHeadsets);
// Render the keyboard layer-by-layer
- Profile?.DrawProfile(keyboard, renderLayers, DataModel, MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale), true, true);
- // Render the first enabled mouse (will default to null if renderMice was false)
- mouse = Profile?.GenerateBrush(renderLayers.LastOrDefault(l => l.LayerType == LayerType.Mouse), DataModel);
- // Render the first enabled headset (will default to null if renderHeadsets was false)
- headset = Profile?.GenerateBrush(renderLayers.LastOrDefault(l => l.LayerType == LayerType.Headset),
- DataModel);
+ var keyboardRect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
+ using (var g = Graphics.FromImage(keyboard))
+ {
+ // Fill the bitmap's background with black to avoid trailing colors on some keyboards
+ g.Clear(Color.Black);
+ Profile.DrawLayers(g, renderLayers.Where(rl => rl.MustDraw()), DataModel, keyboardRect, true, true);
+ }
+
+ // Render the mouse layer-by-layer
+ var smallRect = new Rect(0, 0, 40, 40);
+ mouse = new Bitmap(40, 40);
+ using (var g = Graphics.FromImage(mouse))
+ {
+ Profile.DrawLayers(g, renderLayers.Where(rl => rl.LayerType is MouseType), DataModel, smallRect,
+ true, true);
+ }
+
+ // Render the headset layer-by-layer
+ headset = new Bitmap(40, 40);
+ using (var g = Graphics.FromImage(headset))
+ {
+ Profile.DrawLayers(g, renderLayers.Where(rl => rl.LayerType is HeadsetType), DataModel, smallRect,
+ true, true);
+ }
}
}
diff --git a/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveModel.cs b/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveModel.cs
index 366012c8f..8020ac68d 100644
--- a/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveModel.cs
+++ b/Artemis/Artemis/Modules/Effects/TypeWave/TypeWaveModel.cs
@@ -7,9 +7,8 @@ using Artemis.DeviceProviders.Corsair;
using Artemis.DeviceProviders.Logitech.Utilities;
using Artemis.Managers;
using Artemis.Models;
-using Artemis.Models.Profiles;
+using Artemis.Profiles.Layers.Models;
using Artemis.Utilities;
-using Brush = System.Windows.Media.Brush;
namespace Artemis.Modules.Effects.TypeWave
{
@@ -46,8 +45,8 @@ namespace Artemis.Modules.Effects.TypeWave
return;
_waves.Add(Settings.IsRandomColors
- ? new Wave(new Point(keyMatch.PosX * KeyboardScale, keyMatch.PosY * KeyboardScale), 0, _randomColor)
- : new Wave(new Point(keyMatch.PosX * KeyboardScale, keyMatch.PosY * KeyboardScale), 0,
+ ? new Wave(new Point(keyMatch.PosX*KeyboardScale, keyMatch.PosY*KeyboardScale), 0, _randomColor)
+ : new Wave(new Point(keyMatch.PosX*KeyboardScale, keyMatch.PosY*KeyboardScale), 0,
ColorHelpers.ToDrawingColor(Settings.WaveColor)));
}
@@ -71,12 +70,12 @@ namespace Artemis.Modules.Effects.TypeWave
// TODO: Get from settings
var fps = 25;
- _waves[i].Size += Settings.SpreadSpeed * KeyboardScale;
+ _waves[i].Size += Settings.SpreadSpeed*KeyboardScale;
if (Settings.IsShiftColors)
_waves[i].Color = ColorHelpers.ShiftColor(_waves[i].Color, Settings.ShiftColorSpeed);
- var decreaseAmount = 255 / (Settings.TimeToLive / fps);
+ var decreaseAmount = 255/(Settings.TimeToLive/fps);
_waves[i].Color = Color.FromArgb(
_waves[i].Color.A - decreaseAmount, _waves[i].Color.R,
_waves[i].Color.G,
@@ -95,7 +94,7 @@ namespace Artemis.Modules.Effects.TypeWave
return null;
}
- public override void Render(Graphics keyboard, out Brush mouse, out Brush headset, bool renderMice,
+ public override void Render(Bitmap keyboard, out Bitmap mouse, out Bitmap headset, bool renderMice,
bool renderHeadsets)
{
mouse = null;
@@ -111,7 +110,7 @@ namespace Artemis.Modules.Effects.TypeWave
if (_waves[i].Size == 0)
continue;
var path = new GraphicsPath();
- path.AddEllipse(_waves[i].Point.X - _waves[i].Size / 2, _waves[i].Point.Y - _waves[i].Size / 2,
+ path.AddEllipse(_waves[i].Point.X - _waves[i].Size/2, _waves[i].Point.Y - _waves[i].Size/2,
_waves[i].Size, _waves[i].Size);
Color fillColor;
@@ -122,16 +121,19 @@ namespace Artemis.Modules.Effects.TypeWave
var pthGrBrush = new PathGradientBrush(path)
{
- SurroundColors = new[] { _waves[i].Color },
+ SurroundColors = new[] {_waves[i].Color},
CenterColor = fillColor
};
- keyboard.FillPath(pthGrBrush, path);
- pthGrBrush.FocusScales = new PointF(0.3f, 0.8f);
+ using (var g = Graphics.FromImage(keyboard))
+ {
+ g.FillPath(pthGrBrush, path);
+ pthGrBrush.FocusScales = new PointF(0.3f, 0.8f);
- keyboard.FillPath(pthGrBrush, path);
- keyboard.DrawEllipse(new Pen(pthGrBrush, 1), _waves[i].Point.X - _waves[i].Size / 2,
- _waves[i].Point.Y - _waves[i].Size / 2, _waves[i].Size, _waves[i].Size);
+ g.FillPath(pthGrBrush, path);
+ g.DrawEllipse(new Pen(pthGrBrush, 1), _waves[i].Point.X - _waves[i].Size/2,
+ _waves[i].Point.Y - _waves[i].Size/2, _waves[i].Size, _waves[i].Size);
+ }
}
}
}
diff --git a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileDataModel.cs b/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileDataModel.cs
index be27cad22..ca28bc496 100644
--- a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileDataModel.cs
+++ b/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileDataModel.cs
@@ -14,6 +14,16 @@ namespace Artemis.Modules.Effects.WindowsProfile
public CpuDataModel Cpu { get; set; }
public PerformanceDataModel Performance { get; set; }
public Spotify Spotify { get; set; }
+ public CurrentTime CurrentTime { get; set; }
+ }
+
+ class CurrentTime
+ {
+ public int Hours24 { get; set; }
+ public int Hours12 { get; set; }
+ public int Minutes { get; set; }
+ public int Seconds { get; set; }
+
}
public class CpuDataModel
diff --git a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileModel.cs b/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileModel.cs
index 03d1843ee..1ce50203f 100644
--- a/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileModel.cs
+++ b/Artemis/Artemis/Modules/Effects/WindowsProfile/WindowsProfileModel.cs
@@ -6,7 +6,7 @@ using System.Threading;
using System.Threading.Tasks;
using Artemis.Managers;
using Artemis.Models;
-using Artemis.Models.Profiles;
+using Artemis.Profiles.Layers.Models;
using Ninject.Extensions.Logging;
using SpotifyAPI.Local;
@@ -16,7 +16,8 @@ namespace Artemis.Modules.Effects.WindowsProfile
{
[DllImport("psapi.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool GetPerformanceInfo([Out] out PerformanceInformation performanceInformation, [In] int size);
+ public static extern bool GetPerformanceInfo([Out] out PerformanceInformation performanceInformation,
+ [In] int size);
public static long GetPhysicalAvailableMemoryInMiB()
{
@@ -58,6 +59,8 @@ namespace Artemis.Modules.Effects.WindowsProfile
}
}
+
+
public class WindowsProfileModel : EffectModel
{
private readonly ILogger _logger;
@@ -95,6 +98,7 @@ namespace Artemis.Modules.Effects.WindowsProfile
var dataModel = (WindowsProfileDataModel) DataModel;
UpdateCpu(dataModel);
UpdateSpotify(dataModel);
+ UpdateDay(dataModel);
}
#region CPU
@@ -161,7 +165,7 @@ namespace Artemis.Modules.Effects.WindowsProfile
public override List GetRenderLayers(bool renderMice, bool renderHeadsets)
{
- return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets, false);
+ return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets, false);
}
public static PerformanceCounter GetOverallPerformanceCounter()
@@ -190,6 +194,19 @@ namespace Artemis.Modules.Effects.WindowsProfile
#endregion
+ #region Current Time
+ private void UpdateDay(WindowsProfileDataModel dataModel)
+ {
+
+ var now = DateTime.Now;
+ dataModel.CurrentTime.Hours24 = int.Parse(now.ToString("HH"));
+ dataModel.CurrentTime.Hours12 = int.Parse(now.ToString("hh"));
+ dataModel.CurrentTime.Minutes = int.Parse(now.ToString("mm"));
+ dataModel.CurrentTime.Seconds = int.Parse(now.ToString("ss"));
+
+ }
+ #endregion
+
#region Spotify
public void SetupSpotify()
diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrike.Designer.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrike.Designer.cs
index e9ab9d8e4..85a966af8 100644
--- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrike.Designer.cs
+++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrike.Designer.cs
@@ -35,102 +35,6 @@ namespace Artemis.Modules.Games.CounterStrike {
}
}
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("")]
- public string GameDirectory {
- get {
- return ((string)(this["GameDirectory"]));
- }
- set {
- this["GameDirectory"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("True")]
- public bool AmmoEnabled {
- get {
- return ((bool)(this["AmmoEnabled"]));
- }
- set {
- this["AmmoEnabled"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("#FFFF2900")]
- public global::System.Windows.Media.Color AmmoMainColor {
- get {
- return ((global::System.Windows.Media.Color)(this["AmmoMainColor"]));
- }
- set {
- this["AmmoMainColor"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("#FF26F600")]
- public global::System.Windows.Media.Color AmmoSecondaryColor {
- get {
- return ((global::System.Windows.Media.Color)(this["AmmoSecondaryColor"]));
- }
- set {
- this["AmmoSecondaryColor"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("True")]
- public bool TeamColorEnabled {
- get {
- return ((bool)(this["TeamColorEnabled"]));
- }
- set {
- this["TeamColorEnabled"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("True")]
- public bool FlashEnabled {
- get {
- return ((bool)(this["FlashEnabled"]));
- }
- set {
- this["FlashEnabled"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("True")]
- public bool SmokeEnabled {
- get {
- return ((bool)(this["SmokeEnabled"]));
- }
- set {
- this["SmokeEnabled"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("True")]
- public bool LowHpEnabled {
- get {
- return ((bool)(this["LowHpEnabled"]));
- }
- set {
- this["LowHpEnabled"] = value;
- }
- }
-
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("Default")]
@@ -142,5 +46,17 @@ namespace Artemis.Modules.Games.CounterStrike {
this["LastProfile"] = value;
}
}
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string GameDirectory {
+ get {
+ return ((string)(this["GameDirectory"]));
+ }
+ set {
+ this["GameDirectory"] = value;
+ }
+ }
}
}
diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrike.settings b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrike.settings
index e5b8b302b..cfa6c587e 100644
--- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrike.settings
+++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrike.settings
@@ -1,7 +1,5 @@
-
-
+
@@ -13,26 +11,5 @@
-
- True
-
-
- #FFFF2900
-
-
- #FF26F600
-
-
- True
-
-
- True
-
-
- True
-
-
- True
-
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs
index 35f69761b..567c79bca 100644
--- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs
+++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using Artemis.Managers;
using Artemis.Models;
-using Artemis.Models.Profiles;
+using Artemis.Profiles.Layers.Models;
using Artemis.Utilities.GameState;
using Newtonsoft.Json;
using Ninject.Extensions.Logging;
@@ -66,7 +66,7 @@ namespace Artemis.Modules.Games.CounterStrike
public override List GetRenderLayers(bool renderMice, bool renderHeadsets)
{
- return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
+ return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeSettings.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeSettings.cs
index 96141065c..24b5699f1 100644
--- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeSettings.cs
+++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeSettings.cs
@@ -1,5 +1,4 @@
-using System.Windows.Media;
-using Artemis.Models;
+using Artemis.Models;
namespace Artemis.Modules.Games.CounterStrike
{
@@ -12,29 +11,11 @@ namespace Artemis.Modules.Games.CounterStrike
public string GameDirectory { get; set; }
- public bool AmmoEnabled { get; set; }
- public Color AmmoMainColor { get; set; }
- public Color AmmoSecondaryColor { get; set; }
-
- public bool TeamColorEnabled { get; set; }
- public bool FlashEnabled { get; set; }
- public bool SmokeEnabled { get; set; }
- public bool LowHpEnabled { get; set; }
-
public sealed override void Load()
{
Enabled = CounterStrike.Default.Enabled;
LastProfile = CounterStrike.Default.LastProfile;
GameDirectory = CounterStrike.Default.GameDirectory;
-
- AmmoEnabled = CounterStrike.Default.AmmoEnabled;
- AmmoMainColor = CounterStrike.Default.AmmoMainColor;
- AmmoSecondaryColor = CounterStrike.Default.AmmoSecondaryColor;
-
- TeamColorEnabled = CounterStrike.Default.TeamColorEnabled;
- FlashEnabled = CounterStrike.Default.FlashEnabled;
- SmokeEnabled = CounterStrike.Default.SmokeEnabled;
- LowHpEnabled = CounterStrike.Default.LowHpEnabled;
}
public sealed override void Save()
@@ -42,15 +23,6 @@ namespace Artemis.Modules.Games.CounterStrike
CounterStrike.Default.Enabled = Enabled;
CounterStrike.Default.GameDirectory = GameDirectory;
- CounterStrike.Default.AmmoEnabled = AmmoEnabled;
- CounterStrike.Default.AmmoMainColor = AmmoMainColor;
- CounterStrike.Default.AmmoSecondaryColor = AmmoSecondaryColor;
-
- CounterStrike.Default.TeamColorEnabled = TeamColorEnabled;
- CounterStrike.Default.FlashEnabled = FlashEnabled;
- CounterStrike.Default.SmokeEnabled = SmokeEnabled;
- CounterStrike.Default.LowHpEnabled = LowHpEnabled;
-
CounterStrike.Default.Save();
}
@@ -58,15 +30,6 @@ namespace Artemis.Modules.Games.CounterStrike
{
Enabled = true;
GameDirectory = string.Empty;
-
- AmmoEnabled = true;
- AmmoMainColor = Color.FromArgb(255, 38, 246, 0);
- AmmoSecondaryColor = Color.FromArgb(255, 255, 41, 0);
-
- TeamColorEnabled = true;
- FlashEnabled = true;
- SmokeEnabled = true;
- LowHpEnabled = true;
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Dota2/Dota2.Designer.cs b/Artemis/Artemis/Modules/Games/Dota2/Dota2.Designer.cs
index 8e1cd92e2..1f692a740 100644
--- a/Artemis/Artemis/Modules/Games/Dota2/Dota2.Designer.cs
+++ b/Artemis/Artemis/Modules/Games/Dota2/Dota2.Designer.cs
@@ -58,125 +58,5 @@ namespace Artemis.Modules.Games.Dota2 {
this["GameDirectory"] = value;
}
}
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("True")]
- public bool CanCastAbility {
- get {
- return ((bool)(this["CanCastAbility"]));
- }
- set {
- this["CanCastAbility"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("True")]
- public bool ShowHealth {
- get {
- return ((bool)(this["ShowHealth"]));
- }
- set {
- this["ShowHealth"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("True")]
- public bool ShowDayCycle {
- get {
- return ((bool)(this["ShowDayCycle"]));
- }
- set {
- this["ShowDayCycle"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("True")]
- public bool ShowMana {
- get {
- return ((bool)(this["ShowMana"]));
- }
- set {
- this["ShowMana"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("True")]
- public bool ShowEvents {
- get {
- return ((bool)(this["ShowEvents"]));
- }
- set {
- this["ShowEvents"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("#FFFF0000")]
- public global::System.Windows.Media.Color MainColor {
- get {
- return ((global::System.Windows.Media.Color)(this["MainColor"]));
- }
- set {
- this["MainColor"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("#FF0000FF")]
- public global::System.Windows.Media.Color ManaColor {
- get {
- return ((global::System.Windows.Media.Color)(this["ManaColor"]));
- }
- set {
- this["ManaColor"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("Default")]
- public string KeyboardLayout {
- get {
- return ((string)(this["KeyboardLayout"]));
- }
- set {
- this["KeyboardLayout"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("#FF00FF00")]
- public global::System.Windows.Media.Color AbilityReadyColor {
- get {
- return ((global::System.Windows.Media.Color)(this["AbilityReadyColor"]));
- }
- set {
- this["AbilityReadyColor"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("#FF6A5ACD")]
- public global::System.Windows.Media.Color AbilityCooldownColor {
- get {
- return ((global::System.Windows.Media.Color)(this["AbilityCooldownColor"]));
- }
- set {
- this["AbilityCooldownColor"] = value;
- }
- }
}
}
diff --git a/Artemis/Artemis/Modules/Games/Dota2/Dota2.settings b/Artemis/Artemis/Modules/Games/Dota2/Dota2.settings
index 557cc1a44..c3dafb56c 100644
--- a/Artemis/Artemis/Modules/Games/Dota2/Dota2.settings
+++ b/Artemis/Artemis/Modules/Games/Dota2/Dota2.settings
@@ -1,7 +1,5 @@
-
-
+
@@ -13,35 +11,5 @@
-
- True
-
-
- True
-
-
- True
-
-
- True
-
-
- True
-
-
- #FFFF0000
-
-
- #FF0000FF
-
-
- Default
-
-
- #FF00FF00
-
-
- #FF6A5ACD
-
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs b/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs
index 6b3c77ce3..1c4fb8fb4 100644
--- a/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs
+++ b/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using Artemis.Managers;
using Artemis.Models;
-using Artemis.Models.Profiles;
+using Artemis.Profiles.Layers.Models;
using Artemis.Utilities.GameState;
using Newtonsoft.Json;
@@ -66,7 +66,7 @@ namespace Artemis.Modules.Games.Dota2
public override List GetRenderLayers(bool renderMice, bool renderHeadsets)
{
- return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
+ return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Dota2/Dota2Settings.cs b/Artemis/Artemis/Modules/Games/Dota2/Dota2Settings.cs
index ada8893d1..b57b5b478 100644
--- a/Artemis/Artemis/Modules/Games/Dota2/Dota2Settings.cs
+++ b/Artemis/Artemis/Modules/Games/Dota2/Dota2Settings.cs
@@ -1,5 +1,4 @@
-using System.Windows.Media;
-using Artemis.Models;
+using Artemis.Models;
namespace Artemis.Modules.Games.Dota2
{
@@ -10,74 +9,28 @@ namespace Artemis.Modules.Games.Dota2
Load();
}
+ public string GameDirectory { get; set; }
- public override void Load()
+
+ public sealed override void Load()
{
- KeyboardLayout = Dota2.Default.KeyboardLayout;
- MainColor = Dota2.Default.MainColor;
- ManaColor = Dota2.Default.ManaColor;
- ShowHealth = Dota2.Default.ShowHealth;
- CanCastAbility = Dota2.Default.CanCastAbility;
Enabled = Dota2.Default.Enabled;
GameDirectory = Dota2.Default.GameDirectory;
- ShowDayCycle = Dota2.Default.ShowDayCycle;
- ShowMana = Dota2.Default.ShowMana;
- ShowEvents = Dota2.Default.ShowEvents;
- AbilityReadyColor = Dota2.Default.AbilityReadyColor;
- AbilityCooldownColor = Dota2.Default.AbilityCooldownColor;
}
- public override void Save()
+ public sealed override void Save()
{
Dota2.Default.Enabled = Enabled;
Dota2.Default.LastProfile = LastProfile;
Dota2.Default.GameDirectory = GameDirectory;
- Dota2.Default.KeyboardLayout = KeyboardLayout;
- Dota2.Default.MainColor = MainColor;
- Dota2.Default.ManaColor = ManaColor;
- Dota2.Default.ShowDayCycle = ShowDayCycle;
- Dota2.Default.ShowHealth = ShowHealth;
- Dota2.Default.CanCastAbility = CanCastAbility;
- Dota2.Default.ShowMana = ShowMana;
- Dota2.Default.ShowEvents = ShowEvents;
- Dota2.Default.AbilityCooldownColor = AbilityCooldownColor;
- Dota2.Default.AbilityReadyColor = AbilityReadyColor;
-
Dota2.Default.Save();
}
- public override void ToDefault()
+ public sealed override void ToDefault()
{
Enabled = true;
GameDirectory = string.Empty;
-
- KeyboardLayout = "Default";
- MainColor = Color.FromArgb(255, 255, 0, 0);
- ManaColor = Color.FromArgb(255, 0, 0, 255);
- AbilityCooldownColor = Color.FromArgb(255, 106, 90, 205);
- AbilityReadyColor = Color.FromArgb(255, 0, 255, 0);
- ShowHealth = true;
- CanCastAbility = true;
- ShowDayCycle = true;
- ShowMana = true;
- ShowEvents = true;
}
-
- #region Variables
-
- public string GameDirectory { get; set; }
- public bool CanCastAbility { get; set; }
- public bool ShowHealth { get; set; }
- public bool ShowDayCycle { get; set; }
- public bool ShowMana { get; set; }
- public bool ShowEvents { get; set; }
- public Color MainColor { get; set; }
- public Color ManaColor { get; set; }
- public string KeyboardLayout { get; set; }
- public Color AbilityCooldownColor { get; set; }
- public Color AbilityReadyColor { get; set; }
-
- #endregion
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchDataModel.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchDataModel.cs
index 31bd573ee..f7e3ece14 100644
--- a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchDataModel.cs
+++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchDataModel.cs
@@ -9,13 +9,16 @@ namespace Artemis.Modules.Games.Overwatch
public bool UltimateReady { get; set; }
public bool Ability1Ready { get; set; }
public bool Ability2Ready { get; set; }
+ public bool UltimateUsed { get; set; }
+ public bool CanChangeHero { get; set; }
}
public enum OverwatchStatus
{
- Unkown,
+ Unknown,
InMainMenu,
- InGame
+ InGame,
+ InCharacterSelect
}
public enum OverwatchCharacter
diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs
index acab9c792..fa92cebaf 100644
--- a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs
+++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs
@@ -1,21 +1,28 @@
-using System.Collections.Generic;
-using System.Drawing;
+using System;
+using System.Collections.Generic;
using System.Linq;
+using System.Windows.Media;
using Artemis.Events;
using Artemis.Managers;
using Artemis.Models;
using Artemis.Models.Interfaces;
-using Artemis.Models.Profiles;
+using Artemis.Profiles.Layers.Models;
using Artemis.Utilities;
using Artemis.Utilities.DataReaders;
using Caliburn.Micro;
-using Color = System.Windows.Media.Color;
namespace Artemis.Modules.Games.Overwatch
{
public class OverwatchModel : GameModel
{
private readonly IEventAggregator _events;
+ private DateTime _characterChange;
+ // Using sticky values on these since they can cause flickering
+ private StickyValue _stickyStatus;
+ private StickyValue _stickyUltimateReady;
+ private StickyValue _stickyUltimateUsed;
+ private DateTime _ultimateReady;
+ private DateTime _ultimateUsed;
public OverwatchModel(IEventAggregator events, MainManager mainManager, OverwatchSettings settings)
: base(mainManager, settings, new OverwatchDataModel())
@@ -27,7 +34,7 @@ namespace Artemis.Modules.Games.Overwatch
Enabled = Settings.Enabled;
Initialized = false;
- MmfReader = new MmfReader("overwatchMmf");
+ MmfReader = new MmfReader("overwatchMmf", MainManager.Logger);
LoadOverwatchCharacters();
}
@@ -46,102 +53,184 @@ namespace Artemis.Modules.Games.Overwatch
{
OverwatchCharacters = new List
{
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Genji, Color = Color.FromRgb(13, 61, 0)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Mccree, Color = Color.FromRgb(24, 1, 1)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Pharah, Color = Color.FromRgb(0, 6, 32)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Reaper, Color = Color.FromRgb(7, 0, 0)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Soldier76, Color = Color.FromRgb(3, 5, 11)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Tracer, Color = Color.FromRgb(46, 12, 0)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Bastion, Color = Color.FromRgb(6, 10, 5)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Hanzo, Color = Color.FromRgb(28, 24, 8)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Junkrat, Color = Color.FromRgb(59, 28, 0)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Mei, Color = Color.FromRgb(3, 20, 55)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Torbjörn, Color = Color.FromRgb(31, 4, 3)},
- new CharacterColor
- {
- OverwatchCharacter = OverwatchCharacter.Widowmaker,
- Color = Color.FromRgb(16, 3, 17)
- },
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Dva, Color = Color.FromRgb(62, 12, 32)},
- new CharacterColor
- {
- OverwatchCharacter = OverwatchCharacter.Reinhardt,
- Color = Color.FromRgb(12, 16, 16)
- },
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Roadhog, Color = Color.FromRgb(26, 10, 0)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Winston, Color = Color.FromRgb(17, 18, 26)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Zarya, Color = Color.FromRgb(58, 7, 24)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Lúcio, Color = Color.FromRgb(8, 35, 0)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Mercy, Color = Color.FromRgb(60, 56, 26)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Symmetra, Color = Color.FromRgb(11, 29, 37)},
- new CharacterColor {OverwatchCharacter = OverwatchCharacter.Zenyatta, Color = Color.FromRgb(62, 54, 6)}
+ new CharacterColor {Character = OverwatchCharacter.Genji, Color = Color.FromRgb(55, 245, 0)},
+ new CharacterColor {Character = OverwatchCharacter.Mccree, Color = Color.FromRgb(97, 5, 5)},
+ new CharacterColor {Character = OverwatchCharacter.Pharah, Color = Color.FromRgb(0, 24, 128)},
+ new CharacterColor {Character = OverwatchCharacter.Reaper, Color = Color.FromRgb(28, 0, 2)},
+ new CharacterColor {Character = OverwatchCharacter.Soldier76, Color = Color.FromRgb(14, 21, 45)},
+ new CharacterColor {Character = OverwatchCharacter.Tracer, Color = Color.FromRgb(186, 49, 0)},
+ new CharacterColor {Character = OverwatchCharacter.Bastion, Color = Color.FromRgb(26, 43, 20)},
+ new CharacterColor {Character = OverwatchCharacter.Hanzo, Color = Color.FromRgb(113, 99, 33)},
+ new CharacterColor {Character = OverwatchCharacter.Junkrat, Color = Color.FromRgb(237, 113, 2)},
+ new CharacterColor {Character = OverwatchCharacter.Mei, Color = Color.FromRgb(15, 82, 222)},
+ new CharacterColor {Character = OverwatchCharacter.Torbjörn, Color = Color.FromRgb(125, 18, 12)},
+ new CharacterColor {Character = OverwatchCharacter.Widowmaker, Color = Color.FromRgb(65, 12, 70)},
+ new CharacterColor {Character = OverwatchCharacter.Dva, Color = Color.FromRgb(248, 48, 129)},
+ new CharacterColor {Character = OverwatchCharacter.Reinhardt, Color = Color.FromRgb(51, 65, 66)},
+ new CharacterColor {Character = OverwatchCharacter.Roadhog, Color = Color.FromRgb(107, 40, 2)},
+ new CharacterColor {Character = OverwatchCharacter.Winston, Color = Color.FromRgb(70, 73, 107)},
+ new CharacterColor {Character = OverwatchCharacter.Zarya, Color = Color.FromRgb(235, 28, 97)},
+ 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)}
};
}
- public override void Dispose()
- {
- Initialized = false;
- }
-
public override void Enable()
{
+ _stickyStatus = new StickyValue(300);
+ _stickyUltimateReady = new StickyValue(350);
+ _stickyUltimateUsed = new StickyValue(350);
Initialized = true;
}
+ public override void Dispose()
+ {
+ _stickyStatus.Dispose();
+ _stickyUltimateReady.Dispose();
+ _stickyUltimateUsed.Dispose();
+ Initialized = false;
+ }
+
public override void Update()
+ {
+ UpdateOverwatch();
+ ApplyStickyValues();
+ }
+
+ private void ApplyStickyValues()
+ {
+ var gameDataModel = (OverwatchDataModel) DataModel;
+ gameDataModel.Status = _stickyStatus.Value;
+ gameDataModel.UltimateReady = _stickyUltimateReady.Value;
+ gameDataModel.UltimateUsed = _stickyUltimateUsed.Value;
+ }
+
+ public void UpdateOverwatch()
{
var gameDataModel = (OverwatchDataModel) DataModel;
var colors = MmfReader.GetColorArray();
if (colors == null)
return;
- var bitmap = new Bitmap(22, 6);
-
- using (var g = Graphics.FromImage(bitmap))
- {
- for (var y = 0; y < 6; y++)
- {
- for (var x = 0; x < 22; x++)
- {
- g.DrawRectangle(new Pen(ColorHelpers.ToDrawingColor(colors[y, x])), y, x, 1, 1);
- }
- }
- }
- _events.PublishOnUIThread(new ChangeBitmap(bitmap));
+ _events.PublishOnUIThread(new RazerColorArrayChanged(colors));
+ //MainManager.Logger.Trace("DataModel: \r\n{0}",
+ // JsonConvert.SerializeObject(gameDataModel, Formatting.Indented));
// Determine general game state
- gameDataModel.Status = colors[0, 0].Equals(Color.FromRgb(55, 30, 0))
- ? OverwatchStatus.InMainMenu
- : OverwatchStatus.Unkown;
+ ParseGameSate(gameDataModel, colors);
- if (gameDataModel.Status == OverwatchStatus.InMainMenu)
+ // Parse the lighting
+ var characterMatch = ParseCharacter(gameDataModel, colors);
+
+ // Ult can't possibly be ready within 2 seconds of changing, this avoids false positives.
+ // Filtering on ultReady and ultUsed removes false positives from the native ultimate effects
+ // The control keys don't show during character select, so don't continue on those either.
+ if (_characterChange.AddSeconds(2) >= DateTime.Now ||
+ _ultimateUsed.AddSeconds(2) >= DateTime.Now ||
+ _ultimateReady.AddSeconds(2) >= DateTime.Now ||
+ _stickyStatus.Value == OverwatchStatus.InCharacterSelect)
return;
- // If ingame, look for a character
- var characterMatch = OverwatchCharacters.FirstOrDefault(c => c.Color == colors[0, 0]);
- if (characterMatch.OverwatchCharacter == OverwatchCharacter.None)
+ ParseSpecialKeys(gameDataModel, characterMatch, colors);
+ ParseAbilities(gameDataModel, colors);
+ }
+
+ private void ParseGameSate(OverwatchDataModel gameDataModel, Color[,] colors)
+ {
+ if (_ultimateUsed.AddSeconds(5) >= DateTime.Now)
return;
- gameDataModel.Status = OverwatchStatus.InGame;
- gameDataModel.Character = characterMatch.OverwatchCharacter;
+ if (colors[0, 0].Equals(Color.FromRgb(55, 30, 0)))
+ _stickyStatus.Value = OverwatchStatus.InMainMenu;
+
+ if (_stickyStatus.Value != OverwatchStatus.InMainMenu)
+ return;
+
+ gameDataModel.Character = OverwatchCharacter.None;
+ gameDataModel.Ability1Ready = false;
+ gameDataModel.Ability2Ready = false;
+ _stickyUltimateReady.Value = false;
+ _stickyUltimateUsed.Value = false;
+ }
+
+ private CharacterColor? ParseCharacter(OverwatchDataModel gameDataModel, Color[,] colors)
+ {
+ var characterMatch = OverwatchCharacters.FirstOrDefault(c => c.Color == colors[0, 20]);
+ // If a new character was chosen, let the other methods know
+ if (characterMatch.Character != gameDataModel.Character)
+ _characterChange = DateTime.Now;
+
+ // If no character was found, this method shouldn't continue
+ if (characterMatch.Character == OverwatchCharacter.None)
+ return characterMatch;
+
+ // If WASD isn't orange (any of them will do), player is in character select
+ _stickyStatus.Value = ControlsShown(colors) ? OverwatchStatus.InGame : OverwatchStatus.InCharacterSelect;
+
+ // Update the datamodel
+ gameDataModel.Character = characterMatch.Character;
+ return characterMatch;
+ }
+
+ private bool ControlsShown(Color[,] colors)
+ {
+ var keyColor = Color.FromRgb(222, 153, 0);
+ return colors[2, 3] == keyColor || colors[3, 2] == keyColor ||
+ colors[3, 3] == keyColor || colors[3, 4] == keyColor;
+ }
+
+ private void ParseSpecialKeys(OverwatchDataModel gameDataModel, CharacterColor? characterMatch, Color[,] colors)
+ {
+ if (characterMatch == null || characterMatch.Value.Character == OverwatchCharacter.None)
+ return;
- // Ability1 is ready when LShift is lid
- gameDataModel.Ability1Ready = colors[4, 1].Equals(Color.FromRgb(4, 141, 144));
- // Ability2 is ready when E is lid
- gameDataModel.Ability2Ready = colors[2, 4].Equals(Color.FromRgb(4, 141, 144));
// Ultimate is ready when Q is blinking
- gameDataModel.UltimateReady = !characterMatch.Color.Equals(colors[2, 2]);
+ var charCol = characterMatch.Value.Color;
+ var backlidColor = Color.FromRgb((byte) (charCol.R*0.25), (byte) (charCol.G*0.25), (byte) (charCol.B*0.25));
+ var ultReady = !backlidColor.Equals(colors[2, 2]);
+
+ if (_ultimateUsed.AddSeconds(15) <= DateTime.Now)
+ {
+ // Player can change hero if H is blinking
+ gameDataModel.CanChangeHero = !colors[3, 7].Equals(backlidColor);
+
+ if (!_stickyUltimateReady.Value && ultReady && ControlsShown(colors))
+ {
+ _ultimateReady = DateTime.Now;
+ _stickyUltimateReady.Value = true;
+ }
+ }
+
+ // If ult no longer ready but it was ready before, it was used.
+ if (_stickyUltimateReady.Value && !ultReady)
+ {
+ _stickyUltimateReady.Value = false;
+ if (_ultimateUsed.AddSeconds(15) <= DateTime.Now)
+ _ultimateUsed = DateTime.Now;
+ }
+
+ // UltimateUsed is true for 10 seconds after ultimate went on cooldown
+ if (_ultimateUsed != DateTime.MinValue)
+ _stickyUltimateUsed.Value = _ultimateUsed.AddSeconds(10) >= DateTime.Now;
+ }
+
+ private void ParseAbilities(OverwatchDataModel gameDataModel, Color[,] colors)
+ {
+ gameDataModel.Ability1Ready = colors[4, 1].Equals(Color.FromRgb(4, 141, 144));
+ gameDataModel.Ability2Ready = colors[2, 4].Equals(Color.FromRgb(4, 141, 144));
}
public override List GetRenderLayers(bool renderMice, bool renderHeadsets)
{
- return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
+ return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
}
}
public struct CharacterColor
{
- public OverwatchCharacter OverwatchCharacter { get; set; }
+ public OverwatchCharacter Character { get; set; }
public Color Color { get; set; }
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs
index 4b93dc620..8d5aa782b 100644
--- a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs
+++ b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs
@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using Artemis.Managers;
using Artemis.Models;
-using Artemis.Models.Profiles;
+using Artemis.Profiles.Layers.Models;
using Artemis.Settings;
using Artemis.Utilities;
using Artemis.Utilities.Memory;
@@ -66,11 +66,20 @@ namespace Artemis.Modules.Games.RocketLeague
((RocketLeagueDataModel) DataModel).Boost = 0;
if (((RocketLeagueDataModel) DataModel).Boost > 100)
((RocketLeagueDataModel) DataModel).Boost = 100;
+
+ if (DateTime.Now.AddSeconds(-2) <= LastTrace)
+ return;
+
+ MainManager.Logger.Trace("Offsets as JSON: \r\n{0}",
+ JsonConvert.SerializeObject(_pointer.GameAddresses, Formatting.Indented));
+ MainManager.Logger.Trace("RL specific offsets: {0}", offsets);
+ MainManager.Logger.Trace("Boost address: {0}", boostAddress);
+ MainManager.Logger.Trace("Boost float: {0}", boostFloat);
}
public override List GetRenderLayers(bool renderMice, bool renderHeadsets)
{
- return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
+ return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs
index 8087cb468..d7c683626 100644
--- a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs
+++ b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs
@@ -3,7 +3,7 @@ using System.Threading;
using System.Threading.Tasks;
using Artemis.Managers;
using Artemis.Models;
-using Artemis.Models.Profiles;
+using Artemis.Profiles.Layers.Models;
using Artemis.Utilities;
using Artemis.Utilities.LogitechDll;
@@ -131,7 +131,7 @@ namespace Artemis.Modules.Games.TheDivision
public override List GetRenderLayers(bool renderMice, bool renderHeadsets)
{
- return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
+ return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs
index a61da7526..3de8ee80f 100644
--- a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs
+++ b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs
@@ -1,20 +1,19 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Artemis.Managers;
using Artemis.Models;
-using Artemis.Models.Profiles;
+using Artemis.Profiles.Layers.Models;
namespace Artemis.Modules.Games.Witcher3
{
public class Witcher3Model : GameModel
{
- private readonly Stopwatch _updateSw;
private readonly Regex _configRegex;
+ private readonly Stopwatch _updateSw;
private string _witcherSettings;
public Witcher3Model(MainManager mainManager, Witcher3Settings settings)
@@ -139,7 +138,7 @@ namespace Artemis.Modules.Games.Witcher3
public override List GetRenderLayers(bool renderMice, bool renderHeadsets)
{
- return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
+ return Profile.GetRenderLayers(DataModel, renderMice, renderHeadsets);
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs
index 7a2af183c..435fa4d0a 100644
--- a/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs
+++ b/Artemis/Artemis/Modules/Overlays/VolumeDisplay/VolumeDisplayModel.cs
@@ -4,9 +4,8 @@ using System.Runtime.InteropServices;
using System.Windows.Forms;
using Artemis.Managers;
using Artemis.Models;
-using Artemis.Models.Profiles;
+using Artemis.Profiles.Layers.Models;
using NAudio.CoreAudioApi;
-using Brush = System.Windows.Media.Brush;
namespace Artemis.Modules.Overlays.VolumeDisplay
{
@@ -46,10 +45,10 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
if (VolumeDisplay.Ttl < 1)
return;
- var decreaseAmount = 500 / fps;
+ var decreaseAmount = 500/fps;
VolumeDisplay.Ttl = VolumeDisplay.Ttl - decreaseAmount;
if (VolumeDisplay.Ttl < 128)
- VolumeDisplay.Transparancy = (byte)(VolumeDisplay.Transparancy - 20);
+ VolumeDisplay.Transparancy = (byte) (VolumeDisplay.Transparancy - 20);
try
{
@@ -57,7 +56,7 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
var volumeFloat =
enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Console)
.AudioEndpointVolume.MasterVolumeLevelScalar;
- VolumeDisplay.Volume = (int)(volumeFloat * 100);
+ VolumeDisplay.Volume = (int) (volumeFloat*100);
}
catch (COMException)
{
@@ -78,11 +77,16 @@ namespace Artemis.Modules.Overlays.VolumeDisplay
VolumeDisplay.Transparancy = 255;
}
- public override void RenderOverlay(Graphics keyboard, ref Brush mouse, ref Brush headset, bool renderMice,
+ public override void RenderOverlay(Bitmap keyboard, ref Bitmap mouse, ref Bitmap headset, bool renderMice,
bool renderHeadsets)
{
- if (MainManager.DeviceManager.ActiveKeyboard != null && VolumeDisplay != null && VolumeDisplay.Ttl >= 1)
- VolumeDisplay.Draw(keyboard);
+ if (MainManager.DeviceManager.ActiveKeyboard == null || VolumeDisplay == null || VolumeDisplay.Ttl < 1)
+ return;
+
+ using (var g = Graphics.FromImage(keyboard))
+ {
+ VolumeDisplay.Draw(g);
+ }
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Animations/GrowAnimation.cs b/Artemis/Artemis/Profiles/Layers/Animations/GrowAnimation.cs
new file mode 100644
index 000000000..da70c3808
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Animations/GrowAnimation.cs
@@ -0,0 +1,61 @@
+using System.Windows;
+using System.Windows.Media;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Animations
+{
+ public class GrowAnimation : ILayerAnimation
+ {
+ public string Name { get; } = "Grow";
+
+ public void Update(LayerModel layerModel, bool updateAnimations)
+ {
+ var progress = layerModel.Properties.AnimationProgress;
+
+ if (MustExpire(layerModel))
+ progress = 0;
+ progress = progress + layerModel.Properties.AnimationSpeed/2.5;
+
+ // If not previewing, store the animation progress in the actual model for the next frame
+ if (updateAnimations)
+ layerModel.Properties.AnimationProgress = progress;
+ }
+
+ public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c)
+ {
+ if (applied.Brush == null)
+ return;
+
+ const int scale = 4;
+ // Set up variables for this frame
+ var rect = props.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 clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale);
+
+ // Take an offset of 4 to allow layers to slightly leave their bounds
+ var progress = (6.0 - props.AnimationProgress)*10.0;
+ if (progress < 0)
+ {
+ // Can't meddle with the original brush because it's frozen.
+ var brush = applied.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;
+ }
+ 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.Pop();
+ }
+
+ public bool MustExpire(LayerModel layer) => layer.Properties.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
new file mode 100644
index 000000000..3bbe7d9d1
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Animations/NoneAnimation.cs
@@ -0,0 +1,24 @@
+using System.Windows.Media;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Animations
+{
+ public class NoneAnimation : ILayerAnimation
+ {
+ public string Name { get; } = "None";
+
+ public void Update(LayerModel layerModel, bool updateAnimations)
+ {
+ }
+
+ public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c)
+ {
+ }
+
+ public bool MustExpire(LayerModel layer)
+ {
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs b/Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs
new file mode 100644
index 000000000..0d5e34253
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Windows;
+using System.Windows.Media;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Animations
+{
+ public class PulseAnimation : ILayerAnimation
+ {
+ public string Name { get; } = "Pulse";
+
+ public void Update(LayerModel layerModel, bool updateAnimations)
+ {
+ var progress = layerModel.Properties.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;
+ }
+
+ public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c)
+ {
+ if (applied.Brush == null)
+ return;
+
+ const int scale = 4;
+ // Set up variables for this frame
+ var rect = props.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 clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale);
+
+ // 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;
+
+ c.PushClip(new RectangleGeometry(clip));
+ c.DrawRectangle(applied.Brush, null, rect);
+ c.Pop();
+ }
+
+ public bool MustExpire(LayerModel layer) => layer.Properties.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
new file mode 100644
index 000000000..e25af27df
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Animations/SlideDownAnimation.cs
@@ -0,0 +1,51 @@
+using System.Windows;
+using System.Windows.Media;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Animations
+{
+ public class SlideDownAnimation : ILayerAnimation
+ {
+ public string Name { get; } = "Slide down";
+
+ public void Update(LayerModel layerModel, bool updateAnimations)
+ {
+ var progress = layerModel.Properties.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;
+ }
+
+ public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c)
+ {
+ if (applied.Brush == null)
+ return;
+
+ const int scale = 4;
+ // Set up variables for this frame
+ var rect = props.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 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));
+
+ var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale);
+
+ c.PushClip(new RectangleGeometry(clip));
+ c.DrawRectangle(applied.Brush, null, s1);
+ c.DrawRectangle(applied.Brush, null, s2);
+ c.Pop();
+ }
+
+ public bool MustExpire(LayerModel layer)
+ {
+ return layer.Properties.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
new file mode 100644
index 000000000..ff277c1a9
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Animations/SlideLeftAnimation.cs
@@ -0,0 +1,52 @@
+using System.Windows;
+using System.Windows.Media;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Animations
+{
+ public class SlideLeftAnimation : ILayerAnimation
+ {
+ public string Name { get; } = "Slide left";
+
+ public void Update(LayerModel layerModel, bool updateAnimations)
+ {
+ var progress = layerModel.Properties.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;
+ }
+
+ public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c)
+ {
+ if (applied.Brush == null)
+ return;
+
+ const int scale = 4;
+ // Set up variables for this frame
+ var rect = props.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 s1 = new Rect(new Point(rect.X - props.AnimationProgress, rect.Y),
+ new Size(rect.Width + 0.05, 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);
+
+ c.PushClip(new RectangleGeometry(clip));
+ c.DrawRectangle(applied.Brush, null, s1);
+ c.DrawRectangle(applied.Brush, null, s2);
+ c.Pop();
+ }
+
+ public bool MustExpire(LayerModel layer)
+ {
+ return layer.Properties.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
new file mode 100644
index 000000000..88b02828b
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Animations/SlideRightAnimation.cs
@@ -0,0 +1,51 @@
+using System.Windows;
+using System.Windows.Media;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Animations
+{
+ public class SlideRightAnimation : ILayerAnimation
+ {
+ public string Name { get; } = "Slide right";
+
+ public void Update(LayerModel layerModel, bool updateAnimations)
+ {
+ var progress = layerModel.Properties.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;
+ }
+
+ public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c)
+ {
+ if (applied.Brush == null)
+ return;
+
+ const int scale = 4;
+ // Set up variables for this frame
+ var rect = props.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 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 + 1, rect.Height));
+
+ var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale);
+
+ c.PushClip(new RectangleGeometry(clip));
+ c.DrawRectangle(applied.Brush, null, s1);
+ c.DrawRectangle(applied.Brush, null, s2);
+ c.Pop();
+ }
+
+ public bool MustExpire(LayerModel layer)
+ {
+ return layer.Properties.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
new file mode 100644
index 000000000..05c2f8b6c
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Animations/SlideUpAnimation.cs
@@ -0,0 +1,51 @@
+using System.Windows;
+using System.Windows.Media;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Animations
+{
+ public class SlideUpAnimation : ILayerAnimation
+ {
+ public string Name { get; } = "Slide up";
+
+ public void Update(LayerModel layerModel, bool updateAnimations)
+ {
+ var progress = layerModel.Properties.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;
+ }
+
+ public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c)
+ {
+ if (applied.Brush == null)
+ return;
+
+ const int scale = 4;
+ // Set up variables for this frame
+ var rect = props.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 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));
+
+ var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale);
+
+ c.PushClip(new RectangleGeometry(clip));
+ c.DrawRectangle(applied.Brush, null, s1);
+ c.DrawRectangle(applied.Brush, null, s2);
+ c.Pop();
+ }
+
+ public bool MustExpire(LayerModel layer)
+ {
+ return layer.Properties.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
new file mode 100644
index 000000000..aba92d32f
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs
@@ -0,0 +1,15 @@
+using System.Linq;
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Conditions
+{
+ public class DataModelCondition : ILayerCondition
+ {
+ public bool ConditionsMet(LayerModel layer, IDataModel dataModel)
+ {
+ return layer.Properties.Conditions.All(cm => cm.ConditionMet(dataModel));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs b/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs
new file mode 100644
index 000000000..5a7adc7d0
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs
@@ -0,0 +1,21 @@
+using System.Linq;
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Conditions
+{
+ public class EventCondition : ILayerCondition
+ {
+ public bool ConditionsMet(LayerModel layer, IDataModel dataModel)
+ {
+ var conditionsMet = layer.Properties.Conditions.All(cm => cm.ConditionMet(dataModel));
+ layer.EventProperties.Update(layer, conditionsMet);
+
+ if (conditionsMet && layer.EventProperties.MustTrigger)
+ layer.EventProperties.TriggerEvent(layer);
+
+ return conditionsMet && layer.EventProperties.MustDraw;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerAnimation.cs b/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerAnimation.cs
new file mode 100644
index 000000000..c0df0f6a4
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerAnimation.cs
@@ -0,0 +1,13 @@
+using System.Windows.Media;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Interfaces
+{
+ public interface ILayerAnimation
+ {
+ string Name { get; }
+ void Update(LayerModel layerModel, bool updateAnimations);
+ void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c);
+ bool MustExpire(LayerModel layer);
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerCondition.cs b/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerCondition.cs
new file mode 100644
index 000000000..56588ad8d
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerCondition.cs
@@ -0,0 +1,10 @@
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Interfaces
+{
+ public interface ILayerCondition
+ {
+ bool ConditionsMet(LayerModel layer, 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
new file mode 100644
index 000000000..e83eb6382
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerType.cs
@@ -0,0 +1,57 @@
+using System.Collections.Generic;
+using System.Windows.Media;
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Models;
+using Artemis.ViewModels.Profiles.Layers;
+
+namespace Artemis.Profiles.Layers.Interfaces
+{
+ public interface ILayerType
+ {
+ ///
+ /// Layer type name
+ ///
+ string Name { get; }
+
+ ///
+ /// Gets whether this type must be drawn on the keyboard/the editor or not
+ ///
+ bool MustDraw { get; }
+
+ ///
+ /// The the thumbnail for this layer type
+ ///
+ /// The layer to draw the thumbnail for
+ ImageSource DrawThumbnail(LayerModel layer);
+
+ ///
+ /// Draws the layer
+ ///
+ /// The layer to draw
+ /// The drawing context to draw with
+ void Draw(LayerModel layer, DrawingContext c);
+
+ ///
+ /// Updates the provided layer layerModel according to this type
+ ///
+ /// The layerModel to apply to
+ /// The datamodel to base the layer on
+ /// Set to true if previewing this layer
+ void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false);
+
+ ///
+ /// Sets up the layer's properties to accommodate this layerType
+ ///
+ ///
+ void SetupProperties(LayerModel layerModel);
+
+ ///
+ /// Sets up a viewmodel to accomodate this layerType
+ ///
+ /// The current viewmodel
+ ///
+ /// The datamodel to use in the new viewmodel
+ /// The layer to use in the new viewmodel
+ LayerPropertiesViewModel SetupViewModel(LayerPropertiesViewModel layerPropertiesViewModel, List layerAnimations, IDataModel dataModel, LayerModel proposedLayer);
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Models/Profiles/Properties/DynamicPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Models/DynamicPropertiesModel.cs
similarity index 76%
rename from Artemis/Artemis/Models/Profiles/Properties/DynamicPropertiesModel.cs
rename to Artemis/Artemis/Profiles/Layers/Models/DynamicPropertiesModel.cs
index 8c3956744..7c05955d3 100644
--- a/Artemis/Artemis/Models/Profiles/Properties/DynamicPropertiesModel.cs
+++ b/Artemis/Artemis/Profiles/Layers/Models/DynamicPropertiesModel.cs
@@ -1,9 +1,8 @@
using System.ComponentModel;
using Artemis.Models.Interfaces;
using Artemis.Utilities;
-using static System.Decimal;
-namespace Artemis.Models.Profiles.Properties
+namespace Artemis.Profiles.Layers.Models
{
public class DynamicPropertiesModel
{
@@ -37,31 +36,31 @@ namespace Artemis.Models.Profiles.Properties
///
public LayerPropertyOptions LayerPropertyOptions { get; set; }
- internal void ApplyProperty(IDataModel dataModel, ref AppliedProperties properties)
+ internal void ApplyProperty(IDataModel dataModel, LayerPropertiesModel properties)
{
if (LayerPropertyType == LayerPropertyType.PercentageOf)
- ApplyPercentageOf(dataModel, ref properties, PercentageSource);
+ ApplyPercentageOf(dataModel, properties, PercentageSource);
if (LayerPropertyType == LayerPropertyType.PercentageOfProperty)
- ApplyPercentageOfProperty(dataModel, ref properties);
+ ApplyPercentageOfProperty(dataModel, properties);
}
- private void ApplyPercentageOf(IDataModel dataModel, ref AppliedProperties properties, double src)
+ private void ApplyPercentageOf(IDataModel dataModel, LayerPropertiesModel properties, double src)
{
if (GameProperty == null)
return;
var gameProperty = dataModel.GetPropValue(GameProperty);
- var percentage = ToDouble(gameProperty)/src;
+ var percentage = decimal.ToDouble(gameProperty)/src;
if (LayerProperty == "Width")
- ApplyWidth(ref properties, percentage);
+ ApplyWidth(properties, percentage);
else if (LayerProperty == "Height")
- ApplyHeight(ref properties, percentage);
+ ApplyHeight(properties, percentage);
else if (LayerProperty == "Opacity")
- ApplyOpacity(ref properties, percentage);
+ ApplyOpacity(properties, percentage);
}
- private void ApplyWidth(ref AppliedProperties properties, double percentage)
+ private void ApplyWidth(LayerPropertiesModel properties, double percentage)
{
var newWidth = percentage*properties.Width;
var difference = properties.Width - newWidth;
@@ -72,7 +71,7 @@ namespace Artemis.Models.Profiles.Properties
properties.X = properties.X + difference;
}
- private void ApplyHeight(ref AppliedProperties properties, double percentage)
+ private void ApplyHeight(LayerPropertiesModel properties, double percentage)
{
var newHeight = percentage*properties.Height;
var difference = properties.Height - newHeight;
@@ -82,7 +81,7 @@ namespace Artemis.Models.Profiles.Properties
properties.Y = properties.Y + difference;
}
- private void ApplyOpacity(ref AppliedProperties properties, double percentage)
+ private void ApplyOpacity(LayerPropertiesModel properties, double percentage)
{
properties.Opacity = percentage*properties.Opacity;
if (properties.Opacity < 0.0)
@@ -93,12 +92,16 @@ namespace Artemis.Models.Profiles.Properties
// Apply the inverse/decrease option
if (LayerPropertyOptions == LayerPropertyOptions.Decrease)
properties.Opacity = 1.0 - properties.Opacity;
+
+ var brush = properties.Brush.Clone();
+ brush.Opacity = properties.Opacity;
+ properties.Brush = brush;
}
- private void ApplyPercentageOfProperty(IDataModel dataModel, ref AppliedProperties properties)
+ private void ApplyPercentageOfProperty(IDataModel dataModel, LayerPropertiesModel properties)
{
var value = dataModel.GetPropValue(PercentageProperty);
- ApplyPercentageOf(dataModel, ref properties, value);
+ ApplyPercentageOf(dataModel, properties, value);
}
}
diff --git a/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs
new file mode 100644
index 000000000..8acd950da
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs
@@ -0,0 +1,49 @@
+using System;
+using Newtonsoft.Json;
+
+namespace Artemis.Profiles.Layers.Models
+{
+ public abstract class EventPropertiesModel
+ {
+ public ExpirationType ExpirationType { get; set; }
+ public TimeSpan Length { get; set; }
+ public TimeSpan TriggerDelay { get; set; }
+
+ [JsonIgnore]
+ public bool MustTrigger { get; set; }
+
+ [JsonIgnore]
+ public DateTime AnimationStart { get; set; }
+
+ [JsonIgnore]
+ public bool MustDraw { get; set; }
+
+ ///
+ /// Resets the event's properties and triggers it
+ ///
+ public abstract void TriggerEvent(LayerModel layer);
+
+ ///
+ /// Gets whether the event should stop
+ ///
+ ///
+ ///
+ public abstract bool MustStop(LayerModel layer);
+
+ // Called every frame, if parent conditions met.
+ public void Update(LayerModel layerModel, bool conditionsMet)
+ {
+ if (MustStop(layerModel))
+ MustDraw = false;
+
+ if (!conditionsMet)
+ MustTrigger = true;
+ }
+ }
+
+ public enum ExpirationType
+ {
+ Time,
+ Animation
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Models/KeyboardEventPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Models/KeyboardEventPropertiesModel.cs
new file mode 100644
index 000000000..ce0cb8bd2
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Models/KeyboardEventPropertiesModel.cs
@@ -0,0 +1,47 @@
+using System;
+using Artemis.Profiles.Layers.Types.Keyboard;
+using Artemis.Profiles.Layers.Types.KeyboardGif;
+
+namespace Artemis.Profiles.Layers.Models
+{
+ public class KeyboardEventPropertiesModel : EventPropertiesModel
+ {
+ public override void TriggerEvent(LayerModel layer)
+ {
+ var keyboardProperties = layer.Properties as KeyboardPropertiesModel;
+ if (keyboardProperties == null)
+ throw new ArgumentException("Layer's properties cannot be null " +
+ "and must be of type KeyboardPropertiesModel");
+ if (!MustTrigger)
+ return;
+
+ MustTrigger = false;
+ MustDraw = true;
+ keyboardProperties.AnimationProgress = 0.0;
+ if (layer.GifImage != null)
+ layer.GifImage.CurrentFrame = 0;
+ }
+
+ public override bool MustStop(LayerModel layer)
+ {
+ var keyboardProperties = layer.Properties as KeyboardPropertiesModel;
+ if (keyboardProperties == null)
+ throw new ArgumentException("Layer's properties cannot be null " +
+ "and must be of type KeyboardPropertiesModel");
+
+ switch (ExpirationType)
+ {
+ case ExpirationType.Time:
+ if (AnimationStart == DateTime.MinValue)
+ return false;
+ return DateTime.Now - Length > AnimationStart;
+ case ExpirationType.Animation:
+ if (layer.LayerType is KeyboardGifType)
+ return layer.GifImage?.CurrentFrame >= layer.GifImage?.FrameCount - 1;
+ return layer.LayerAnimation == null || layer.LayerAnimation.MustExpire(layer);
+ default:
+ return true;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Models/Profiles/LayerConditionModel.cs b/Artemis/Artemis/Profiles/Layers/Models/LayerConditionModel.cs
similarity index 85%
rename from Artemis/Artemis/Models/Profiles/LayerConditionModel.cs
rename to Artemis/Artemis/Profiles/Layers/Models/LayerConditionModel.cs
index cc8f723dd..3e93af114 100644
--- a/Artemis/Artemis/Models/Profiles/LayerConditionModel.cs
+++ b/Artemis/Artemis/Profiles/Layers/Models/LayerConditionModel.cs
@@ -1,58 +1,58 @@
-using System;
-using Artemis.Models.Interfaces;
-using Artemis.Utilities;
-using DynamicExpresso;
-
-namespace Artemis.Models.Profiles
-{
- public class LayerConditionModel
- {
- private readonly Interpreter _interpreter;
-
- public LayerConditionModel()
- {
- _interpreter = new Interpreter();
- }
-
- public string Field { get; set; }
- public string Value { get; set; }
- public string Operator { get; set; }
- public string Type { get; set; }
-
- public bool ConditionMet(IDataModel subject)
- {
- if (string.IsNullOrEmpty(Field) || string.IsNullOrEmpty(Value) || string.IsNullOrEmpty(Type))
- return false;
-
- var inspect = GeneralHelpers.GetPropertyValue(subject, Field);
- if (inspect == null)
- return false;
-
- // Put the subject in a list, allowing Dynamic Linq to be used.
- if (Type == "String")
- {
- return _interpreter.Eval($"subject.{Field}.ToLower() {Operator} value",
- new Parameter("subject", typeof(T), subject),
- new Parameter("value", Value.ToLower()));
- }
-
- Parameter rightParam = null;
- switch (Type)
- {
- case "Enum":
- var enumType = GeneralHelpers.GetPropertyValue(subject, Field).GetType();
- rightParam = new Parameter("value", Enum.Parse(enumType, Value));
- break;
- case "Boolean":
- rightParam = new Parameter("value", bool.Parse(Value));
- break;
- case "Int32":
- rightParam = new Parameter("value", int.Parse(Value));
- break;
- }
-
- return _interpreter.Eval($"subject.{Field} {Operator} value",
- new Parameter("subject", typeof(T), subject), rightParam);
- }
- }
+using System;
+using Artemis.Models.Interfaces;
+using Artemis.Utilities;
+using DynamicExpresso;
+
+namespace Artemis.Profiles.Layers.Models
+{
+ public class LayerConditionModel
+ {
+ private readonly Interpreter _interpreter;
+
+ public LayerConditionModel()
+ {
+ _interpreter = new Interpreter();
+ }
+
+ public string Field { get; set; }
+ public string Value { get; set; }
+ public string Operator { get; set; }
+ public string Type { get; set; }
+
+ public bool ConditionMet(IDataModel subject)
+ {
+ if (string.IsNullOrEmpty(Field) || string.IsNullOrEmpty(Value) || string.IsNullOrEmpty(Type))
+ return false;
+
+ var inspect = GeneralHelpers.GetPropertyValue(subject, Field);
+ if (inspect == null)
+ return false;
+
+ // Put the subject in a list, allowing Dynamic Linq to be used.
+ if (Type == "String")
+ {
+ return _interpreter.Eval($"subject.{Field}.ToLower() {Operator} value",
+ new Parameter("subject", subject.GetType(), subject),
+ new Parameter("value", Value.ToLower()));
+ }
+
+ Parameter rightParam = null;
+ switch (Type)
+ {
+ case "Enum":
+ var enumType = GeneralHelpers.GetPropertyValue(subject, Field).GetType();
+ rightParam = new Parameter("value", Enum.Parse(enumType, Value));
+ break;
+ case "Boolean":
+ rightParam = new Parameter("value", bool.Parse(Value));
+ break;
+ case "Int32":
+ rightParam = new Parameter("value", int.Parse(Value));
+ break;
+ }
+
+ return _interpreter.Eval($"subject.{Field} {Operator} value",
+ new Parameter("subject", subject.GetType(), subject), rightParam);
+ }
+ }
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Models/Profiles/LayerModel.cs b/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs
similarity index 50%
rename from Artemis/Artemis/Models/Profiles/LayerModel.cs
rename to Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs
index 2b8d647ae..5c2cf057e 100644
--- a/Artemis/Artemis/Models/Profiles/LayerModel.cs
+++ b/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs
@@ -1,276 +1,259 @@
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Windows.Media;
-using System.Xml.Serialization;
-using Artemis.Models.Interfaces;
-using Artemis.Models.Profiles.Properties;
-using Artemis.Utilities;
-using Artemis.Utilities.Layers;
-using Artemis.Utilities.ParentChild;
-
-namespace Artemis.Models.Profiles
-{
- public class LayerModel : IChildItem, IChildItem
- {
- public LayerModel()
- {
- Children = new ChildItemCollection(this);
- }
-
- public string Name { get; set; }
- public int Order { get; set; }
- public LayerType LayerType { get; set; }
- public bool Enabled { get; set; }
- public bool Expanded { get; set; }
- public LayerPropertiesModel Properties { get; set; }
- public ChildItemCollection Children { get; }
-
- [XmlIgnore]
- public ImageSource LayerImage => Drawer.DrawThumbnail(this);
-
- [XmlIgnore]
- public LayerModel Parent { get; internal set; }
-
- [XmlIgnore]
- public ProfileModel Profile { get; internal set; }
-
- [XmlIgnore]
- public GifImage GifImage { get; set; }
-
- public bool ConditionsMet(IDataModel dataModel)
- {
- return Enabled && Properties.Conditions.All(cm => cm.ConditionMet(dataModel));
- }
-
- public void Draw(IDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations)
- {
- if (LayerType != LayerType.Keyboard && LayerType != LayerType.KeyboardGif)
- return;
-
- // Preview simply shows the properties as they are. When not previewing they are applied
- var appliedProperties = !preview
- ? Properties.GetAppliedProperties(dataModel)
- : Properties.GetAppliedProperties(dataModel, true);
-
- // Update animations
- AnimationUpdater.UpdateAnimation((KeyboardPropertiesModel) Properties, updateAnimations);
-
- if (LayerType == LayerType.Keyboard)
- Drawer.Draw(c, (KeyboardPropertiesModel) Properties, appliedProperties);
- else if (LayerType == LayerType.KeyboardGif)
- GifImage = Drawer.DrawGif(c, (KeyboardPropertiesModel) Properties, appliedProperties, GifImage);
- }
-
- public Brush GenerateBrush(LayerType type, IDataModel dataModel, bool preview, bool updateAnimations)
- {
- if (!Enabled)
- return null;
- if (LayerType != LayerType.Folder && LayerType != type)
- return null;
-
- // Preview simply shows the properties as they are. When not previewing they are applied
- AppliedProperties appliedProperties;
- if (!preview)
- {
- if (!ConditionsMet(dataModel))
- return null; // Return null when not previewing and the conditions arent met
- appliedProperties = Properties.GetAppliedProperties(dataModel);
- }
- else
- appliedProperties = Properties.GetAppliedProperties(dataModel, true);
-
- // TODO: Mouse/headset animations
-
- if (LayerType != LayerType.Folder)
- return appliedProperties.Brush;
-
- Brush res = null;
- foreach (var layerModel in Children.OrderByDescending(l => l.Order))
- {
- var brush = layerModel.GenerateBrush(type, dataModel, preview, updateAnimations);
- if (brush != null)
- res = brush;
- }
- return res;
- }
-
- public void SetupProperties()
- {
- if ((LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif) &&
- !(Properties is KeyboardPropertiesModel))
- {
- Properties = new KeyboardPropertiesModel
- {
- Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()),
- Animation = LayerAnimation.None,
- Height = 1,
- Width = 1,
- X = 0,
- Y = 0,
- Opacity = 1
- };
- }
- else if (LayerType == LayerType.Mouse && !(Properties is MousePropertiesModel))
- Properties = new MousePropertiesModel
- {
- Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor())
- };
- else if (LayerType == LayerType.Headset && !(Properties is HeadsetPropertiesModel))
- Properties = new HeadsetPropertiesModel
- {
- Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor())
- };
- }
-
- public void FixOrder()
- {
- Children.Sort(l => l.Order);
- for (var i = 0; i < Children.Count; i++)
- Children[i].Order = i;
- }
-
- ///
- /// Returns whether the layer meets the requirements to be drawn
- ///
- ///
- public bool MustDraw()
- {
- // If any of the parents are disabled, this layer must not be drawn
- var parent = Parent;
- while (parent != null)
- {
- if (!parent.Enabled)
- return false;
- parent = parent.Parent;
- }
- return Enabled && (LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif);
- }
-
- public IEnumerable GetLayers()
- {
- var layers = new List();
- foreach (var layerModel in Children)
- {
- layers.Add(layerModel);
- layers.AddRange(layerModel.GetLayers());
- }
-
- return layers;
- }
-
- public static LayerModel CreateLayer()
- {
- return new LayerModel
- {
- Name = "New layer",
- Enabled = true,
- Order = -1,
- LayerType = LayerType.Keyboard,
- Properties = new KeyboardPropertiesModel
- {
- Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()),
- Animation = LayerAnimation.None,
- Height = 1,
- Width = 1,
- X = 0,
- Y = 0,
- Opacity = 1
- }
- };
- }
-
- public void InsertBefore(LayerModel source)
- {
- source.Order = Order;
- Insert(source);
- }
-
- public void InsertAfter(LayerModel source)
- {
- source.Order = Order + 1;
- Insert(source);
- }
-
- private void Insert(LayerModel source)
- {
- if (Parent != null)
- {
- foreach (var child in Parent.Children.OrderBy(c => c.Order))
- {
- if (child.Order >= source.Order)
- child.Order++;
- }
- Parent.Children.Add(source);
- }
- else if (Profile != null)
- {
- foreach (var layer in Profile.Layers.OrderBy(l => l.Order))
- {
- if (layer.Order >= source.Order)
- layer.Order++;
- }
- Profile.Layers.Add(source);
- }
- }
-
- ///
- /// 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 include mice in the list
- /// Whether or not to include headsets in the list
- ///
- /// A flat list containing all layers that must be rendered
- public List GetRenderLayers(IDataModel dataModel, bool includeMice, bool includeHeadsets,
- bool ignoreConditions = false)
- {
- var layers = new List();
- foreach (var layerModel in Children.OrderByDescending(c => c.Order))
- {
- if (!layerModel.Enabled ||
- !includeMice && layerModel.LayerType == LayerType.Mouse ||
- !includeHeadsets && layerModel.LayerType == LayerType.Headset)
- continue;
-
- if (!ignoreConditions)
- {
- if (!layerModel.ConditionsMet(dataModel))
- continue;
- }
-
- layers.Add(layerModel);
- layers.AddRange(layerModel.GetRenderLayers(dataModel, includeMice, includeHeadsets, ignoreConditions));
- }
-
- return layers;
- }
-
- #region IChildItem Members
-
- LayerModel IChildItem.Parent
- {
- get { return Parent; }
- set { Parent = value; }
- }
-
- ProfileModel IChildItem.Parent
- {
- get { return Profile; }
- set { Profile = value; }
- }
-
- #endregion
- }
-
- public enum LayerType
- {
- [Description("Folder")] Folder,
- [Description("Keyboard")] Keyboard,
- [Description("Keyboard - GIF")] KeyboardGif,
- [Description("Mouse")] Mouse,
- [Description("Headset")] Headset
- }
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Media;
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Conditions;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Types.Headset;
+using Artemis.Profiles.Layers.Types.Keyboard;
+using Artemis.Profiles.Layers.Types.Mouse;
+using Artemis.Utilities;
+using Artemis.Utilities.ParentChild;
+using Newtonsoft.Json;
+
+namespace Artemis.Profiles.Layers.Models
+{
+ public class LayerModel : IChildItem, IChildItem
+ {
+ public LayerModel()
+ {
+ Children = new ChildItemCollection(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; }
+
+ ///
+ /// Checks whether this layers conditions are met.
+ /// If they are met and this layer is an event, this also triggers that event.
+ ///
+ ///
+ ///
+ public bool ConditionsMet(IDataModel dataModel)
+ {
+ // Conditions are not even checked if the layer isn't enabled
+ return Enabled && LayerCondition.ConditionsMet(this, dataModel);
+ }
+
+ public void Update(IDataModel dataModel, bool preview, bool updateAnimations)
+ {
+ LayerType.Update(this, dataModel, preview);
+ LayerAnimation?.Update(this, updateAnimations);
+ }
+
+ public void Draw(IDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations)
+ {
+ LayerType.Draw(this, c);
+ }
+
+ public void SetupProperties()
+ {
+ LayerType.SetupProperties(this);
+
+ // If the type is an event, set it up
+ if (IsEvent && EventProperties == null)
+ {
+ EventProperties = new KeyboardEventPropertiesModel
+ {
+ ExpirationType = ExpirationType.Time,
+ Length = new TimeSpan(0, 0, 1),
+ TriggerDelay = new TimeSpan(0)
+ };
+ }
+ }
+
+ public void FixOrder()
+ {
+ Children.Sort(l => l.Order);
+ for (var i = 0; i < Children.Count; i++)
+ Children[i].Order = i;
+ }
+
+ ///
+ /// Returns whether the layer meets the requirements to be drawn in the profile editor
+ ///
+ ///
+ public bool MustDraw()
+ {
+ // If any of the parents are disabled, this layer must not be drawn
+ var parent = Parent;
+ while (parent != null)
+ {
+ if (!parent.Enabled)
+ return false;
+ parent = parent.Parent;
+ }
+ return Enabled && LayerType.MustDraw;
+ }
+
+ ///
+ /// Returns every descendant of this layer
+ ///
+ ///
+ public IEnumerable GetLayers()
+ {
+ var layers = new List();
+ foreach (var layerModel in Children)
+ {
+ layers.Add(layerModel);
+ layers.AddRange(layerModel.GetLayers());
+ }
+
+ return layers;
+ }
+
+ ///
+ /// Creates a new Keyboard layer with default settings
+ ///
+ ///
+ public static LayerModel CreateLayer()
+ {
+ return new LayerModel
+ {
+ Name = "New layer",
+ Enabled = true,
+ Order = -1,
+ LayerType = new KeyboardType(),
+ LayerCondition = new DataModelCondition(),
+ Properties = new KeyboardPropertiesModel
+ {
+ Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()),
+ Height = 1,
+ Width = 1,
+ X = 0,
+ Y = 0,
+ Opacity = 1
+ }
+ };
+ }
+
+ public void InsertBefore(LayerModel source)
+ {
+ source.Order = Order;
+ Insert(source);
+ }
+
+ public void InsertAfter(LayerModel source)
+ {
+ source.Order = Order + 1;
+ Insert(source);
+ }
+
+ private void Insert(LayerModel source)
+ {
+ if (Parent != null)
+ {
+ foreach (var child in Parent.Children.OrderBy(c => c.Order))
+ {
+ if (child.Order >= source.Order)
+ child.Order++;
+ }
+ Parent.Children.Add(source);
+ }
+ else if (Profile != null)
+ {
+ foreach (var layer in Profile.Layers.OrderBy(l => l.Order))
+ {
+ if (layer.Order >= source.Order)
+ layer.Order++;
+ }
+ Profile.Layers.Add(source);
+ }
+ }
+
+ public void Replace(LayerModel layer)
+ {
+ layer.Order = Order;
+ layer.Parent = null;
+ layer.Profile = null;
+
+ if (Parent != null)
+ {
+ Parent.Children.Add(layer);
+ Parent.Children.Remove(this);
+ }
+ else if (Profile != null)
+ {
+ Profile.Layers.Add(layer);
+ Profile.Layers.Remove(this);
+ }
+ }
+
+ ///
+ /// 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 include mice in the list
+ /// Whether or not to include headsets in the list
+ ///
+ /// A flat list containing all layers that must be rendered
+ public List GetRenderLayers(IDataModel dataModel, bool includeMice, bool includeHeadsets,
+ bool ignoreConditions = false)
+ {
+ var layers = new List();
+ foreach (var layerModel in Children.OrderByDescending(c => c.Order))
+ {
+ if (!layerModel.Enabled || !includeMice && layerModel.LayerType is MouseType ||
+ !includeHeadsets && layerModel.LayerType is HeadsetType)
+ continue;
+
+ if (!ignoreConditions && !layerModel.ConditionsMet(dataModel))
+ continue;
+
+ layers.Add(layerModel);
+ layers.AddRange(layerModel.GetRenderLayers(dataModel, includeMice, includeHeadsets, ignoreConditions));
+ }
+
+ return layers;
+ }
+
+ #region IChildItem Members
+
+ LayerModel IChildItem.Parent
+ {
+ get { return Parent; }
+ set { Parent = value; }
+ }
+
+ ProfileModel IChildItem.Parent
+ {
+ get { return Profile; }
+ set { Profile = value; }
+ }
+
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Models/LayerPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Models/LayerPropertiesModel.cs
new file mode 100644
index 000000000..6c80bc49f
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Models/LayerPropertiesModel.cs
@@ -0,0 +1,69 @@
+using System.Collections.Generic;
+using System.Windows.Media;
+using Artemis.Utilities.Converters;
+using Newtonsoft.Json;
+
+namespace Artemis.Profiles.Layers.Models
+{
+ public abstract class LayerPropertiesModel
+ {
+ public LayerPropertiesModel(LayerPropertiesModel source = null)
+ {
+ if (source == null)
+ return;
+
+ // Clone the source's properties onto the new properties model (useful when changing property type)
+ X = source.X;
+ Y = source.Y;
+ Width = source.Width;
+ Height = source.Height;
+ Contain = source.Contain;
+ Opacity = source.Opacity;
+ AnimationSpeed = source.AnimationSpeed;
+ Conditions = source.Conditions;
+ DynamicProperties = source.DynamicProperties;
+ Brush = source.Brush;
+ }
+
+ private Brush _brush;
+
+ public double X { get; set; }
+ public double Y { get; set; }
+ public double Width { get; set; }
+ public double Height { get; set; }
+ public bool Contain { get; set; }
+ public double Opacity { get; set; }
+ public double AnimationSpeed { 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
+ {
+ 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;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Models/SimplePropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Models/SimplePropertiesModel.cs
new file mode 100644
index 000000000..463ca0006
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Models/SimplePropertiesModel.cs
@@ -0,0 +1,12 @@
+namespace Artemis.Profiles.Layers.Models
+{
+ ///
+ /// An empty layer properties model used by layers that don't have their own special properties
+ ///
+ public class SimplePropertiesModel : LayerPropertiesModel
+ {
+ public SimplePropertiesModel(LayerPropertiesModel properties = null) : base(properties)
+ {
+ }
+ }
+}
\ 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
new file mode 100644
index 000000000..08b24cb63
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Types/Folder/FolderType.cs
@@ -0,0 +1,53 @@
+using System.Collections.Generic;
+using System.Windows;
+using System.Windows.Media;
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Properties;
+using Artemis.Utilities;
+using Artemis.ViewModels.Profiles.Layers;
+
+namespace Artemis.Profiles.Layers.Types.Folder
+{
+ public class FolderType : ILayerType
+ {
+ public string Name { get; } = "Folder";
+ public bool MustDraw { get; } = false;
+
+ public ImageSource DrawThumbnail(LayerModel layer)
+ {
+ var thumbnailRect = new Rect(0, 0, 18, 18);
+ var visual = new DrawingVisual();
+ using (var c = visual.RenderOpen())
+ c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.folder), thumbnailRect);
+
+ var image = new DrawingImage(visual.Drawing);
+ return image;
+ }
+
+ public void Draw(LayerModel layer, DrawingContext c)
+ {
+ }
+
+ public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false)
+ {
+ }
+
+ public void SetupProperties(LayerModel layerModel)
+ {
+ if (layerModel.Properties is SimplePropertiesModel)
+ return;
+
+ layerModel.Properties = new SimplePropertiesModel(layerModel.Properties);
+ }
+
+ public LayerPropertiesViewModel SetupViewModel(LayerPropertiesViewModel layerPropertiesViewModel,
+ List layerAnimations, IDataModel dataModel, LayerModel proposedLayer)
+ {
+ if (layerPropertiesViewModel is FolderPropertiesViewModel)
+ return layerPropertiesViewModel;
+ return new FolderPropertiesViewModel(proposedLayer, dataModel);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs b/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs
new file mode 100644
index 000000000..b50921b8b
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetType.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.Windows;
+using System.Windows.Media;
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Animations;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Properties;
+using Artemis.Utilities;
+using Artemis.ViewModels.Profiles.Layers;
+
+namespace Artemis.Profiles.Layers.Types.Headset
+{
+ public class HeadsetType : ILayerType
+ {
+ public string Name { get; } = "Headset";
+ public bool MustDraw { get; } = false;
+
+ public ImageSource DrawThumbnail(LayerModel layer)
+ {
+ var thumbnailRect = new Rect(0, 0, 18, 18);
+ var visual = new DrawingVisual();
+ using (var c = visual.RenderOpen())
+ c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.headset), thumbnailRect);
+
+ var image = new DrawingImage(visual.Drawing);
+ return image;
+ }
+
+ public void Draw(LayerModel layer, DrawingContext c)
+ {
+ // If an animation is present, let it handle the drawing
+ if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation))
+ {
+ layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, 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);
+
+ c.PushClip(new RectangleGeometry(rect));
+ c.DrawRectangle(layer.AppliedProperties.Brush, null, rect);
+ c.Pop();
+ }
+
+ public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false)
+ {
+ // Headset layers are always drawn 10*10 (which is 40*40 when scaled up)
+ layerModel.Properties.Width = 10;
+ layerModel.Properties.Height = 10;
+ layerModel.Properties.X = 0;
+ layerModel.Properties.Y = 0;
+ layerModel.Properties.Contain = true;
+
+ layerModel.AppliedProperties = new SimplePropertiesModel(layerModel.Properties);
+
+ 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);
+ }
+
+ public void SetupProperties(LayerModel layerModel)
+ {
+ if (layerModel.Properties is SimplePropertiesModel)
+ return;
+
+ layerModel.Properties = new SimplePropertiesModel(layerModel.Properties);
+ }
+
+ public LayerPropertiesViewModel SetupViewModel(LayerPropertiesViewModel layerPropertiesViewModel,
+ List layerAnimations, IDataModel dataModel, LayerModel proposedLayer)
+ {
+ if (layerPropertiesViewModel is HeadsetPropertiesViewModel)
+ return layerPropertiesViewModel;
+ return new HeadsetPropertiesViewModel(proposedLayer, dataModel, layerAnimations);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesModel.cs
new file mode 100644
index 000000000..4ae12f40c
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesModel.cs
@@ -0,0 +1,19 @@
+using System.Windows;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Types.Keyboard
+{
+ public class KeyboardPropertiesModel : LayerPropertiesModel
+ {
+ public KeyboardPropertiesModel(LayerPropertiesModel properties = null) : base(properties)
+ {
+ }
+
+ public string GifFile { get; set; }
+
+ public Rect GetRect(int scale = 4)
+ {
+ return new Rect(X*scale, Y*scale, Width*scale, Height*scale);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardType.cs b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardType.cs
new file mode 100644
index 000000000..a9b3bdfcf
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardType.cs
@@ -0,0 +1,100 @@
+using System.Collections.Generic;
+using System.Windows;
+using System.Windows.Media;
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Animations;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Utilities;
+using Artemis.ViewModels.Profiles.Layers;
+
+
+namespace Artemis.Profiles.Layers.Types.Keyboard
+{
+ public class KeyboardType : ILayerType
+ {
+ public string Name { get; } = "Keyboard";
+ public bool MustDraw { get; } = true;
+
+ public ImageSource DrawThumbnail(LayerModel layer)
+ {
+ var thumbnailRect = new Rect(0, 0, 18, 18);
+ var visual = new DrawingVisual();
+ using (var c = visual.RenderOpen())
+ {
+ if (layer.Properties.Brush != null)
+ {
+ c.DrawRectangle(layer.Properties.Brush,
+ new Pen(new SolidColorBrush(Colors.White), 1),
+ thumbnailRect);
+ }
+ }
+
+ var image = new DrawingImage(visual.Drawing);
+ return image;
+ }
+
+ public void Draw(LayerModel layer, DrawingContext c)
+ {
+ // If an animation is present, let it handle the drawing
+ if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation))
+ {
+ layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, c);
+ return;
+ }
+
+ // Otherwise draw the rectangle with its layer.AppliedProperties dimensions and brush
+ var rect = layer.Properties.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 clip = new Rect(layer.AppliedProperties.X*4, layer.AppliedProperties.Y*4,
+ layer.AppliedProperties.Width*4, layer.AppliedProperties.Height*4);
+
+
+ c.PushClip(new RectangleGeometry(clip));
+ c.DrawRectangle(layer.AppliedProperties.Brush, null, rect);
+ c.Pop();
+ }
+
+ public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false)
+ {
+ layerModel.AppliedProperties = new KeyboardPropertiesModel(layerModel.Properties);
+ 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);
+ }
+
+ public void SetupProperties(LayerModel layerModel)
+ {
+ if (layerModel.Properties is KeyboardPropertiesModel)
+ return;
+
+ layerModel.Properties = new KeyboardPropertiesModel(layerModel.Properties);
+ }
+
+ public LayerPropertiesViewModel SetupViewModel(LayerPropertiesViewModel layerPropertiesViewModel,
+ List layerAnimations, IDataModel dataModel, LayerModel proposedLayer)
+ {
+ var model = layerPropertiesViewModel as KeyboardPropertiesViewModel;
+ if (model == null)
+ return new KeyboardPropertiesViewModel(proposedLayer, dataModel, layerAnimations)
+ {
+ IsGif = false
+ };
+
+ model.IsGif = false;
+ return layerPropertiesViewModel;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs b/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs
new file mode 100644
index 000000000..e4814e51a
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs
@@ -0,0 +1,93 @@
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using System.Windows;
+using System.Windows.Media;
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Profiles.Layers.Types.Keyboard;
+using Artemis.Properties;
+using Artemis.Utilities;
+using Artemis.ViewModels.Profiles.Layers;
+
+
+namespace Artemis.Profiles.Layers.Types.KeyboardGif
+{
+ internal class KeyboardGifType : ILayerType
+ {
+ public string Name { get; } = "Keyboard - GIF";
+ public bool MustDraw { get; } = true;
+
+ public ImageSource DrawThumbnail(LayerModel layer)
+ {
+ var thumbnailRect = new Rect(0, 0, 18, 18);
+ var visual = new DrawingVisual();
+ using (var c = visual.RenderOpen())
+ c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.gif), thumbnailRect);
+
+ var image = new DrawingImage(visual.Drawing);
+ return image;
+ }
+
+ public void Draw(LayerModel layer, DrawingContext c)
+ {
+ var props = (KeyboardPropertiesModel) layer.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);
+
+ var rect = new Rect(layer.AppliedProperties.X*4,
+ layer.AppliedProperties.Y*4,
+ layer.AppliedProperties.Width*4,
+ layer.AppliedProperties.Height*4);
+
+ lock (layer.GifImage)
+ {
+ var draw = layer.GifImage.GetNextFrame();
+ c.DrawImage(ImageUtilities.BitmapToBitmapImage(new Bitmap(draw)), rect);
+ }
+ }
+
+ public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false)
+ {
+ layerModel.AppliedProperties = new KeyboardPropertiesModel(layerModel.Properties);
+ 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);
+ }
+
+ public void SetupProperties(LayerModel layerModel)
+ {
+ if (layerModel.Properties is KeyboardPropertiesModel)
+ return;
+
+ layerModel.Properties = new KeyboardPropertiesModel(layerModel.Properties);
+ }
+
+ public LayerPropertiesViewModel SetupViewModel(LayerPropertiesViewModel layerPropertiesViewModel,
+ List layerAnimations, IDataModel dataModel, LayerModel proposedLayer)
+ {
+ var model = layerPropertiesViewModel as KeyboardPropertiesViewModel;
+ if (model == null)
+ return new KeyboardPropertiesViewModel(proposedLayer, dataModel, layerAnimations)
+ {
+ IsGif = true
+ };
+
+ model.IsGif = true;
+ return layerPropertiesViewModel;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs b/Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs
new file mode 100644
index 000000000..1ad7d68ba
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Types/Mouse/MouseType.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Windows;
+using System.Windows.Media;
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Animations;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Properties;
+using Artemis.Utilities;
+using Artemis.ViewModels.Profiles.Layers;
+
+
+namespace Artemis.Profiles.Layers.Types.Mouse
+{
+ public class MouseType : ILayerType
+ {
+ public string Name { get; } = "Mouse";
+ public bool MustDraw { get; } = false;
+
+ public ImageSource DrawThumbnail(LayerModel layer)
+ {
+ var thumbnailRect = new Rect(0, 0, 18, 18);
+ var visual = new DrawingVisual();
+ using (var c = visual.RenderOpen())
+ c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.mouse), thumbnailRect);
+
+ var image = new DrawingImage(visual.Drawing);
+ return image;
+ }
+
+ public void Draw(LayerModel layer, DrawingContext c)
+ {
+ // If an animation is present, let it handle the drawing
+ if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation))
+ {
+ layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, 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);
+
+ c.PushClip(new RectangleGeometry(rect));
+ c.DrawRectangle(layer.AppliedProperties.Brush, null, rect);
+ c.Pop();
+ }
+
+ public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false)
+ {
+ // Mouse layers are always drawn 10*10 (which is 40*40 when scaled up)
+ layerModel.Properties.Width = 10;
+ layerModel.Properties.Height = 10;
+ layerModel.Properties.X = 0;
+ layerModel.Properties.Y = 0;
+ layerModel.Properties.Contain = true;
+
+ layerModel.AppliedProperties = new SimplePropertiesModel(layerModel.Properties);
+
+ 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);
+ }
+
+ public void SetupProperties(LayerModel layerModel)
+ {
+ if (layerModel.Properties is SimplePropertiesModel)
+ return;
+
+ layerModel.Properties = new SimplePropertiesModel(layerModel.Properties);
+ }
+
+ public LayerPropertiesViewModel SetupViewModel(LayerPropertiesViewModel layerPropertiesViewModel,
+ List layerAnimations, IDataModel dataModel, LayerModel proposedLayer)
+ {
+ if (layerPropertiesViewModel is MousePropertiesViewModel)
+ return layerPropertiesViewModel;
+ return new MousePropertiesViewModel(proposedLayer, dataModel, layerAnimations);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Models/Profiles/ProfileModel.cs b/Artemis/Artemis/Profiles/ProfileModel.cs
similarity index 61%
rename from Artemis/Artemis/Models/Profiles/ProfileModel.cs
rename to Artemis/Artemis/Profiles/ProfileModel.cs
index 12c2ed998..66f2962d9 100644
--- a/Artemis/Artemis/Models/Profiles/ProfileModel.cs
+++ b/Artemis/Artemis/Profiles/ProfileModel.cs
@@ -1,223 +1,201 @@
-using System.Collections.Generic;
-using System.Drawing;
-using System.Linq;
-using System.Windows;
-using System.Windows.Media;
-using System.Xml.Serialization;
-using Artemis.Models.Interfaces;
-using Artemis.Models.Profiles.Properties;
-using Artemis.Utilities;
-using Artemis.Utilities.ParentChild;
-using Brush = System.Windows.Media.Brush;
-using Color = System.Windows.Media.Color;
-using Point = System.Windows.Point;
-using Size = System.Windows.Size;
-
-namespace Artemis.Models.Profiles
-{
- public class ProfileModel
- {
- public ProfileModel()
- {
- Layers = new ChildItemCollection(this);
- DrawingVisual = new DrawingVisual();
- }
-
- public ChildItemCollection Layers { get; }
-
- public string Name { get; set; }
- public bool IsDefault { get; set; }
- public string KeyboardSlug { get; set; }
- public string GameName { get; set; }
-
- [XmlIgnore]
- public DrawingVisual DrawingVisual { get; set; }
-
- protected bool Equals(ProfileModel other)
- {
- return string.Equals(Name, other.Name) &&
- string.Equals(KeyboardSlug, other.KeyboardSlug) &&
- string.Equals(GameName, other.GameName);
- }
-
- public override bool Equals(object obj)
- {
- if (ReferenceEquals(null, obj)) return false;
- if (ReferenceEquals(this, obj)) return true;
- if (obj.GetType() != GetType()) return false;
- return Equals((ProfileModel)obj);
- }
-
- public override int GetHashCode()
- {
- unchecked
- {
- var hashCode = Name?.GetHashCode() ?? 0;
- hashCode = (hashCode * 397) ^ (KeyboardSlug?.GetHashCode() ?? 0);
- hashCode = (hashCode * 397) ^ (GameName?.GetHashCode() ?? 0);
- return hashCode;
- }
- }
-
- public void FixOrder()
- {
- Layers.Sort(l => l.Order);
- for (var i = 0; i < Layers.Count; i++)
- Layers[i].Order = i;
- }
-
- public void DrawProfile(Graphics keyboard, Rect keyboardRect, IDataModel dataModel, bool preview,
- bool updateAnimations)
- {
- var visual = new DrawingVisual();
- using (var c = visual.RenderOpen())
- {
- // Setup the DrawingVisual's size
- c.PushClip(new RectangleGeometry(keyboardRect));
- c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect);
-
- // Draw the layers
- foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
- layerModel.Draw(dataModel, c, preview, updateAnimations);
-
- // Remove the clip
- c.Pop();
- }
-
- using (Bitmap bmp = ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect))
- keyboard.DrawImage(bmp, new PointF(0, 0));
- }
-
- public Brush GenerateBrush(IDataModel dataModel, LayerType type, bool preview, bool updateAnimations)
- {
- Brush result = null;
- // Draw the layers
- foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
- {
- var generated = layerModel.GenerateBrush(type, dataModel, preview, updateAnimations);
- if (generated != null)
- result = generated;
- }
-
- return result;
- }
-
- ///
- /// Gives all the layers and their children in a flat list
- ///
- public List GetLayers()
- {
- var layers = new List();
- foreach (var layerModel in Layers)
- {
- layers.Add(layerModel);
- layers.AddRange(layerModel.GetLayers());
- }
-
- return layers;
- }
-
- ///
- /// 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 include mice in the list
- /// Whether or not to include headsets in the list
- ///
- /// A flat list containing all layers that must be rendered
- public List GetRenderLayers(IDataModel dataModel, bool includeMice, bool includeHeadsets,
- bool ignoreConditions = false)
- {
- var layers = new List();
- foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
- {
- if (!layerModel.Enabled ||
- !includeMice && layerModel.LayerType == LayerType.Mouse ||
- !includeHeadsets && layerModel.LayerType == LayerType.Headset)
- continue;
-
- if (!ignoreConditions)
- {
- if (!layerModel.ConditionsMet(dataModel))
- continue;
- }
-
- layers.Add(layerModel);
- layers.AddRange(layerModel.GetRenderLayers(dataModel, includeMice, includeHeadsets, ignoreConditions));
- }
-
- return layers;
- }
-
- ///
- /// Looks at all the layers wthin the profile and makes sure they are within boundaries of the given rectangle
- ///
- ///
- public void FixBoundaries(Rect keyboardRectangle)
- {
- foreach (var layer in GetLayers())
- {
- if (layer.LayerType != LayerType.Keyboard && layer.LayerType != LayerType.KeyboardGif)
- continue;
-
- var props = (KeyboardPropertiesModel)layer.Properties;
- var layerRect = new Rect(new Point(props.X, props.Y), new Size(props.Width, props.Height));
- if (keyboardRectangle.Contains(layerRect))
- continue;
-
- props.X = 0;
- props.Y = 0;
- layer.Properties = props;
- }
- }
-
- ///
- /// Draw all the provided layers of type Keyboard and KeyboardGif
- ///
- /// The graphics to draw on
- /// The layers to render
- /// The data model to base the layer's properties on
- /// A rectangle matching the current keyboard's size on a scale of 4, used for clipping
- /// Indicates wheter the layer is drawn as a preview, ignoring dynamic properties
- /// Wheter or not to update the layer's animations
- internal void DrawProfile(Graphics keyboard, List renderLayers, IDataModel dataModel, Rect keyboardRect,
- bool preview,
- bool updateAnimations)
- {
- var visual = new DrawingVisual();
- using (var c = visual.RenderOpen())
- {
- // Setup the DrawingVisual's size
- c.PushClip(new RectangleGeometry(keyboardRect));
- c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect);
-
- // Draw the layers
- foreach (var layerModel in renderLayers
- .Where(l => l.LayerType == LayerType.Keyboard ||
- l.LayerType == LayerType.KeyboardGif))
- {
- layerModel.Draw(dataModel, c, preview, updateAnimations);
- }
-
- // Remove the clip
- c.Pop();
- }
-
- using (Bitmap bmp = ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect))
- keyboard.DrawImage(bmp, new PointF(0, 0));
- }
-
- ///
- /// Generates a brush out of the given layer, for usage with mice and headsets
- ///
- /// The layer to base the brush on
- /// The game data model to base the layer's properties on
- /// The generated brush
- public Brush GenerateBrush(LayerModel layerModel, IDataModel dataModel)
- {
- return layerModel?.Properties.GetAppliedProperties(dataModel).Brush;
- }
- }
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows;
+using System.Windows.Media;
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Profiles.Layers.Types.Headset;
+using Artemis.Profiles.Layers.Types.Keyboard;
+using Artemis.Profiles.Layers.Types.Mouse;
+using Artemis.Utilities;
+using Artemis.Utilities.ParentChild;
+using Newtonsoft.Json;
+using Color = System.Windows.Media.Color;
+using Point = System.Windows.Point;
+using Size = System.Windows.Size;
+
+namespace Artemis.Profiles
+{
+ public class ProfileModel
+ {
+ public ProfileModel()
+ {
+ Layers = new ChildItemCollection(this);
+ DrawingVisual = new DrawingVisual();
+ }
+
+ public ChildItemCollection Layers { get; }
+
+ public string Name { get; set; }
+ public bool IsDefault { get; set; }
+ public string KeyboardSlug { get; set; }
+ public string GameName { get; set; }
+
+ [JsonIgnore]
+
+ public DrawingVisual DrawingVisual { get; set; }
+
+ public void FixOrder()
+ {
+ Layers.Sort(l => l.Order);
+ for (var i = 0; i < Layers.Count; i++)
+ Layers[i].Order = i;
+ }
+
+ public void DrawLayers(Graphics keyboard, Rect keyboardRect, IDataModel dataModel, bool preview,
+ bool updateAnimations)
+ {
+ var visual = new DrawingVisual();
+ using (var c = visual.RenderOpen())
+ {
+ // Setup the DrawingVisual's size
+ c.PushClip(new RectangleGeometry(keyboardRect));
+ c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect);
+
+ // Draw the layers
+ foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
+ {
+ layerModel.Update(dataModel, preview, updateAnimations);
+ layerModel.Draw(dataModel, c, preview, updateAnimations);
+ }
+ // Remove the clip
+ c.Pop();
+ }
+
+ using (var bmp = ImageUtilities.DrawinVisualToBitmap(visual, keyboardRect))
+ keyboard.DrawImage(bmp, new PointF(0, 0));
+ }
+
+ ///
+ /// Gives all the layers and their children in a flat list
+ ///
+ public List GetLayers()
+ {
+ var layers = new List();
+ foreach (var layerModel in Layers)
+ {
+ layers.Add(layerModel);
+ layers.AddRange(layerModel.GetLayers());
+ }
+
+ return layers;
+ }
+
+ ///
+ /// 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 include mice in the list
+ /// Whether or not to include headsets in the list
+ ///
+ /// A flat list containing all layers that must be rendered
+ public List GetRenderLayers(IDataModel dataModel, bool includeMice, bool includeHeadsets,
+ bool ignoreConditions = false)
+ {
+ var layers = new List();
+ foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
+ {
+ if (!layerModel.Enabled || !includeMice && layerModel.LayerType is MouseType ||
+ !includeHeadsets && layerModel.LayerType is HeadsetType)
+ continue;
+
+ if (!ignoreConditions && !layerModel.ConditionsMet(dataModel))
+ continue;
+
+ layers.Add(layerModel);
+ layers.AddRange(layerModel.GetRenderLayers(dataModel, includeMice, includeHeadsets, ignoreConditions));
+ }
+
+ return layers;
+ }
+
+ ///
+ /// Looks at all the layers wthin the profile and makes sure they are within boundaries of the given rectangle
+ ///
+ ///
+ public void FixBoundaries(Rect keyboardRectangle)
+ {
+ foreach (var layer in GetLayers())
+ {
+ if (!layer.LayerType.MustDraw)
+ continue;
+
+ var props = (KeyboardPropertiesModel) layer.Properties;
+ var layerRect = new Rect(new Point(props.X, props.Y), new Size(props.Width, props.Height));
+ if (keyboardRectangle.Contains(layerRect))
+ continue;
+
+ props.X = 0;
+ props.Y = 0;
+ layer.Properties = props;
+ }
+ }
+
+ ///
+ /// Draw all the given layers on the given rect
+ ///
+ /// The graphics to draw on
+ /// The layers to render
+ /// The data model to base the layer's properties on
+ /// A rectangle matching the current keyboard's size on a scale of 4, used for clipping
+ /// Indicates wheter the layer is drawn as a preview, ignoring dynamic properties
+ /// Wheter or not to update the layer's animations
+ internal void DrawLayers(Graphics g, IEnumerable renderLayers, IDataModel dataModel, Rect rect,
+ bool preview, bool updateAnimations)
+ {
+ var visual = new DrawingVisual();
+ using (var c = visual.RenderOpen())
+ {
+ // Setup the DrawingVisual's size
+ c.PushClip(new RectangleGeometry(rect));
+ c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, rect);
+
+ // Draw the layers
+ foreach (var layerModel in renderLayers)
+ {
+ layerModel.Update(dataModel, preview, updateAnimations);
+ layerModel.Draw(dataModel, c, preview, updateAnimations);
+ }
+
+ // Remove the clip
+ c.Pop();
+ }
+
+ using (var bmp = ImageUtilities.DrawinVisualToBitmap(visual, rect))
+ g.DrawImage(bmp, new PointF(0, 0));
+ }
+
+ #region Compare
+
+ protected bool Equals(ProfileModel other)
+ {
+ return string.Equals(Name, other.Name) &&
+ string.Equals(KeyboardSlug, other.KeyboardSlug) &&
+ string.Equals(GameName, other.GameName);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != GetType()) return false;
+ return Equals((ProfileModel) obj);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ var hashCode = Name?.GetHashCode() ?? 0;
+ hashCode = (hashCode*397) ^ (KeyboardSlug?.GetHashCode() ?? 0);
+ hashCode = (hashCode*397) ^ (GameName?.GetHashCode() ?? 0);
+ return hashCode;
+ }
+ }
+
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Resources/Witcher3/Witcher3Artemis.zip b/Artemis/Artemis/Resources/Witcher3/Witcher3Artemis.zip
index 8269c99d9..002796ac6 100644
Binary files a/Artemis/Artemis/Resources/Witcher3/Witcher3Artemis.zip and b/Artemis/Artemis/Resources/Witcher3/Witcher3Artemis.zip differ
diff --git a/Artemis/Artemis/Settings/General.settings b/Artemis/Artemis/Settings/General.settings
index 521a80d33..326ce89c3 100644
--- a/Artemis/Artemis/Settings/General.settings
+++ b/Artemis/Artemis/Settings/General.settings
@@ -1,5 +1,7 @@
-
+
+
diff --git a/Artemis/Artemis/Settings/GeneralSettings.cs b/Artemis/Artemis/Settings/GeneralSettings.cs
index 296ed2f52..573f4e20c 100644
--- a/Artemis/Artemis/Settings/GeneralSettings.cs
+++ b/Artemis/Artemis/Settings/GeneralSettings.cs
@@ -5,7 +5,6 @@ using System.Runtime.InteropServices.ComTypes;
using System.Windows;
using Artemis.Utilities;
using MahApps.Metro;
-using NLog;
namespace Artemis.Settings
{
diff --git a/Artemis/Artemis/Styles/ColorBox.xaml b/Artemis/Artemis/Styles/ColorBox.xaml
index 40a64f1fc..bbd797280 100644
--- a/Artemis/Artemis/Styles/ColorBox.xaml
+++ b/Artemis/Artemis/Styles/ColorBox.xaml
@@ -84,7 +84,7 @@
+ BorderBrush="{TemplateBinding BorderBrush}" />
@@ -491,7 +491,8 @@
SelectedGradient="{Binding}"
Margin="0,0,0,2">
-
+
diff --git a/Artemis/Artemis/Utilities/ColorHelpers.cs b/Artemis/Artemis/Utilities/ColorHelpers.cs
index fb96440e3..0a28d5a77 100644
--- a/Artemis/Artemis/Utilities/ColorHelpers.cs
+++ b/Artemis/Artemis/Utilities/ColorHelpers.cs
@@ -33,7 +33,7 @@ namespace Artemis.Utilities
{
var colors = new List();
for (var i = 0; i < 3; i++)
- colors.Add((byte)_rand.Next(0, 256));
+ colors.Add((byte) _rand.Next(0, 256));
var highest = colors.Max();
var lowest = colors.Min();
diff --git a/Artemis/Artemis/Utilities/Converters/JsonConverters.cs b/Artemis/Artemis/Utilities/Converters/JsonConverters.cs
new file mode 100644
index 000000000..cfc95ae1f
--- /dev/null
+++ b/Artemis/Artemis/Utilities/Converters/JsonConverters.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Windows.Markup;
+using System.Windows.Media;
+using System.Xml;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Artemis.Utilities.Converters
+{
+ ///
+ /// Stores a brush by temporarily serializing it to XAML because Json.NET has trouble
+ /// saving it as JSON
+ ///
+ public class BrushJsonConverter : JsonConverter
+ {
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ // Turn the brush into an XML node
+ var doc = new XmlDocument();
+ doc.LoadXml(XamlWriter.Save(value));
+
+ // Serialize the XML node as JSON
+ var jo = JObject.Parse(JsonConvert.SerializeXmlNode(doc.DocumentElement));
+ jo.WriteTo(writer);
+ }
+
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
+ JsonSerializer serializer)
+ {
+ // Load JObject from stream
+ var jObject = JObject.Load(reader);
+
+ // Seriaze the JSON node to XML
+ var xml = JsonConvert.DeserializeXmlNode(jObject.ToString());
+ return XamlReader.Parse(xml.InnerXml);
+ }
+
+ public override bool CanConvert(Type objectType)
+ {
+ return typeof(Brush).IsAssignableFrom(objectType);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Utilities/ValueConverters.cs b/Artemis/Artemis/Utilities/Converters/ValueConverters.cs
similarity index 78%
rename from Artemis/Artemis/Utilities/ValueConverters.cs
rename to Artemis/Artemis/Utilities/Converters/ValueConverters.cs
index bd60915d0..7af474bfb 100644
--- a/Artemis/Artemis/Utilities/ValueConverters.cs
+++ b/Artemis/Artemis/Utilities/Converters/ValueConverters.cs
@@ -1,66 +1,79 @@
-using System;
-using System.Collections;
-using System.ComponentModel;
-using System.Globalization;
-using System.Linq;
-using System.Windows.Data;
-using Artemis.Models.Profiles;
-using Artemis.Utilities.ParentChild;
-
-namespace Artemis.Utilities
-{
- ///
- /// Fredrik Hedblad - http://stackoverflow.com/a/3987099/5015269
- ///
- public class EnumDescriptionConverter : IValueConverter
- {
- object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
- {
- var myEnum = (Enum) value;
- var description = GetEnumDescription(myEnum);
- return description;
- }
-
- object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
- {
- return string.Empty;
- }
-
- private string GetEnumDescription(Enum enumObj)
- {
- var fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
-
- var attribArray = fieldInfo.GetCustomAttributes(false);
-
- if (attribArray.Length == 0)
- {
- return enumObj.ToString();
- }
- var attrib = attribArray[0] as DescriptionAttribute;
- return attrib?.Description;
- }
- }
-
- public class LayerOrderConverter : IValueConverter
- {
- public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
- {
- IList collection;
- if (value is ChildItemCollection)
- collection = ((ChildItemCollection) value).ToList();
- else
- collection = (IList) value;
-
- var view = new ListCollectionView(collection);
- var sort = new SortDescription(parameter.ToString(), ListSortDirection.Ascending);
- view.SortDescriptions.Add(sort);
-
- return view;
- }
-
- public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
- {
- return null;
- }
- }
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq;
+using System.Windows.Data;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Utilities.ParentChild;
+
+namespace Artemis.Utilities.Converters
+{
+ ///
+ /// Fredrik Hedblad - http://stackoverflow.com/a/3987099/5015269
+ ///
+ public class EnumDescriptionConverter : IValueConverter
+ {
+ object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var myEnum = (Enum) value;
+ var description = GetEnumDescription(myEnum);
+ return description;
+ }
+
+ object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return string.Empty;
+ }
+
+ private string GetEnumDescription(Enum enumObj)
+ {
+ var fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
+
+ var attribArray = fieldInfo.GetCustomAttributes(false);
+
+ if (attribArray.Length == 0)
+ {
+ return enumObj.ToString();
+ }
+ var attrib = attribArray[0] as DescriptionAttribute;
+ return attrib?.Description;
+ }
+ }
+
+ public class LayerOrderConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ IList collection;
+ if (value is ChildItemCollection)
+ collection = ((ChildItemCollection) value).ToList();
+ else
+ collection = (IList) value;
+
+ var view = new ListCollectionView(collection);
+ var sort = new SortDescription(parameter.ToString(), ListSortDirection.Ascending);
+ view.SortDescriptions.Add(sort);
+
+ return view;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return null;
+ }
+ }
+
+ public class MilliSecondTimespanConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value == null ? 0.0 : ((TimeSpan)value).TotalMilliseconds;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value == null ? new TimeSpan() : TimeSpan.FromMilliseconds((double)value);
+ }
+ }
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Utilities/DataReaders/MmfReader.cs b/Artemis/Artemis/Utilities/DataReaders/MmfReader.cs
index 744b9576f..51c0aaf57 100644
--- a/Artemis/Artemis/Utilities/DataReaders/MmfReader.cs
+++ b/Artemis/Artemis/Utilities/DataReaders/MmfReader.cs
@@ -4,6 +4,7 @@ using System.IO.MemoryMappedFiles;
using System.Linq;
using System.Text;
using System.Windows.Media;
+using Ninject.Extensions.Logging;
namespace Artemis.Utilities.DataReaders
{
@@ -12,10 +13,11 @@ namespace Artemis.Utilities.DataReaders
///
public class MmfReader
{
- private DateTime _lastFailure;
+ private readonly ILogger _logger;
- public MmfReader(string mmfName)
+ public MmfReader(string mmfName, ILogger logger)
{
+ _logger = logger;
MmfName = mmfName;
}
@@ -54,8 +56,9 @@ namespace Artemis.Utilities.DataReaders
}
return colors;
}
- catch (FormatException)
+ catch (FormatException e)
{
+ _logger.Trace(e, "Failed to parse to color array");
return null;
}
}
@@ -67,10 +70,6 @@ namespace Artemis.Utilities.DataReaders
///
private string ReadMmf(string fileName)
{
- // Don't read the file within one second after failing
- //if (DateTime.Now - _lastFailure > new TimeSpan(0, 0, 1))
- // return null;
-
try
{
using (var mmf = MemoryMappedFile.OpenExisting(fileName))
@@ -85,9 +84,9 @@ namespace Artemis.Utilities.DataReaders
}
}
}
- catch (FileNotFoundException)
+ catch (FileNotFoundException e)
{
- _lastFailure = DateTime.Now;
+ _logger.Trace(e, "Failed to read mff");
return null;
//ignored
}
diff --git a/Artemis/Artemis/Utilities/GeneralHelpers.cs b/Artemis/Artemis/Utilities/GeneralHelpers.cs
index 8dc160b6e..3eb2c5ac2 100644
--- a/Artemis/Artemis/Utilities/GeneralHelpers.cs
+++ b/Artemis/Artemis/Utilities/GeneralHelpers.cs
@@ -5,8 +5,8 @@ using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows;
-using System.Xml.Serialization;
using Microsoft.Win32;
+using Newtonsoft.Json;
using static System.String;
namespace Artemis.Utilities
@@ -39,7 +39,7 @@ namespace Artemis.Utilities
}
///
- /// Perform a deep Copy of the object.
+ /// Perform a deep Copy of the object, using Json as a serialisation method.
///
/// The type of object being copied.
/// The object instance to copy.
@@ -50,35 +50,20 @@ namespace Artemis.Utilities
if (ReferenceEquals(source, null))
return default(T);
- var serializer = new XmlSerializer(typeof(T));
- Stream stream = new MemoryStream();
- using (stream)
+ var deserializeSettings = new JsonSerializerSettings
{
- serializer.Serialize(stream, source);
- stream.Seek(0, SeekOrigin.Begin);
- return (T) serializer.Deserialize(stream);
- }
- }
-
- public static string Serialize(T source)
- {
- // Don't serialize a null object, simply return the default for that object
- if (ReferenceEquals(source, null))
- return null;
-
- var serializer = new XmlSerializer(typeof(T));
- var stream = new StringWriter();
- using (stream)
- {
- serializer.Serialize(stream, source);
- return stream.ToString();
- }
+ ObjectCreationHandling = ObjectCreationHandling.Replace,
+ TypeNameHandling = TypeNameHandling.Auto
+ };
+ return (T)JsonConvert.DeserializeObject(JsonConvert.SerializeObject(source), source.GetType(),
+ deserializeSettings);
}
public static object GetPropertyValue(object o, string path)
{
var propertyNames = path.Split('.');
- var value = o.GetType().GetProperty(propertyNames[0]).GetValue(o, null);
+ var prop = o.GetType().GetProperty(propertyNames[0]);
+ var value = prop.GetValue(o, null);
if (propertyNames.Length == 1 || value == null)
return value;
diff --git a/Artemis/Artemis/Utilities/GifImage.cs b/Artemis/Artemis/Utilities/GifImage.cs
index bf06ea040..085e51165 100644
--- a/Artemis/Artemis/Utilities/GifImage.cs
+++ b/Artemis/Artemis/Utilities/GifImage.cs
@@ -8,9 +8,7 @@ namespace Artemis.Utilities
{
private readonly int _delay;
private readonly FrameDimension _dimension;
- private readonly int _frameCount;
private readonly Image _gifImage;
- private int _currentFrame = -1;
private DateTime _lastRequest;
private int _step = 1;
@@ -19,7 +17,7 @@ namespace Artemis.Utilities
_lastRequest = DateTime.Now;
_gifImage = Image.FromFile(path); //initialize
_dimension = new FrameDimension(_gifImage.FrameDimensionsList[0]); //gets the GUID
- _frameCount = _gifImage.GetFrameCount(_dimension); //total frames in the animation
+ FrameCount = _gifImage.GetFrameCount(_dimension); //total frames in the animation
Source = path;
@@ -27,7 +25,20 @@ namespace Artemis.Utilities
_delay = (item.Value[0] + item.Value[1]*256)*10; // Time is in 1/100th of a second
}
- public string Source { get; set; }
+ ///
+ /// Gets the path the GifImage is based on
+ ///
+ public string Source { get; private set; }
+
+ ///
+ /// Gets or sets the current frame, set to -1 to reset
+ ///
+ public int CurrentFrame { get; set; } = -1;
+
+ ///
+ /// Gets the total amount of frames in the GIF
+ ///
+ public int FrameCount { get; }
///
/// Whether the gif should play backwards when it reaches the end
@@ -39,23 +50,23 @@ namespace Artemis.Utilities
// Only pass the next frame if the proper amount of time has passed
if ((DateTime.Now - _lastRequest).Milliseconds > _delay)
{
- _currentFrame += _step;
+ CurrentFrame += _step;
_lastRequest = DateTime.Now;
}
//if the animation reaches a boundary...
- if (_currentFrame < _frameCount && _currentFrame >= 1)
- return GetFrame(_currentFrame);
+ if (CurrentFrame < FrameCount && CurrentFrame >= 1)
+ return GetFrame(CurrentFrame);
if (ReverseAtEnd)
{
_step *= -1; //...reverse the count
- _currentFrame += _step; //apply it
+ CurrentFrame += _step; //apply it
}
else
- _currentFrame = 0; //...or start over
+ CurrentFrame = 0; //...or start over
- return GetFrame(_currentFrame);
+ return GetFrame(CurrentFrame);
}
public Image GetFrame(int index)
diff --git a/Artemis/Artemis/Utilities/ImageUtilities.cs b/Artemis/Artemis/Utilities/ImageUtilities.cs
index 57203e821..c45875482 100644
--- a/Artemis/Artemis/Utilities/ImageUtilities.cs
+++ b/Artemis/Artemis/Utilities/ImageUtilities.cs
@@ -70,5 +70,24 @@ namespace Artemis.Utilities
}
return bitmap;
}
+
+ ///
+ /// Loads the BowIcon from resources and colors it according to the current theme
+ ///
+ ///
+ public static RenderTargetBitmap GenerateWindowIcon()
+ {
+ var iconImage = new System.Windows.Controls.Image
+ {
+ Source = (DrawingImage) Application.Current.MainWindow.Resources["BowIcon"],
+ Stretch = Stretch.Uniform,
+ Margin = new Thickness(20)
+ };
+
+ iconImage.Arrange(new Rect(0, 0, 100, 100));
+ var bitmap = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32);
+ bitmap.Render(iconImage);
+ return bitmap;
+ }
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Utilities/Layers/AnimationUpdater.cs b/Artemis/Artemis/Utilities/Layers/AnimationUpdater.cs
deleted file mode 100644
index c4430b174..000000000
--- a/Artemis/Artemis/Utilities/Layers/AnimationUpdater.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using Artemis.Models.Profiles.Properties;
-
-namespace Artemis.Utilities.Layers
-{
- public static class AnimationUpdater
- {
- public static void UpdateAnimation(KeyboardPropertiesModel properties, bool updateAnimations)
- {
- const int scale = 4;
- var progress = properties.AnimationProgress;
-
- switch (properties.Animation)
- {
- case LayerAnimation.SlideRight:
- case LayerAnimation.SlideLeft:
- if (progress + properties.AnimationSpeed * 2 >= properties.Width*scale)
- progress = 0;
- progress = progress + properties.AnimationSpeed*2;
- break;
- case LayerAnimation.SlideDown:
- case LayerAnimation.SlideUp:
- if (progress + properties.AnimationSpeed * 2 >= properties.Height*scale)
- progress = 0;
- progress = progress + properties.AnimationSpeed*2;
- break;
- case LayerAnimation.Pulse:
- if (progress > 2)
- progress = 0;
- progress = progress + properties.AnimationSpeed/2;
- break;
- case LayerAnimation.Grow:
- if (progress > 10)
- progress = 0;
- progress = progress + properties.AnimationSpeed/2.5;
- break;
- default:
- progress = progress + properties.AnimationSpeed*2;
- break;
- }
-
- // If not previewing, store the animation progress in the actual model for the next frame
- if (updateAnimations)
- properties.AnimationProgress = progress;
- }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/Utilities/Layers/Drawer.cs b/Artemis/Artemis/Utilities/Layers/Drawer.cs
deleted file mode 100644
index 1fe261602..000000000
--- a/Artemis/Artemis/Utilities/Layers/Drawer.cs
+++ /dev/null
@@ -1,161 +0,0 @@
-using System;
-using System.Drawing;
-using System.IO;
-using System.Windows;
-using System.Windows.Media;
-using Artemis.Models.Profiles;
-using Artemis.Models.Profiles.Properties;
-using Artemis.Properties;
-using Pen = System.Windows.Media.Pen;
-using Point = System.Windows.Point;
-using Size = System.Windows.Size;
-
-namespace Artemis.Utilities.Layers
-{
- public static class Drawer
- {
- public static void Draw(DrawingContext c, KeyboardPropertiesModel props, AppliedProperties applied)
- {
- if (applied.Brush == null)
- return;
-
- const int scale = 4;
- // Set up variables for this frame
- var rect = props.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 s1 = new Rect();
- var s2 = new Rect();
-
- if (props.Animation == LayerAnimation.SlideRight)
- {
- s1 = new Rect(new Point(rect.X + props.AnimationProgress, rect.Y), new Size(rect.Width, rect.Height));
- s2 = new Rect(new Point(s1.X - rect.Width, rect.Y), new Size(rect.Width + 1, rect.Height));
- }
- if (props.Animation == LayerAnimation.SlideLeft)
- {
- s1 = new Rect(new Point(rect.X - props.AnimationProgress, rect.Y),
- new Size(rect.Width + 0.05, rect.Height));
- s2 = new Rect(new Point(s1.X + rect.Width, rect.Y), new Size(rect.Width, rect.Height));
- }
- if (props.Animation == LayerAnimation.SlideDown)
- {
- s1 = new Rect(new Point(rect.X, rect.Y + props.AnimationProgress), new Size(rect.Width, rect.Height));
- s2 = new Rect(new Point(s1.X, s1.Y - rect.Height), new Size(rect.Width, rect.Height));
- }
- if (props.Animation == LayerAnimation.SlideUp)
- {
- s1 = new Rect(new Point(rect.X, rect.Y - props.AnimationProgress), new Size(rect.Width, rect.Height));
- 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);
- DrawRectangle(c, props, applied, clip, rect, s1, s2);
- }
-
- private static void DrawRectangle(DrawingContext c, KeyboardPropertiesModel props, AppliedProperties applied,
- Rect clip, Rect rectangle, Rect slide1, Rect slide2)
- {
- // Apply the pulse animation
- if (props.Animation == LayerAnimation.Pulse)
- applied.Brush.Opacity = (Math.Sin(props.AnimationProgress*Math.PI) + 1)*(props.Opacity/2);
- else
- applied.Brush.Opacity = props.Opacity;
-
- if (props.Animation == LayerAnimation.Grow)
- {
- // Take an offset of 4 to allow layers to slightly leave their bounds
- var progress = (6.0 - props.AnimationProgress)*10.0;
- if (progress < 0)
- {
- applied.Brush.Opacity = 1 + 0.025*progress;
- if (applied.Brush.Opacity < 0)
- applied.Brush.Opacity = 0;
- if (applied.Brush.Opacity > 1)
- applied.Brush.Opacity = 1;
- }
- rectangle.Inflate(-rectangle.Width/100.0*progress, -rectangle.Height/100.0*progress);
- clip.Inflate(-clip.Width/100.0*progress, -clip.Height/100.0*progress);
- }
-
- c.PushClip(new RectangleGeometry(clip));
- // Most animation types can be drawn regularly
- if (props.Animation == LayerAnimation.None ||
- props.Animation == LayerAnimation.Grow ||
- props.Animation == LayerAnimation.Pulse)
- {
- c.DrawRectangle(applied.Brush, null, rectangle);
- }
- // Sliding animations however, require offsetting two rects
- else
- {
- c.PushClip(new RectangleGeometry(clip));
- c.DrawRectangle(applied.Brush, null, slide1);
- c.DrawRectangle(applied.Brush, null, slide2);
- c.Pop();
- }
- c.Pop();
- }
-
- public static GifImage DrawGif(DrawingContext c, KeyboardPropertiesModel props, AppliedProperties applied,
- GifImage gifImage)
- {
- if (string.IsNullOrEmpty(props.GifFile))
- return null;
- if (!File.Exists(props.GifFile))
- return null;
-
- const int scale = 4;
-
- // Only reconstruct GifImage if the underlying source has changed
- if (gifImage == null)
- gifImage = new GifImage(props.GifFile);
- if (gifImage.Source != props.GifFile)
- gifImage = new GifImage(props.GifFile);
-
- var gifRect = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale,
- applied.Height*scale);
-
- lock (gifImage)
- {
- var draw = gifImage.GetNextFrame();
- c.DrawImage(ImageUtilities.BitmapToBitmapImage(new Bitmap(draw)), gifRect);
- }
-
- return gifImage;
- }
-
- public static void UpdateMouse(LayerPropertiesModel properties)
- {
- }
-
- public static void UpdateHeadset(LayerPropertiesModel properties)
- {
- }
-
- public static ImageSource DrawThumbnail(LayerModel layerModel)
- {
- var thumbnailRect = new Rect(0, 0, 18, 18);
- var visual = new DrawingVisual();
- using (var c = visual.RenderOpen())
- {
- // Draw the appropiate icon or draw the brush
- if (layerModel.LayerType == LayerType.Folder)
- c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.folder), thumbnailRect);
- else if (layerModel.LayerType == LayerType.Headset)
- c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.headset), thumbnailRect);
- else if (layerModel.LayerType == LayerType.Mouse)
- c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.mouse), thumbnailRect);
- else if (layerModel.LayerType == LayerType.KeyboardGif)
- c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.gif), thumbnailRect);
- else if (layerModel.LayerType == LayerType.Keyboard && layerModel.Properties.Brush != null)
- c.DrawRectangle(layerModel.Properties.Brush, new Pen(new SolidColorBrush(Colors.White), 1),
- thumbnailRect);
- }
-
- var image = new DrawingImage(visual.Drawing);
- return image;
- }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/Utilities/StickyValue.cs b/Artemis/Artemis/Utilities/StickyValue.cs
index a9ad4c1fd..7df32ae79 100644
--- a/Artemis/Artemis/Utilities/StickyValue.cs
+++ b/Artemis/Artemis/Utilities/StickyValue.cs
@@ -48,14 +48,14 @@ namespace Artemis.Utilities
{
if (_waitTime < _stickyTime)
{
- Thread.Sleep(100);
+ Thread.Sleep(10);
continue;
}
while (_waitTime > 0)
{
- Thread.Sleep(50);
- _waitTime -= 50;
+ Thread.Sleep(10);
+ _waitTime -= 10;
}
_value = _toStick;
}
diff --git a/Artemis/Artemis/ViewModels/DebugViewModel.cs b/Artemis/Artemis/ViewModels/DebugViewModel.cs
new file mode 100644
index 000000000..95e74588e
--- /dev/null
+++ b/Artemis/Artemis/ViewModels/DebugViewModel.cs
@@ -0,0 +1,58 @@
+using System.Windows;
+using System.Windows.Media;
+using Artemis.Events;
+using Caliburn.Micro;
+
+namespace Artemis.ViewModels
+{
+ public class DebugViewModel : Screen, IHandle
+ {
+ private readonly IEventAggregator _events;
+ private DrawingImage _razerDisplay;
+
+ public DebugViewModel(IEventAggregator events)
+ {
+ _events = events;
+ }
+
+ public DrawingImage RazerDisplay
+ {
+ get { return _razerDisplay; }
+ set
+ {
+ if (Equals(value, _razerDisplay)) return;
+ _razerDisplay = value;
+ NotifyOfPropertyChange(() => RazerDisplay);
+ }
+ }
+
+ public void Handle(RazerColorArrayChanged message)
+ {
+ var visual = new DrawingVisual();
+ using (var dc = visual.RenderOpen())
+ {
+ dc.PushClip(new RectangleGeometry(new Rect(0, 0, 22, 6)));
+ for (var y = 0; y < 6; y++)
+ {
+ for (var x = 0; x < 22; x++)
+ dc.DrawRectangle(new SolidColorBrush(message.Colors[y, x]), null, new Rect(x, y, 1, 1));
+ }
+ }
+ var drawnDisplay = new DrawingImage(visual.Drawing);
+ drawnDisplay.Freeze();
+ RazerDisplay = drawnDisplay;
+ }
+
+ protected override void OnActivate()
+ {
+ _events.Subscribe(this);
+ base.OnActivate();
+ }
+
+ protected override void OnDeactivate(bool close)
+ {
+ _events.Unsubscribe(this);
+ base.OnDeactivate(close);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs
index 2d927fde8..946cba921 100644
--- a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs
@@ -1,9 +1,11 @@
using System.ComponentModel;
using System.Diagnostics;
+using System.Dynamic;
using System.Linq;
using Artemis.Events;
using Artemis.Managers;
using Artemis.Settings;
+using Artemis.Utilities;
using Caliburn.Micro;
using MahApps.Metro.Controls;
using NLog;
@@ -14,15 +16,18 @@ namespace Artemis.ViewModels.Flyouts
public sealed class FlyoutSettingsViewModel : FlyoutBaseViewModel, IHandle,
IHandle
{
+ private readonly DebugViewModel _debugViewModel;
private readonly ILogger _logger;
private string _activeEffectName;
private bool _enableDebug;
private GeneralSettings _generalSettings;
private string _selectedKeyboardProvider;
- public FlyoutSettingsViewModel(MainManager mainManager, IEventAggregator events, ILogger logger)
+ public FlyoutSettingsViewModel(MainManager mainManager, IEventAggregator events, ILogger logger,
+ DebugViewModel debugViewModel)
{
_logger = logger;
+ _debugViewModel = debugViewModel;
MainManager = mainManager;
Header = "Settings";
@@ -178,6 +183,18 @@ namespace Artemis.ViewModels.Flyouts
MainManager.EnableProgram();
}
+ public void ShowDebug()
+ {
+ IWindowManager manager = new WindowManager();
+ dynamic settings = new ExpandoObject();
+ var icon = ImageUtilities.GenerateWindowIcon();
+
+ settings.Title = "Artemis | Debugger";
+ settings.Icon = icon;
+
+ manager.ShowWindow(_debugViewModel, null, settings);
+ }
+
public void ResetSettings()
{
GeneralSettings.ResetSettings();
diff --git a/Artemis/Artemis/ViewModels/Profiles/Events/EventPropertiesViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/Events/EventPropertiesViewModel.cs
new file mode 100644
index 000000000..8b1af58c7
--- /dev/null
+++ b/Artemis/Artemis/ViewModels/Profiles/Events/EventPropertiesViewModel.cs
@@ -0,0 +1,42 @@
+using System;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Utilities;
+using Caliburn.Micro;
+
+
+namespace Artemis.ViewModels.Profiles.Events
+{
+ public class EventPropertiesViewModel : PropertyChangedBase
+ {
+ private EventPropertiesModel _proposedProperties;
+
+ public EventPropertiesViewModel(EventPropertiesModel eventPropertiesModel)
+ {
+ if (eventPropertiesModel == null)
+ ProposedProperties = new KeyboardEventPropertiesModel
+ {
+ ExpirationType = ExpirationType.Time,
+ Length = new TimeSpan(0, 0, 1),
+ TriggerDelay = new TimeSpan(0)
+ };
+ else
+ ProposedProperties = GeneralHelpers.Clone(eventPropertiesModel);
+ }
+
+ public EventPropertiesModel ProposedProperties
+ {
+ get { return _proposedProperties; }
+ set
+ {
+ if (Equals(value, _proposedProperties)) return;
+ _proposedProperties = value;
+ NotifyOfPropertyChange(() => ProposedProperties);
+ }
+ }
+
+ public EventPropertiesModel GetAppliedProperties()
+ {
+ return GeneralHelpers.Clone(ProposedProperties);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Profiles/LayerConditionViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/LayerConditionViewModel.cs
index 554173910..db5f5c219 100644
--- a/Artemis/Artemis/ViewModels/Profiles/LayerConditionViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Profiles/LayerConditionViewModel.cs
@@ -1,6 +1,6 @@
using System.ComponentModel;
using System.Linq;
-using Artemis.Models.Profiles;
+using Artemis.Profiles.Layers.Models;
using Artemis.Utilities;
using Caliburn.Micro;
diff --git a/Artemis/Artemis/ViewModels/Profiles/LayerDynamicPropertiesViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/LayerDynamicPropertiesViewModel.cs
index 9505f2ef4..bd5061cbd 100644
--- a/Artemis/Artemis/ViewModels/Profiles/LayerDynamicPropertiesViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Profiles/LayerDynamicPropertiesViewModel.cs
@@ -1,10 +1,11 @@
using System.ComponentModel;
using System.Linq;
-using Artemis.Models.Profiles.Properties;
+using Artemis.Profiles.Layers.Models;
using Artemis.Utilities;
using Caliburn.Micro;
using Castle.Core.Internal;
+
namespace Artemis.ViewModels.Profiles
{
public sealed class LayerDynamicPropertiesViewModel : PropertyChangedBase
@@ -21,13 +22,13 @@ namespace Artemis.ViewModels.Profiles
public LayerDynamicPropertiesViewModel(string property,
BindableCollection dataModelProps,
- KeyboardPropertiesModel keyboardProperties)
+ LayerPropertiesModel layerPropertiesModel)
{
_property = property;
// Look for the existing property model
Proposed = new DynamicPropertiesModel();
- var original = keyboardProperties.DynamicProperties.FirstOrDefault(lp => lp.LayerProperty == _property);
+ var original = layerPropertiesModel.DynamicProperties.FirstOrDefault(lp => lp.LayerProperty == _property);
if (original == null)
{
Proposed.LayerProperty = property;
@@ -161,22 +162,22 @@ namespace Artemis.ViewModels.Profiles
case "Width":
LayerPropertyOptions = new BindableCollection
{
- Models.Profiles.Properties.LayerPropertyOptions.LeftToRight,
- Models.Profiles.Properties.LayerPropertyOptions.RightToLeft
+ Artemis.Profiles.Layers.Models.LayerPropertyOptions.LeftToRight,
+ Artemis.Profiles.Layers.Models.LayerPropertyOptions.RightToLeft
};
break;
case "Height":
LayerPropertyOptions = new BindableCollection
{
- Models.Profiles.Properties.LayerPropertyOptions.Downwards,
- Models.Profiles.Properties.LayerPropertyOptions.Upwards
+ Artemis.Profiles.Layers.Models.LayerPropertyOptions.Downwards,
+ Artemis.Profiles.Layers.Models.LayerPropertyOptions.Upwards
};
break;
case "Opacity":
LayerPropertyOptions = new BindableCollection
{
- Models.Profiles.Properties.LayerPropertyOptions.Increase,
- Models.Profiles.Properties.LayerPropertyOptions.Decrease
+ Artemis.Profiles.Layers.Models.LayerPropertyOptions.Increase,
+ Artemis.Profiles.Layers.Models.LayerPropertyOptions.Decrease
};
break;
}
@@ -206,14 +207,14 @@ namespace Artemis.ViewModels.Profiles
}
}
- public void Apply(KeyboardPropertiesModel keyboardProperties)
+ public void Apply(LayerModel layerModel)
{
- var original = keyboardProperties.DynamicProperties.FirstOrDefault(lp => lp.LayerProperty == _property);
+ var original = layerModel.Properties.DynamicProperties.FirstOrDefault(lp => lp.LayerProperty == _property);
if (original != null)
- keyboardProperties.DynamicProperties.Remove(original);
+ layerModel.Properties.DynamicProperties.Remove(original);
if (!Proposed.GameProperty.IsNullOrEmpty())
- keyboardProperties.DynamicProperties.Add(Proposed);
+ layerModel.Properties.DynamicProperties.Add(Proposed);
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs
index 46621f813..f43f71a54 100644
--- a/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs
@@ -1,14 +1,20 @@
using System;
+using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using Artemis.Models.Interfaces;
-using Artemis.Models.Profiles;
-using Artemis.Models.Profiles.Properties;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Profiles.Layers.Types.Keyboard;
+using Artemis.Profiles.Layers.Types.KeyboardGif;
using Artemis.Services;
using Artemis.Utilities;
-using Artemis.ViewModels.Profiles.Properties;
+using Artemis.ViewModels.Profiles.Events;
+using Artemis.ViewModels.Profiles.Layers;
using Caliburn.Micro;
+
+using Newtonsoft.Json;
using Ninject;
namespace Artemis.ViewModels.Profiles
@@ -16,15 +22,18 @@ namespace Artemis.ViewModels.Profiles
public sealed class LayerEditorViewModel : Screen
{
private readonly IDataModel _dataModel;
+ private readonly List _layerAnimations;
+ private EventPropertiesViewModel _eventPropertiesViewModel;
private LayerModel _layer;
private LayerPropertiesViewModel _layerPropertiesViewModel;
- private LayerType _layerType;
private LayerModel _proposedLayer;
- private LayerPropertiesModel _proposedProperties;
+ private ILayerType _selectedLayerType;
- public LayerEditorViewModel(IDataModel dataModel, LayerModel layer)
+ public LayerEditorViewModel(IDataModel dataModel, LayerModel layer, IEnumerable layerTypes,
+ List layerAnimations)
{
_dataModel = dataModel;
+ _layerAnimations = layerAnimations;
Layer = layer;
ProposedLayer = GeneralHelpers.Clone(layer);
@@ -32,26 +41,28 @@ namespace Artemis.ViewModels.Profiles
if (Layer.Properties == null)
Layer.SetupProperties();
- DataModelProps = new BindableCollection();
- DataModelProps.AddRange(GeneralHelpers.GenerateTypeMap(dataModel));
- LayerConditionVms = new BindableCollection(layer.Properties.Conditions
- .Select(c => new LayerConditionViewModel(this, c, DataModelProps)));
+ LayerTypes = new BindableCollection(layerTypes);
+ DataModelProps = new BindableCollection(
+ GeneralHelpers.GenerateTypeMap(dataModel));
+ LayerConditionVms = new BindableCollection(
+ layer.Properties.Conditions.Select(c => new LayerConditionViewModel(this, c, DataModelProps)));
PropertyChanged += PropertiesViewModelHandler;
PreSelect();
}
+
public bool ModelChanged { get; set; }
[Inject]
public MetroDialogService DialogService { get; set; }
+ public BindableCollection LayerTypes { get; set; }
public BindableCollection DataModelProps { get; set; }
-
- public BindableCollection LayerTypes => new BindableCollection();
-
public BindableCollection LayerConditionVms { get; set; }
+ public bool KeyboardGridIsVisible => ProposedLayer.LayerType is KeyboardType;
+ public bool GifGridIsVisible => ProposedLayer.LayerType is KeyboardGifType;
public LayerModel Layer
{
@@ -75,17 +86,6 @@ namespace Artemis.ViewModels.Profiles
}
}
- public LayerType LayerType
- {
- get { return _layerType; }
- set
- {
- if (value == _layerType) return;
- _layerType = value;
- NotifyOfPropertyChange(() => LayerType);
- }
- }
-
public LayerPropertiesViewModel LayerPropertiesViewModel
{
get { return _layerPropertiesViewModel; }
@@ -97,59 +97,66 @@ namespace Artemis.ViewModels.Profiles
}
}
- public bool KeyboardGridIsVisible => ProposedLayer.LayerType == LayerType.Keyboard;
- public bool GifGridIsVisible => ProposedLayer.LayerType == LayerType.KeyboardGif;
+ public EventPropertiesViewModel EventPropertiesViewModel
+ {
+ get { return _eventPropertiesViewModel; }
+ set
+ {
+ if (Equals(value, _eventPropertiesViewModel)) return;
+ _eventPropertiesViewModel = value;
+ NotifyOfPropertyChange(() => EventPropertiesViewModel);
+ }
+ }
+
+ public ILayerType SelectedLayerType
+ {
+ get { return _selectedLayerType; }
+ set
+ {
+ if (Equals(value, _selectedLayerType)) return;
+ _selectedLayerType = value;
+ NotifyOfPropertyChange(() => SelectedLayerType);
+ }
+ }
public void PreSelect()
{
- LayerType = ProposedLayer.LayerType;
-
- if (LayerType == LayerType.Folder && !(LayerPropertiesViewModel is FolderPropertiesViewModel))
- LayerPropertiesViewModel = new FolderPropertiesViewModel(_dataModel, ProposedLayer.Properties);
+ SelectedLayerType = LayerTypes.FirstOrDefault(t => t.Name == ProposedLayer.LayerType.Name);
+ ToggleIsEvent();
}
private void PropertiesViewModelHandler(object sender, PropertyChangedEventArgs e)
{
- if (e.PropertyName != "LayerType")
+ if (e.PropertyName != "SelectedLayerType")
return;
// Store the brush in case the user wants to reuse it
- var oldBrush = LayerPropertiesViewModel?.GetAppliedProperties().Brush;
+ var oldBrush = ProposedLayer.Properties.Brush;
// Update the model
- if (ProposedLayer.LayerType != LayerType)
+ if (ProposedLayer.LayerType.GetType() != SelectedLayerType.GetType())
{
- ProposedLayer.LayerType = LayerType;
+ ProposedLayer.LayerType = SelectedLayerType;
ProposedLayer.SetupProperties();
}
+ // Let the layer type handle the viewmodel setup
+ LayerPropertiesViewModel = ProposedLayer.LayerType.SetupViewModel(LayerPropertiesViewModel, _layerAnimations,
+ _dataModel, ProposedLayer);
+
if (oldBrush != null)
ProposedLayer.Properties.Brush = oldBrush;
- // Update the KeyboardPropertiesViewModel if it's being used
- var model = LayerPropertiesViewModel as KeyboardPropertiesViewModel;
- if (model != null)
- model.IsGif = LayerType == LayerType.KeyboardGif;
-
- // Apply the proper PropertiesViewModel
- if ((LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif) &&
- !(LayerPropertiesViewModel is KeyboardPropertiesViewModel))
- {
- LayerPropertiesViewModel = new KeyboardPropertiesViewModel(_dataModel, ProposedLayer.Properties)
- {
- IsGif = LayerType == LayerType.KeyboardGif
- };
- }
- else if (LayerType == LayerType.Mouse && !(LayerPropertiesViewModel is MousePropertiesViewModel))
- LayerPropertiesViewModel = new MousePropertiesViewModel(_dataModel, ProposedLayer.Properties);
- else if (LayerType == LayerType.Headset && !(LayerPropertiesViewModel is HeadsetPropertiesViewModel))
- LayerPropertiesViewModel = new HeadsetPropertiesViewModel(_dataModel, ProposedLayer.Properties);
- else if (LayerType == LayerType.Folder && !(LayerPropertiesViewModel is FolderPropertiesViewModel))
- LayerPropertiesViewModel = new FolderPropertiesViewModel(_dataModel, ProposedLayer.Properties);
-
NotifyOfPropertyChange(() => LayerPropertiesViewModel);
}
+ public void ToggleIsEvent()
+ {
+ EventPropertiesViewModel = ProposedLayer.IsEvent
+ ? new EventPropertiesViewModel(Layer.EventProperties)
+ : null;
+ }
+
public void AddCondition()
{
var condition = new LayerConditionModel();
@@ -158,19 +165,20 @@ namespace Artemis.ViewModels.Profiles
public void Apply()
{
- Layer.Name = ProposedLayer.Name;
- Layer.LayerType = ProposedLayer.LayerType;
+ LayerPropertiesViewModel?.ApplyProperties();
+ Layer = GeneralHelpers.Clone(ProposedLayer);
+
+ // TODO: EventPropVM must have layer too
+ if (EventPropertiesViewModel != null)
+ Layer.EventProperties = EventPropertiesViewModel.GetAppliedProperties();
- if (LayerPropertiesViewModel != null)
- Layer.Properties = LayerPropertiesViewModel.GetAppliedProperties();
Layer.Properties.Conditions.Clear();
foreach (var conditionViewModel in LayerConditionVms)
- {
Layer.Properties.Conditions.Add(conditionViewModel.LayerConditionModel);
- }
- if (Layer.LayerType != LayerType.KeyboardGif)
- return; // Don't bother checking for a GIF path unless the type is GIF
+ // Don't bother checking for a GIF path unless the type is GIF
+ if (!(Layer.LayerType is KeyboardGifType))
+ return;
if (!File.Exists(((KeyboardPropertiesModel) Layer.Properties).GifFile))
DialogService.ShowErrorMessageBox("Couldn't find or access the provided GIF file.");
}
@@ -185,25 +193,26 @@ namespace Artemis.ViewModels.Profiles
public override async void CanClose(Action callback)
{
// Create a fake layer and apply the properties to it
- var fakeLayer = GeneralHelpers.Clone(ProposedLayer);
- if (LayerPropertiesViewModel != null)
- fakeLayer.Properties = LayerPropertiesViewModel.GetAppliedProperties();
- fakeLayer.Properties.Conditions.Clear();
+ LayerPropertiesViewModel?.ApplyProperties();
+ // TODO: EventPropVM must have layer too
+ if (EventPropertiesViewModel != null)
+ ProposedLayer.EventProperties = EventPropertiesViewModel.GetAppliedProperties();
+ ProposedLayer.Properties.Conditions.Clear();
foreach (var conditionViewModel in LayerConditionVms)
- fakeLayer.Properties.Conditions.Add(conditionViewModel.LayerConditionModel);
+ ProposedLayer.Properties.Conditions.Add(conditionViewModel.LayerConditionModel);
- var fake = GeneralHelpers.Serialize(fakeLayer);
- var real = GeneralHelpers.Serialize(Layer);
+ var current = JsonConvert.SerializeObject(Layer, Formatting.Indented);
+ var proposed = JsonConvert.SerializeObject(ProposedLayer, Formatting.Indented);
- if (fake.Equals(real))
+ if (current.Equals(proposed))
{
callback(true);
return;
}
- var close =
- await DialogService.ShowQuestionMessageBox("Unsaved changes", "Do you want to discard your changes?");
+ var close = await DialogService
+ .ShowQuestionMessageBox("Unsaved changes", "Do you want to discard your changes?");
callback(close.Value);
}
}
diff --git a/Artemis/Artemis/ViewModels/Profiles/Layers/FolderPropertiesViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/Layers/FolderPropertiesViewModel.cs
new file mode 100644
index 000000000..fd0ffaf50
--- /dev/null
+++ b/Artemis/Artemis/ViewModels/Profiles/Layers/FolderPropertiesViewModel.cs
@@ -0,0 +1,16 @@
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.ViewModels.Profiles.Layers
+{
+ public class FolderPropertiesViewModel : LayerPropertiesViewModel
+ {
+ public FolderPropertiesViewModel(LayerModel layerModel, IDataModel dataModel) : base(layerModel, dataModel)
+ {
+ }
+
+ public override void ApplyProperties()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Profiles/Layers/HeadsetPropertiesViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/Layers/HeadsetPropertiesViewModel.cs
new file mode 100644
index 000000000..8c3eb2906
--- /dev/null
+++ b/Artemis/Artemis/ViewModels/Profiles/Layers/HeadsetPropertiesViewModel.cs
@@ -0,0 +1,44 @@
+using System.Collections.Generic;
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Utilities;
+using Caliburn.Micro;
+
+namespace Artemis.ViewModels.Profiles.Layers
+{
+ public class HeadsetPropertiesViewModel : LayerPropertiesViewModel
+ {
+ private ILayerAnimation _selectedLayerAnimation;
+
+ public HeadsetPropertiesViewModel(LayerModel layerModel, IDataModel dataModel,
+ IEnumerable layerAnimations) : base(layerModel, dataModel)
+ {
+ LayerAnimations = new BindableCollection(layerAnimations);
+ OpacityProperties = new LayerDynamicPropertiesViewModel("Opacity",
+ new BindableCollection(GeneralHelpers.GenerateTypeMap(dataModel)),
+ layerModel.Properties);
+ }
+
+ public BindableCollection LayerAnimations { get; set; }
+ public LayerDynamicPropertiesViewModel OpacityProperties { get; set; }
+
+ public ILayerAnimation SelectedLayerAnimation
+ {
+ get { return _selectedLayerAnimation; }
+ set
+ {
+ if (Equals(value, _selectedLayerAnimation)) return;
+ _selectedLayerAnimation = value;
+ NotifyOfPropertyChange(() => SelectedLayerAnimation);
+ }
+ }
+
+ public override void ApplyProperties()
+ {
+ OpacityProperties.Apply(LayerModel);
+ LayerModel.Properties.Brush = Brush;
+ LayerModel.LayerAnimation = SelectedLayerAnimation;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Profiles/Layers/KeyboardPropertiesViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/Layers/KeyboardPropertiesViewModel.cs
new file mode 100644
index 000000000..28a935a4d
--- /dev/null
+++ b/Artemis/Artemis/ViewModels/Profiles/Layers/KeyboardPropertiesViewModel.cs
@@ -0,0 +1,83 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Profiles.Layers.Types.Keyboard;
+using Caliburn.Micro;
+using static Artemis.Utilities.GeneralHelpers;
+
+namespace Artemis.ViewModels.Profiles.Layers
+{
+ public class KeyboardPropertiesViewModel : LayerPropertiesViewModel
+ {
+ private bool _isGif;
+ private ILayerAnimation _selectedLayerAnimation;
+
+ public KeyboardPropertiesViewModel(LayerModel layerModel, IDataModel dataModel,
+ IEnumerable layerAnimations) : base(layerModel, dataModel)
+ {
+ LayerAnimations = new BindableCollection(layerAnimations);
+
+ var dataModelProps = new BindableCollection(GenerateTypeMap(dataModel));
+ HeightProperties = new LayerDynamicPropertiesViewModel("Height", dataModelProps, layerModel.Properties);
+ WidthProperties = new LayerDynamicPropertiesViewModel("Width", dataModelProps, layerModel.Properties);
+ OpacityProperties = new LayerDynamicPropertiesViewModel("Opacity", dataModelProps, layerModel.Properties);
+
+ SelectedLayerAnimation = LayerAnimations.FirstOrDefault(l => l.Name == layerModel.LayerAnimation?.Name) ??
+ LayerAnimations.First(l => l.Name == "None");
+ }
+
+ public bool ShowGif => IsGif;
+ public bool ShowBrush => !IsGif;
+ public BindableCollection DataModelProps { get; set; }
+ public BindableCollection LayerAnimations { get; set; }
+ public LayerDynamicPropertiesViewModel HeightProperties { get; set; }
+ public LayerDynamicPropertiesViewModel WidthProperties { get; set; }
+ public LayerDynamicPropertiesViewModel OpacityProperties { get; set; }
+
+ public bool IsGif
+ {
+ get { return _isGif; }
+ set
+ {
+ _isGif = value;
+ NotifyOfPropertyChange(() => ShowGif);
+ NotifyOfPropertyChange(() => ShowBrush);
+ }
+ }
+
+ public ILayerAnimation SelectedLayerAnimation
+ {
+ get { return _selectedLayerAnimation; }
+ set
+ {
+ if (Equals(value, _selectedLayerAnimation)) return;
+ _selectedLayerAnimation = value;
+ NotifyOfPropertyChange(() => SelectedLayerAnimation);
+ }
+ }
+
+ public void BrowseGif()
+ {
+ var dialog = new OpenFileDialog {Filter = "Animated image file (*.gif)|*.gif"};
+ var result = dialog.ShowDialog();
+ if (result != DialogResult.OK)
+ return;
+
+ ((KeyboardPropertiesModel) LayerModel.Properties).GifFile = dialog.FileName;
+ NotifyOfPropertyChange(() => LayerModel);
+ }
+
+ public override void ApplyProperties()
+ {
+ HeightProperties.Apply(LayerModel);
+ WidthProperties.Apply(LayerModel);
+ OpacityProperties.Apply(LayerModel);
+ LayerModel.Properties.Brush = Brush;
+
+ LayerModel.LayerAnimation = SelectedLayerAnimation;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Profiles/Layers/LayerPropertiesViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/Layers/LayerPropertiesViewModel.cs
new file mode 100644
index 000000000..f633520b0
--- /dev/null
+++ b/Artemis/Artemis/ViewModels/Profiles/Layers/LayerPropertiesViewModel.cs
@@ -0,0 +1,47 @@
+using System.Drawing;
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Models;
+using Caliburn.Micro;
+using Brush = System.Windows.Media.Brush;
+
+namespace Artemis.ViewModels.Profiles.Layers
+{
+ public abstract class LayerPropertiesViewModel : PropertyChangedBase
+ {
+ private LayerModel _layerModel;
+ private Brush _brush;
+
+ protected LayerPropertiesViewModel(LayerModel layerModel, IDataModel dataModel)
+ {
+ LayerModel = layerModel;
+ DataModel = dataModel;
+ Brush = LayerModel.Properties.Brush.Clone();
+ }
+
+ public Brush Brush
+ {
+ get { return _brush; }
+ set
+ {
+ if (Equals(value, _brush)) return;
+ _brush = value;
+ NotifyOfPropertyChange(() => Brush);
+ }
+ }
+
+ public LayerModel LayerModel
+ {
+ get { return _layerModel; }
+ set
+ {
+ if (Equals(value, _layerModel)) return;
+ _layerModel = value;
+ NotifyOfPropertyChange(() => LayerModel);
+ }
+ }
+
+ public IDataModel DataModel { get; set; }
+
+ public abstract void ApplyProperties();
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Profiles/Layers/MousePropertiesViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/Layers/MousePropertiesViewModel.cs
new file mode 100644
index 000000000..0bfbc0eaa
--- /dev/null
+++ b/Artemis/Artemis/ViewModels/Profiles/Layers/MousePropertiesViewModel.cs
@@ -0,0 +1,48 @@
+using System.Collections.Generic;
+using System.Linq;
+using Artemis.Models.Interfaces;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Utilities;
+using Caliburn.Micro;
+
+namespace Artemis.ViewModels.Profiles.Layers
+{
+ public class MousePropertiesViewModel : LayerPropertiesViewModel
+ {
+ private ILayerAnimation _selectedLayerAnimation;
+
+ public MousePropertiesViewModel(LayerModel layerModel, IDataModel dataModel,
+ IEnumerable layerAnimations) : base(layerModel, dataModel)
+ {
+ LayerAnimations = new BindableCollection(layerAnimations);
+ OpacityProperties = new LayerDynamicPropertiesViewModel("Opacity",
+ new BindableCollection(GeneralHelpers.GenerateTypeMap(dataModel)),
+ layerModel.Properties);
+
+ SelectedLayerAnimation = LayerAnimations.FirstOrDefault(l => l.Name == layerModel.LayerAnimation.Name) ??
+ LayerAnimations.First(l => l.Name == "None");
+ }
+
+ public BindableCollection LayerAnimations { get; set; }
+ public LayerDynamicPropertiesViewModel OpacityProperties { get; set; }
+
+ public ILayerAnimation SelectedLayerAnimation
+ {
+ get { return _selectedLayerAnimation; }
+ set
+ {
+ if (Equals(value, _selectedLayerAnimation)) return;
+ _selectedLayerAnimation = value;
+ NotifyOfPropertyChange(() => SelectedLayerAnimation);
+ }
+ }
+
+ public override void ApplyProperties()
+ {
+ OpacityProperties.Apply(LayerModel);
+ LayerModel.Properties.Brush = Brush;
+ LayerModel.LayerAnimation = SelectedLayerAnimation;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs
index e28eed39d..acda2190d 100644
--- a/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs
@@ -3,27 +3,26 @@ using System.Dynamic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
-using System.Windows.Media.Imaging;
using Artemis.DAL;
using Artemis.DeviceProviders;
using Artemis.Events;
using Artemis.InjectionFactories;
using Artemis.Managers;
using Artemis.Models;
-using Artemis.Models.Profiles;
+using Artemis.Profiles;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Profiles.Layers.Types.Folder;
using Artemis.Services;
using Artemis.Styles.DropTargetAdorners;
using Artemis.Utilities;
using Caliburn.Micro;
using GongSolutions.Wpf.DragDrop;
using MahApps.Metro.Controls.Dialogs;
+
using Ninject;
-using Application = System.Windows.Application;
using DragDropEffects = System.Windows.DragDropEffects;
using IDropTarget = GongSolutions.Wpf.DragDrop.IDropTarget;
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
@@ -131,7 +130,7 @@ namespace Artemis.ViewModels.Profiles
return;
if (dropInfo.InsertPosition == RelativeInsertPosition.TargetItemCenter &&
- target.LayerType == LayerType.Folder)
+ target.LayerType is FolderType)
{
dropInfo.DropTargetAdorner = typeof(DropTargetMetroHighlightAdorner);
dropInfo.Effects = DragDropEffects.Copy;
@@ -169,7 +168,7 @@ namespace Artemis.ViewModels.Profiles
}
if (dropInfo.InsertPosition == RelativeInsertPosition.TargetItemCenter &&
- target.LayerType == LayerType.Folder)
+ target.LayerType is FolderType)
{
// Insert into folder
source.Order = -1;
@@ -257,7 +256,7 @@ namespace Artemis.ViewModels.Profiles
public void EditLayerFromDoubleClick()
{
- if (ProfileViewModel.SelectedLayer?.LayerType == LayerType.Folder)
+ if (ProfileViewModel.SelectedLayer?.LayerType is FolderType)
return;
EditLayer();
@@ -280,23 +279,19 @@ namespace Artemis.ViewModels.Profiles
IWindowManager manager = new WindowManager();
var editorVm = _layerEditorVmFactory.CreateLayerEditorVm(_gameModel.DataModel, layer);
dynamic settings = new ExpandoObject();
- var iconImage = new Image
- {
- Source = (DrawingImage) Application.Current.MainWindow.Resources["BowIcon"],
- Stretch = Stretch.Uniform,
- Margin = new Thickness(20)
- };
- iconImage.Arrange(new Rect(0, 0, 100, 100));
- var bitmap = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32);
- bitmap.Render(iconImage);
+ var icon = ImageUtilities.GenerateWindowIcon();
settings.Title = "Artemis | Edit " + layer.Name;
- settings.Icon = bitmap;
+ settings.Icon = icon;
manager.ShowDialog(editorVm, null, settings);
+ // The layer editor VM may have created a new instance of the layer, reapply it to the list
+ layer.Replace(editorVm.Layer);
+ layer = editorVm.Layer;
+
// If the layer was a folder, but isn't anymore, assign it's children to it's parent.
- if (layer.LayerType != LayerType.Folder && layer.Children.Any())
+ if (!(layer.LayerType is FolderType) && layer.Children.Any())
{
while (layer.Children.Any())
{
@@ -596,7 +591,7 @@ namespace Artemis.ViewModels.Profiles
"To import a profile, please select a keyboard in the options menu first.");
return;
}
- var dialog = new OpenFileDialog {Filter = "Artemis profile (*.xml)|*.xml"};
+ var dialog = new OpenFileDialog {Filter = "Artemis profile (*.json)|*.json"};
var result = dialog.ShowDialog();
if (result != DialogResult.OK)
return;
@@ -654,7 +649,7 @@ namespace Artemis.ViewModels.Profiles
if (SelectedProfile == null)
return;
- var dialog = new SaveFileDialog {Filter = "Artemis profile (*.xml)|*.xml"};
+ var dialog = new SaveFileDialog {Filter = "Artemis profile (*.json)|*.json"};
var result = dialog.ShowDialog();
if (result != DialogResult.OK)
return;
diff --git a/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs
index 660673f9c..4f7b0aede 100644
--- a/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs
@@ -7,9 +7,10 @@ using System.Windows.Input;
using System.Windows.Media;
using Artemis.Events;
using Artemis.Managers;
-using Artemis.Models.Profiles;
-using Artemis.Models.Profiles.Properties;
using Artemis.Modules.Effects.ProfilePreview;
+using Artemis.Profiles;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Profiles.Layers.Types.Keyboard;
using Artemis.Properties;
using Artemis.Utilities;
using Caliburn.Micro;
@@ -109,10 +110,12 @@ namespace Artemis.ViewModels.Profiles
drawingContext.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect);
// Draw the layers
- var drawLayers = SelectedProfile.GetRenderLayers(
- new ProfilePreviewDataModel(), false, false, true);
+ var drawLayers = SelectedProfile.GetRenderLayers(new ProfilePreviewDataModel(), false, false, true);
foreach (var layer in drawLayers)
+ {
+ layer.Update(null, true, false);
layer.Draw(null, drawingContext, true, false);
+ }
// Get the selection color
var accentColor = ThemeManager.DetectAppStyle(Application.Current)?.Item2?.Resources["AccentColor"];
diff --git a/Artemis/Artemis/ViewModels/Profiles/Properties/FolderPropertiesViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/Properties/FolderPropertiesViewModel.cs
deleted file mode 100644
index 4a0cb16e1..000000000
--- a/Artemis/Artemis/ViewModels/Profiles/Properties/FolderPropertiesViewModel.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using Artemis.Models.Interfaces;
-using Artemis.Models.Profiles.Properties;
-using Artemis.Utilities;
-
-namespace Artemis.ViewModels.Profiles.Properties
-{
- public class FolderPropertiesViewModel : LayerPropertiesViewModel
- {
- private LayerPropertiesModel _proposedProperties;
-
- public FolderPropertiesViewModel(IDataModel dataModel, LayerPropertiesModel properties)
- : base(dataModel)
- {
- ProposedProperties = GeneralHelpers.Clone(properties);
- }
-
- public LayerPropertiesModel ProposedProperties
- {
- get { return _proposedProperties; }
- set
- {
- if (Equals(value, _proposedProperties)) return;
- _proposedProperties = value;
- NotifyOfPropertyChange(() => ProposedProperties);
- }
- }
-
- public override LayerPropertiesModel GetAppliedProperties()
- {
- return GeneralHelpers.Clone(ProposedProperties);
- }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Profiles/Properties/HeadsetPropertiesViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/Properties/HeadsetPropertiesViewModel.cs
deleted file mode 100644
index 23d853420..000000000
--- a/Artemis/Artemis/ViewModels/Profiles/Properties/HeadsetPropertiesViewModel.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System.Windows.Media;
-using Artemis.Models.Interfaces;
-using Artemis.Models.Profiles.Properties;
-using Artemis.Utilities;
-
-namespace Artemis.ViewModels.Profiles.Properties
-{
- public class HeadsetPropertiesViewModel : LayerPropertiesViewModel
- {
- private Brush _brush;
- private LayerPropertiesModel _proposedProperties;
-
- public HeadsetPropertiesViewModel(IDataModel dataModel, LayerPropertiesModel properties)
- : base(dataModel)
- {
- ProposedProperties = GeneralHelpers.Clone(properties);
- Brush = ProposedProperties.Brush.CloneCurrentValue();
- }
-
- public Brush Brush
- {
- get { return _brush; }
- set
- {
- if (Equals(value, _brush)) return;
- _brush = value;
- NotifyOfPropertyChange(() => Brush);
- }
- }
-
- public LayerPropertiesModel ProposedProperties
- {
- get { return _proposedProperties; }
- set
- {
- if (Equals(value, _proposedProperties)) return;
- _proposedProperties = value;
- NotifyOfPropertyChange(() => ProposedProperties);
- }
- }
-
- public override LayerPropertiesModel GetAppliedProperties()
- {
- var properties = GeneralHelpers.Clone(ProposedProperties);
- properties.Brush = Brush;
- return properties;
- }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Profiles/Properties/KeyboardPropertiesViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/Properties/KeyboardPropertiesViewModel.cs
deleted file mode 100644
index 1359dbed5..000000000
--- a/Artemis/Artemis/ViewModels/Profiles/Properties/KeyboardPropertiesViewModel.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-using System.Windows.Forms;
-using System.Windows.Media;
-using Artemis.Models.Interfaces;
-using Artemis.Models.Profiles.Properties;
-using Artemis.Utilities;
-using Caliburn.Micro;
-
-namespace Artemis.ViewModels.Profiles.Properties
-{
- public class KeyboardPropertiesViewModel : LayerPropertiesViewModel
- {
- private Brush _brush;
- private bool _isGif;
- private KeyboardPropertiesModel _proposedProperties;
-
- public KeyboardPropertiesViewModel(IDataModel dataModel, LayerPropertiesModel properties)
- : base(dataModel)
- {
- var keyboardProperties = (KeyboardPropertiesModel) properties;
- ProposedProperties = GeneralHelpers.Clone(keyboardProperties);
- Brush = ProposedProperties.Brush.CloneCurrentValue();
-
- DataModelProps = new BindableCollection();
- DataModelProps.AddRange(GeneralHelpers.GenerateTypeMap(dataModel));
-
- HeightProperties = new LayerDynamicPropertiesViewModel("Height", DataModelProps, keyboardProperties);
- WidthProperties = new LayerDynamicPropertiesViewModel("Width", DataModelProps, keyboardProperties);
- OpacityProperties = new LayerDynamicPropertiesViewModel("Opacity", DataModelProps, keyboardProperties);
- }
-
-
- public KeyboardPropertiesModel ProposedProperties
- {
- get { return _proposedProperties; }
- set
- {
- if (Equals(value, _proposedProperties)) return;
- _proposedProperties = value;
- NotifyOfPropertyChange(() => ProposedProperties);
- }
- }
-
- public bool IsGif
- {
- get { return _isGif; }
- set
- {
- _isGif = value;
- NotifyOfPropertyChange(() => ShowGif);
- NotifyOfPropertyChange(() => ShowBrush);
- }
- }
-
- public Brush Brush
- {
- get { return _brush; }
- set
- {
- if (Equals(value, _brush)) return;
- _brush = value;
- NotifyOfPropertyChange(() => Brush);
- }
- }
-
- public bool ShowGif => IsGif;
-
- public bool ShowBrush => !IsGif;
-
- public BindableCollection DataModelProps { get; set; }
-
- public LayerDynamicPropertiesViewModel HeightProperties { get; set; }
-
- public LayerDynamicPropertiesViewModel WidthProperties { get; set; }
-
- public LayerDynamicPropertiesViewModel OpacityProperties { get; set; }
-
- public void BrowseGif()
- {
- var dialog = new OpenFileDialog {Filter = "Animated image file (*.gif)|*.gif"};
- var result = dialog.ShowDialog();
- if (result != DialogResult.OK)
- return;
-
- ProposedProperties.GifFile = dialog.FileName;
- NotifyOfPropertyChange(() => ProposedProperties);
- }
-
- public override LayerPropertiesModel GetAppliedProperties()
- {
- HeightProperties.Apply(ProposedProperties);
- WidthProperties.Apply(ProposedProperties);
- OpacityProperties.Apply(ProposedProperties);
-
- var properties = GeneralHelpers.Clone(ProposedProperties);
- properties.Brush = Brush;
- return properties;
- }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Profiles/Properties/LayerPropertiesViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/Properties/LayerPropertiesViewModel.cs
deleted file mode 100644
index 5cbc63f5b..000000000
--- a/Artemis/Artemis/ViewModels/Profiles/Properties/LayerPropertiesViewModel.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using Artemis.Models.Interfaces;
-using Artemis.Models.Profiles.Properties;
-using Caliburn.Micro;
-
-namespace Artemis.ViewModels.Profiles.Properties
-{
- public abstract class LayerPropertiesViewModel : PropertyChangedBase
- {
- protected LayerPropertiesViewModel(IDataModel dataModel)
- {
- DataModel = dataModel;
- }
-
- public IDataModel DataModel { get; set; }
-
- public abstract LayerPropertiesModel GetAppliedProperties();
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Profiles/Properties/MousePropertiesViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/Properties/MousePropertiesViewModel.cs
deleted file mode 100644
index 85106eff9..000000000
--- a/Artemis/Artemis/ViewModels/Profiles/Properties/MousePropertiesViewModel.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System.Windows.Media;
-using Artemis.Models.Interfaces;
-using Artemis.Models.Profiles.Properties;
-using Artemis.Utilities;
-
-namespace Artemis.ViewModels.Profiles.Properties
-{
- public class MousePropertiesViewModel : LayerPropertiesViewModel
- {
- private Brush _brush;
- private LayerPropertiesModel _proposedProperties;
-
- public MousePropertiesViewModel(IDataModel dataModel, LayerPropertiesModel properties)
- : base(dataModel)
- {
- ProposedProperties = GeneralHelpers.Clone(properties);
- Brush = ProposedProperties.Brush.CloneCurrentValue();
- }
-
- public Brush Brush
- {
- get { return _brush; }
- set
- {
- if (Equals(value, _brush)) return;
- _brush = value;
- NotifyOfPropertyChange(() => Brush);
- }
- }
-
- public LayerPropertiesModel ProposedProperties
- {
- get { return _proposedProperties; }
- set
- {
- if (Equals(value, _proposedProperties)) return;
- _proposedProperties = value;
- NotifyOfPropertyChange(() => ProposedProperties);
- }
- }
-
- public override LayerPropertiesModel GetAppliedProperties()
- {
- var properties = GeneralHelpers.Clone(ProposedProperties);
- properties.Brush = Brush;
- return properties;
- }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/ShellViewModel.cs b/Artemis/Artemis/ViewModels/ShellViewModel.cs
index e7a6f4fba..e8cc77059 100644
--- a/Artemis/Artemis/ViewModels/ShellViewModel.cs
+++ b/Artemis/Artemis/ViewModels/ShellViewModel.cs
@@ -1,5 +1,4 @@
using System.Linq;
-using System.Threading.Tasks;
using Artemis.Managers;
using Artemis.Services;
using Artemis.ViewModels.Abstract;
@@ -42,7 +41,7 @@ namespace Artemis.ViewModels
ActiveItem = _viewModels.FirstOrDefault();
}
-
+
public void Settings()
{
Flyouts.First().IsOpen = !Flyouts.First().IsOpen;
diff --git a/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs b/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs
index 33cdc0fca..c4b4223f5 100644
--- a/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs
+++ b/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs
@@ -1,5 +1,4 @@
using System;
-using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using Artemis.Events;
@@ -8,7 +7,6 @@ using Artemis.Services;
using Artemis.Settings;
using Artemis.Utilities;
using Caliburn.Micro;
-using Ninject;
namespace Artemis.ViewModels
{
@@ -21,7 +19,8 @@ namespace Artemis.ViewModels
private bool _enabled;
private string _toggleText;
- public SystemTrayViewModel(IWindowManager windowManager, IEventAggregator events, MetroDialogService dialogService, ShellViewModel shellViewModel,
+ public SystemTrayViewModel(IWindowManager windowManager, IEventAggregator events,
+ MetroDialogService dialogService, ShellViewModel shellViewModel,
MainManager mainManager)
{
_windowManager = windowManager;
@@ -125,7 +124,7 @@ namespace Artemis.ViewModels
private async void ShowKeyboardDialog()
{
- while(!_shellViewModel.IsActive)
+ while (!_shellViewModel.IsActive)
await Task.Delay(200);
NotifyOfPropertyChange(() => CanHideWindow);
diff --git a/Artemis/Artemis/Views/DebugView.xaml b/Artemis/Artemis/Views/DebugView.xaml
new file mode 100644
index 000000000..5c9dd7b8d
--- /dev/null
+++ b/Artemis/Artemis/Views/DebugView.xaml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Views/DebugView.xaml.cs b/Artemis/Artemis/Views/DebugView.xaml.cs
new file mode 100644
index 000000000..f08610dab
--- /dev/null
+++ b/Artemis/Artemis/Views/DebugView.xaml.cs
@@ -0,0 +1,15 @@
+using MahApps.Metro.Controls;
+
+namespace Artemis.Views
+{
+ ///
+ /// Interaction logic for DebugView.xaml
+ ///
+ public partial class DebugView : MetroWindow
+ {
+ public DebugView()
+ {
+ InitializeComponent();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml b/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml
index 105fdbd39..1ea2699c1 100644
--- a/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml
+++ b/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml
@@ -4,24 +4,10 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
- xmlns:cal="http://www.caliburnproject.org"
- xmlns:utilities="clr-namespace:Artemis.Utilities"
- xmlns:sys="clr-namespace:System;assembly=mscorlib"
- xmlns:profileEnumerations="clr-namespace:Artemis.Models.Profiles"
+ xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="300"
Width="300">
-
-
-
-
-
-
-
-
-
@@ -38,6 +24,7 @@
+
@@ -103,17 +90,20 @@
+
-
-
-
+
diff --git a/Artemis/Artemis/Views/Profiles/Events/EventPropertiesView.xaml b/Artemis/Artemis/Views/Profiles/Events/EventPropertiesView.xaml
new file mode 100644
index 000000000..7418f57ed
--- /dev/null
+++ b/Artemis/Artemis/Views/Profiles/Events/EventPropertiesView.xaml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Views/Profiles/Events/EventPropertiesView.xaml.cs b/Artemis/Artemis/Views/Profiles/Events/EventPropertiesView.xaml.cs
new file mode 100644
index 000000000..b338b038c
--- /dev/null
+++ b/Artemis/Artemis/Views/Profiles/Events/EventPropertiesView.xaml.cs
@@ -0,0 +1,15 @@
+using System.Windows.Controls;
+
+namespace Artemis.Views.Profiles.Events
+{
+ ///
+ /// Interaction logic for EventPropertiesView.xaml
+ ///
+ public partial class EventPropertiesView : UserControl
+ {
+ public EventPropertiesView()
+ {
+ InitializeComponent();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Views/Profiles/LayerDynamicPropertiesView.xaml b/Artemis/Artemis/Views/Profiles/LayerDynamicPropertiesView.xaml
index 500c6ae18..1a748e4a0 100644
--- a/Artemis/Artemis/Views/Profiles/LayerDynamicPropertiesView.xaml
+++ b/Artemis/Artemis/Views/Profiles/LayerDynamicPropertiesView.xaml
@@ -6,15 +6,16 @@
xmlns:utilities="clr-namespace:Artemis.Utilities"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
- xmlns:properties="clr-namespace:Artemis.Models.Profiles.Properties"
+ xmlns:models="clr-namespace:Artemis.Profiles.Layers.Models"
+ xmlns:converters="clr-namespace:Artemis.Utilities.Converters"
mc:Ignorable="d"
d:DesignHeight="40" d:DesignWidth="500">
-
+
-
+
diff --git a/Artemis/Artemis/Views/Profiles/LayerEditorView.xaml b/Artemis/Artemis/Views/Profiles/LayerEditorView.xaml
index a6655937f..b804c475f 100644
--- a/Artemis/Artemis/Views/Profiles/LayerEditorView.xaml
+++ b/Artemis/Artemis/Views/Profiles/LayerEditorView.xaml
@@ -7,28 +7,11 @@
xmlns:utilities="clr-namespace:Artemis.Utilities"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
- Title="Artemis | Edit Layer" Height="750" Width="630"
- xmlns:profileEnumerations="clr-namespace:Artemis.Models.Profiles"
+ Title="Artemis | Edit Layer" Height="820" Width="630"
+ xmlns:cal="http://www.caliburnproject.org"
GlowBrush="{DynamicResource AccentColorBrush}" Icon="../../Resources/bow.png"
ResizeMode="NoResize">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -36,34 +19,57 @@
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
@@ -74,7 +80,7 @@
-
@@ -83,14 +89,21 @@
Content="Advanced" Width="97" VerticalAlignment="Bottom" />
-
+
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Views/Profiles/Properties/FolderPropertiesView.xaml b/Artemis/Artemis/Views/Profiles/Layers/FolderPropertiesView.xaml
similarity index 90%
rename from Artemis/Artemis/Views/Profiles/Properties/FolderPropertiesView.xaml
rename to Artemis/Artemis/Views/Profiles/Layers/FolderPropertiesView.xaml
index 285b8f72c..d4493cfa5 100644
--- a/Artemis/Artemis/Views/Profiles/Properties/FolderPropertiesView.xaml
+++ b/Artemis/Artemis/Views/Profiles/Layers/FolderPropertiesView.xaml
@@ -1,4 +1,4 @@
-
/// Interaction logic for FolderPropertiesView.xaml
diff --git a/Artemis/Artemis/Views/Profiles/Properties/HeadsetPropertiesView.xaml b/Artemis/Artemis/Views/Profiles/Layers/HeadsetPropertiesView.xaml
similarity index 95%
rename from Artemis/Artemis/Views/Profiles/Properties/HeadsetPropertiesView.xaml
rename to Artemis/Artemis/Views/Profiles/Layers/HeadsetPropertiesView.xaml
index 0598c241d..46796f59a 100644
--- a/Artemis/Artemis/Views/Profiles/Properties/HeadsetPropertiesView.xaml
+++ b/Artemis/Artemis/Views/Profiles/Layers/HeadsetPropertiesView.xaml
@@ -1,4 +1,4 @@
-
/// Interaction logic for HeadsetPropertiesView.xaml
diff --git a/Artemis/Artemis/Views/Profiles/Properties/KeyboardPropertiesView.xaml b/Artemis/Artemis/Views/Profiles/Layers/KeyboardPropertiesView.xaml
similarity index 76%
rename from Artemis/Artemis/Views/Profiles/Properties/KeyboardPropertiesView.xaml
rename to Artemis/Artemis/Views/Profiles/Layers/KeyboardPropertiesView.xaml
index 907c69cc5..4c0d85e02 100644
--- a/Artemis/Artemis/Views/Profiles/Properties/KeyboardPropertiesView.xaml
+++ b/Artemis/Artemis/Views/Profiles/Layers/KeyboardPropertiesView.xaml
@@ -1,25 +1,12 @@
-
-
-
-
-
-
-
-
-
+ d:DesignHeight="500" d:DesignWidth="500">
@@ -41,12 +28,10 @@
-
+
-
+
@@ -56,13 +41,13 @@
VerticalAlignment="Center" Height="18" />
-
+ Text="{Binding Path=LayerModel.Properties.GifFile, Mode=TwoWay}" />
diff --git a/Artemis/Artemis/Views/Profiles/Properties/KeyboardPropertiesView.xaml.cs b/Artemis/Artemis/Views/Profiles/Layers/KeyboardPropertiesView.xaml.cs
similarity index 87%
rename from Artemis/Artemis/Views/Profiles/Properties/KeyboardPropertiesView.xaml.cs
rename to Artemis/Artemis/Views/Profiles/Layers/KeyboardPropertiesView.xaml.cs
index ec49312dd..c63f3beea 100644
--- a/Artemis/Artemis/Views/Profiles/Properties/KeyboardPropertiesView.xaml.cs
+++ b/Artemis/Artemis/Views/Profiles/Layers/KeyboardPropertiesView.xaml.cs
@@ -1,6 +1,6 @@
using System.Windows.Controls;
-namespace Artemis.Views.Profiles.Properties
+namespace Artemis.Views.Profiles.Layers
{
///
/// Interaction logic for KeyboardPropertiesView.xaml
diff --git a/Artemis/Artemis/Views/Profiles/Layers/MousePropertiesView.xaml b/Artemis/Artemis/Views/Profiles/Layers/MousePropertiesView.xaml
new file mode 100644
index 000000000..af960162a
--- /dev/null
+++ b/Artemis/Artemis/Views/Profiles/Layers/MousePropertiesView.xaml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Views/Profiles/Properties/MousePropertiesView.xaml.cs b/Artemis/Artemis/Views/Profiles/Layers/MousePropertiesView.xaml.cs
similarity index 87%
rename from Artemis/Artemis/Views/Profiles/Properties/MousePropertiesView.xaml.cs
rename to Artemis/Artemis/Views/Profiles/Layers/MousePropertiesView.xaml.cs
index 33874f2db..34fdb7e4c 100644
--- a/Artemis/Artemis/Views/Profiles/Properties/MousePropertiesView.xaml.cs
+++ b/Artemis/Artemis/Views/Profiles/Layers/MousePropertiesView.xaml.cs
@@ -1,6 +1,6 @@
using System.Windows.Controls;
-namespace Artemis.Views.Profiles.Properties
+namespace Artemis.Views.Profiles.Layers
{
///
/// Interaction logic for MousePropertiesView.xaml
diff --git a/Artemis/Artemis/Views/Profiles/ProfileEditorView.xaml b/Artemis/Artemis/Views/Profiles/ProfileEditorView.xaml
index 4e444ecd5..8148a445a 100644
--- a/Artemis/Artemis/Views/Profiles/ProfileEditorView.xaml
+++ b/Artemis/Artemis/Views/Profiles/ProfileEditorView.xaml
@@ -8,10 +8,11 @@
xmlns:itemBehaviours="clr-namespace:Artemis.ItemBehaviours"
xmlns:utilities="clr-namespace:Artemis.Utilities"
xmlns:dragDrop="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop"
+ xmlns:converters="clr-namespace:Artemis.Utilities.Converters"
mc:Ignorable="d"
d:DesignHeight="510" Width="1055">
-
+
diff --git a/Artemis/Artemis/Views/Profiles/Properties/MousePropertiesView.xaml b/Artemis/Artemis/Views/Profiles/Properties/MousePropertiesView.xaml
deleted file mode 100644
index 43de0e580..000000000
--- a/Artemis/Artemis/Views/Profiles/Properties/MousePropertiesView.xaml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file