diff --git a/Artemis/Artemis/App.xaml b/Artemis/Artemis/App.xaml
index 1b093a2b3..15a67464a 100644
--- a/Artemis/Artemis/App.xaml
+++ b/Artemis/Artemis/App.xaml
@@ -17,8 +17,7 @@
-
+
diff --git a/Artemis/Artemis/App.xaml.cs b/Artemis/Artemis/App.xaml.cs
index 3d53eec5c..f7f13e188 100644
--- a/Artemis/Artemis/App.xaml.cs
+++ b/Artemis/Artemis/App.xaml.cs
@@ -1,6 +1,7 @@
using System;
using System.Windows;
using System.Windows.Threading;
+using Artemis.Utilities;
using NLog;
using WpfExceptionViewer;
@@ -26,6 +27,9 @@ namespace Artemis
private void Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
+ // Get rid of the keyboard hook in case of a crash, otherwise input freezes up system wide until Artemis is gone
+ InputHook.Stop();
+
if (DoHandle)
{
GetArtemisExceptionViewer(e.Exception).ShowDialog();
diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj
index e46fc944c..00dba2b00 100644
--- a/Artemis/Artemis/Artemis.csproj
+++ b/Artemis/Artemis/Artemis.csproj
@@ -131,6 +131,10 @@
LocalIntranet
+
+ False
+ lib\AssettoCorsaSharedMemory.dll
+
..\packages\Betwixt.1.4.1\lib\net35\Betwixt.dll
True
@@ -147,20 +151,20 @@
..\packages\Caliburn.Micro.3.0.3\lib\net45\Caliburn.Micro.Platform.Core.dll
True
-
- ..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll
+
+ ..\packages\Castle.Core.4.0.0\lib\net45\Castle.Core.dll
True
..\packages\Colore.5.1.0\lib\net35\Corale.Colore.dll
True
-
- ..\packages\CSCore.1.1.0\lib\net35-client\CSCore.dll
+
+ ..\packages\CSCore.1.2.0\lib\net35-client\CSCore.dll
True
-
- ..\packages\CUE.NET.1.1.2.1\lib\net45\CUE.NET.dll
+
+ ..\packages\CUE.NET.1.1.3.0\lib\net45\CUE.NET.dll
True
@@ -179,6 +183,10 @@
..\packages\DynamicExpresso.Core.1.3.3.5\lib\net40\DynamicExpresso.Core.dll
True
+
+ ..\packages\MouseKeyHook.5.4.0\lib\net40\Gma.System.MouseKeyHook.dll
+ True
+
..\packages\gong-wpf-dragdrop.0.1.4.3\lib\net40\GongSolutions.Wpf.DragDrop.dll
True
@@ -191,12 +199,12 @@
..\packages\squirrel.windows.1.4.4\lib\Net45\ICSharpCode.SharpZipLib.dll
True
-
- ..\packages\log4net.2.0.7\lib\net45-full\log4net.dll
+
+ ..\packages\log4net.2.0.8\lib\net45-full\log4net.dll
True
-
- ..\packages\MahApps.Metro.1.4.1\lib\net45\MahApps.Metro.dll
+
+ ..\packages\MahApps.Metro.1.4.3\lib\net45\MahApps.Metro.dll
True
@@ -240,17 +248,13 @@
True
- ..\packages\NLog.4.4.1\lib\net45\NLog.dll
+ ..\packages\NLog.4.4.4\lib\net45\NLog.dll
True
..\packages\squirrel.windows.1.4.4\lib\Net45\NuGet.Squirrel.dll
True
-
- ..\packages\Open.WinKeyboardHook.1.0.11\lib\net45\Open.WinKeyboardHook.dll
- True
-
..\packages\Process.NET.1.0.8\lib\Process.NET.dll
True
@@ -268,7 +272,7 @@
True
- ..\packages\SpotifyAPI-NET.2.12.0\lib\SpotifyAPI.dll
+ ..\packages\SpotifyAPI-NET.2.13.1\lib\SpotifyAPI.dll
True
@@ -286,7 +290,7 @@
- ..\packages\MahApps.Metro.1.4.1\lib\net45\System.Windows.Interactivity.dll
+ ..\packages\MahApps.Metro.1.4.3\lib\net45\System.Windows.Interactivity.dll
True
@@ -325,6 +329,8 @@
+
+
@@ -354,6 +360,7 @@
+
@@ -363,12 +370,20 @@
+
+
+
+
+
+ AssettoCorsaView.xaml
+
+
@@ -472,9 +487,13 @@
OverlayProfileView.xaml
+
+
+
+
@@ -486,7 +505,7 @@
-
+
@@ -546,6 +565,7 @@
+
@@ -608,7 +628,7 @@
-
+
@@ -639,14 +659,13 @@
-
-
+
@@ -669,6 +688,7 @@
+
@@ -719,6 +739,9 @@
KeyboardPropertiesView.xaml
+
+ LayerKeybindView.xaml
+
LayerConditionView.xaml
@@ -757,6 +780,7 @@
Designer
+
@@ -781,7 +805,7 @@
-
+
PreserveNewest
@@ -828,6 +852,10 @@
Designer
MSBuild:Compile
+
+ MSBuild:Compile
+ Designer
+
Designer
MSBuild:Compile
@@ -964,6 +992,10 @@
Designer
MSBuild:Compile
+
+ MSBuild:Compile
+ Designer
+
Designer
MSBuild:Compile
@@ -1035,12 +1067,12 @@
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
+
+
+
+
+
+ The Assetto Corsa module uses the Assetto Corsa Shared Memory Library project by mdjarv.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/AssettoCorsa/AssettoCorsaView.xaml.cs b/Artemis/Artemis/Modules/Games/AssettoCorsa/AssettoCorsaView.xaml.cs
new file mode 100644
index 000000000..37aec9ee8
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/AssettoCorsa/AssettoCorsaView.xaml.cs
@@ -0,0 +1,18 @@
+using System.Windows.Controls;
+using System.Windows.Navigation;
+
+namespace Artemis.Modules.Games.AssettoCorsa
+{
+ public partial class AssettoCorsaView : UserControl
+ {
+ public AssettoCorsaView()
+ {
+ InitializeComponent();
+ }
+
+ private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
+ {
+ System.Diagnostics.Process.Start(e.Uri.ToString());
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/AssettoCorsa/AssettoCorsaViewModel.cs b/Artemis/Artemis/Modules/Games/AssettoCorsa/AssettoCorsaViewModel.cs
new file mode 100644
index 000000000..3fd02a28c
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/AssettoCorsa/AssettoCorsaViewModel.cs
@@ -0,0 +1,17 @@
+using Artemis.Managers;
+using Artemis.Modules.Abstract;
+using Ninject;
+
+namespace Artemis.Modules.Games.AssettoCorsa
+{
+ public sealed class AssettoCorsaViewModel : ModuleViewModel
+ {
+ public AssettoCorsaViewModel(MainManager mainManager, [Named(nameof(AssettoCorsaModel))] ModuleModel moduleModel,
+ IKernel kernel) : base(mainManager, moduleModel, kernel)
+ {
+ DisplayName = "Assetto Corsa";
+ }
+
+ public override bool UsesProfileEditor => 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 dd80b03d7..08cc13339 100644
--- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs
+++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs
@@ -8,6 +8,7 @@ using Artemis.Services;
using Artemis.Utilities;
using Artemis.Utilities.GameState;
using Newtonsoft.Json;
+using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
namespace Artemis.Modules.Games.CounterStrike
{
@@ -56,7 +57,7 @@ namespace Artemis.Modules.Games.CounterStrike
return;
var dm = (CounterStrikeDataModel) DataModel;
- if (dm.player != null)
+ if (dm.player != null && dm.player.weapons != null)
{
// Detect active weapon
if (dm.player.weapons.weapon_0?.state == "active")
@@ -147,7 +148,7 @@ namespace Artemis.Modules.Games.CounterStrike
{
if (DataModel == null)
DataModel = new CounterStrikeDataModel();
- JsonConvert.PopulateObject(jsonString, DataModel);
+ JsonConvert.PopulateObject(jsonString, DataModel, new JsonSerializerSettings {Error = HandleGameDataError});
}
catch (Exception ex)
{
@@ -155,5 +156,11 @@ namespace Artemis.Modules.Games.CounterStrike
throw;
}
}
+
+ private void HandleGameDataError(object sender, ErrorEventArgs e)
+ {
+ // Ignore errors and leave them null
+ e.ErrorContext.Handled = true;
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml
index 1bdbd9807..358b995e0 100644
--- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml
+++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeView.xaml
@@ -1,68 +1,55 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="476.986" d:DesignWidth="538.772">
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
-
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs
index 7a8f08a83..b6b54b941 100644
--- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs
+++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs
@@ -1,4 +1,5 @@
-using Artemis.Managers;
+using System.Windows.Forms;
+using Artemis.Managers;
using Artemis.Modules.Abstract;
using Ninject;
@@ -6,8 +7,7 @@ namespace Artemis.Modules.Games.CounterStrike
{
public sealed class CounterStrikeViewModel : ModuleViewModel
{
- public CounterStrikeViewModel(MainManager mainManager,
- [Named(nameof(CounterStrikeModel))] ModuleModel moduleModel, IKernel kernel)
+ public CounterStrikeViewModel(MainManager mainManager, [Named(nameof(CounterStrikeModel))] ModuleModel moduleModel, IKernel kernel)
: base(mainManager, moduleModel, kernel)
{
DisplayName = "CS:GO";
@@ -15,10 +15,23 @@ namespace Artemis.Modules.Games.CounterStrike
public override bool UsesProfileEditor => true;
- public void BrowseDirectory()
+ public void PlaceConfigFile()
{
((CounterStrikeModel) ModuleModel).PlaceConfigFile();
NotifyOfPropertyChange(() => Settings);
}
+
+ public void BrowseDirectory()
+ {
+ var dialog = new FolderBrowserDialog { SelectedPath = ((CounterStrikeSettings)Settings).GameDirectory };
+ var result = dialog.ShowDialog();
+ if (result != DialogResult.OK)
+ return;
+
+ ((CounterStrikeSettings)Settings).GameDirectory = dialog.SelectedPath;
+ ((CounterStrikeModel)ModuleModel).PlaceConfigFile();
+ Settings.Save();
+ NotifyOfPropertyChange(() => Settings);
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Artemis/Artemis/Modules/Games/Dota2/Dota2View.xaml b/Artemis/Artemis/Modules/Games/Dota2/Dota2View.xaml
index f3834c409..469979334 100644
--- a/Artemis/Artemis/Modules/Games/Dota2/Dota2View.xaml
+++ b/Artemis/Artemis/Modules/Games/Dota2/Dota2View.xaml
@@ -1,67 +1,55 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="476.986" d:DesignWidth="538.772">
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Dota2/Dota2ViewModel.cs b/Artemis/Artemis/Modules/Games/Dota2/Dota2ViewModel.cs
index ba23d88eb..c9a9acc34 100644
--- a/Artemis/Artemis/Modules/Games/Dota2/Dota2ViewModel.cs
+++ b/Artemis/Artemis/Modules/Games/Dota2/Dota2ViewModel.cs
@@ -1,4 +1,5 @@
-using Artemis.Managers;
+using System.Windows.Forms;
+using Artemis.Managers;
using Artemis.Modules.Abstract;
using Ninject;
@@ -6,18 +7,31 @@ namespace Artemis.Modules.Games.Dota2
{
public sealed class Dota2ViewModel : ModuleViewModel
{
- public Dota2ViewModel(MainManager mainManager, [Named(nameof(Dota2Model))] ModuleModel moduleModel,
- IKernel kernel) : base(mainManager, moduleModel, kernel)
+ public Dota2ViewModel(MainManager mainManager, [Named(nameof(Dota2Model))] ModuleModel moduleModel, IKernel kernel)
+ : base(mainManager, moduleModel, kernel)
{
DisplayName = "Dota 2";
}
public override bool UsesProfileEditor => true;
- public void BrowseDirectory()
+ public void PlaceConfigFile()
{
((Dota2Model) ModuleModel).PlaceConfigFile();
NotifyOfPropertyChange(() => Settings);
}
+
+ public void BrowseDirectory()
+ {
+ var dialog = new FolderBrowserDialog { SelectedPath = ((Dota2Settings)Settings).GameDirectory };
+ var result = dialog.ShowDialog();
+ if (result != DialogResult.OK)
+ return;
+
+ ((Dota2Settings)Settings).GameDirectory = dialog.SelectedPath;
+ ((Dota2Model)ModuleModel).PlaceConfigFile();
+ Settings.Save();
+ NotifyOfPropertyChange(() => Settings);
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Artemis/Artemis/Modules/Games/EurotruckSimulator2/EurotruckSimulator2DataModel.cs b/Artemis/Artemis/Modules/Games/EurotruckSimulator2/EurotruckSimulator2DataModel.cs
index bb45aab72..b97d7df89 100644
--- a/Artemis/Artemis/Modules/Games/EurotruckSimulator2/EurotruckSimulator2DataModel.cs
+++ b/Artemis/Artemis/Modules/Games/EurotruckSimulator2/EurotruckSimulator2DataModel.cs
@@ -1,33 +1,33 @@
-using Artemis.Modules.Abstract;
-using Artemis.Modules.Games.EurotruckSimulator2.Data;
-using MoonSharp.Interpreter;
-
-namespace Artemis.Modules.Games.EurotruckSimulator2
-{
- [MoonSharpUserData]
- public class EurotruckSimulator2DataModel : ModuleDataModel
- {
- public EurotruckSimulator2DataModel()
- {
- // Register types for LUA
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- UserData.RegisterType();
- }
-
- public TruckSimulatorGameName GameName { get; set; }
- public IEts2Game Game { get; set; }
- public IEts2Job Job { get; set; }
- public IEts2Navigation Navigation { get; set; }
- public IEts2Trailer Trailer { get; set; }
+using Artemis.Modules.Abstract;
+using Artemis.Modules.Games.EurotruckSimulator2.Data;
+using MoonSharp.Interpreter;
+
+namespace Artemis.Modules.Games.EurotruckSimulator2
+{
+ [MoonSharpUserData]
+ public class EurotruckSimulator2DataModel : ModuleDataModel
+ {
+ public EurotruckSimulator2DataModel()
+ {
+ // Register types for LUA
+ UserData.RegisterType();
+ UserData.RegisterType();
+ UserData.RegisterType();
+ UserData.RegisterType();
+ UserData.RegisterType();
+ }
+
+ public TruckSimulatorGameName GameName { get; set; }
+ public IEts2Game Game { get; set; }
+ public IEts2Job Job { get; set; }
+ public IEts2Navigation Navigation { get; set; }
+ public IEts2Trailer Trailer { get; set; }
public IEts2Truck Truck { get; set; }
- public enum TruckSimulatorGameName
- {
- EuroTruckSimulator2,
- AmericanTruckSimulator
- }
- }
+ public enum TruckSimulatorGameName
+ {
+ EuroTruckSimulator2,
+ AmericanTruckSimulator
+ }
+ }
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/EurotruckSimulator2/EurotruckSimulator2View.xaml b/Artemis/Artemis/Modules/Games/EurotruckSimulator2/EurotruckSimulator2View.xaml
index 281aa5825..bdaa887ee 100644
--- a/Artemis/Artemis/Modules/Games/EurotruckSimulator2/EurotruckSimulator2View.xaml
+++ b/Artemis/Artemis/Modules/Games/EurotruckSimulator2/EurotruckSimulator2View.xaml
@@ -1,103 +1,75 @@
-
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="559.725" d:DesignWidth="882.696">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The Truck Simulator module uses code from the ETS2 Telemetry Web Server project by Funbit.
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The Truck Simulator module uses code from the
-
- ETS2 Telemetry Web Server
-
- project by Funbit
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/GtaV/GtaVModel.cs b/Artemis/Artemis/Modules/Games/GtaV/GtaVModel.cs
index c41f54b4f..38f854a65 100644
--- a/Artemis/Artemis/Modules/Games/GtaV/GtaVModel.cs
+++ b/Artemis/Artemis/Modules/Games/GtaV/GtaVModel.cs
@@ -1,4 +1,5 @@
-using System.Threading;
+using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media;
using Artemis.DAL;
@@ -13,8 +14,7 @@ namespace Artemis.Modules.Games.GtaV
{
private readonly PipeServer _pipeServer;
- public GtaVModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer)
- : base(deviceManager, luaManager)
+ public GtaVModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer) : base(deviceManager, luaManager)
{
_pipeServer = pipeServer;
@@ -29,6 +29,7 @@ namespace Artemis.Modules.Games.GtaV
public override void Enable()
{
+ var process = System.Diagnostics.Process.GetProcessesByName("GTA5").First();
DllManager.PlaceLogitechDll();
_pipeServer.PipeMessage += PipeServerOnPipeMessage;
base.Enable();
diff --git a/Artemis/Artemis/Modules/Games/GtaV/GtaVView.xaml b/Artemis/Artemis/Modules/Games/GtaV/GtaVView.xaml
index b5ca45e27..0441bb12e 100644
--- a/Artemis/Artemis/Modules/Games/GtaV/GtaVView.xaml
+++ b/Artemis/Artemis/Modules/Games/GtaV/GtaVView.xaml
@@ -1,55 +1,45 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="300" d:DesignWidth="300">
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs b/Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs
index 0ed11700f..db460523e 100644
--- a/Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs
+++ b/Artemis/Artemis/Modules/Games/LightFx/LightFxModel.cs
@@ -1,55 +1,55 @@
-using System;
-using System.IO;
-using Artemis.DAL;
-using Artemis.Managers;
-using Artemis.Modules.Abstract;
-using Artemis.Utilities.DataReaders;
-using Newtonsoft.Json;
-
-namespace Artemis.Modules.Games.LightFx
-{
- public class LightFxModel : ModuleModel
- {
- public LightFxModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer)
- : base(deviceManager, luaManager)
- {
- Settings = SettingsProvider.Load();
- DataModel = new LightFxDataModel();
- ProcessNames.Add("LoL");
-
- // This model can enable itself by changing its process name to the currently running Light FX game.
- pipeServer.PipeMessage += PipeServerOnPipeMessage;
- }
-
- public override string Name => "LightFX";
- public override bool IsOverlay => false;
- public override bool IsBoundToProcess => true;
-
- private void PipeServerOnPipeMessage(string msg)
- {
- // Ensure it's Light FX JSON
- if (!msg.Contains("lightFxState"))
- return;
-
- // Deserialize and data
- try
- {
- JsonConvert.PopulateObject(msg, DataModel);
- }
- catch (Exception ex)
- {
- Logger?.Error(ex, "Failed to deserialize LightFX JSON");
- throw;
- }
-
- // Setup process name
- var processName = Path.GetFileNameWithoutExtension(((LightFxDataModel) DataModel).LightFxState.game);
- if (!ProcessNames.Contains(processName))
- ProcessNames.Add(processName);
- }
-
- public override void Update()
- {
- }
- }
-}
\ No newline at end of file
+//using System;
+//using System.IO;
+//using Artemis.DAL;
+//using Artemis.Managers;
+//using Artemis.Modules.Abstract;
+//using Artemis.Utilities.DataReaders;
+//using Newtonsoft.Json;
+//
+//namespace Artemis.Modules.Games.LightFx
+//{
+// public class LightFxModel : ModuleModel
+// {
+// public LightFxModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer)
+// : base(deviceManager, luaManager)
+// {
+// Settings = SettingsProvider.Load();
+// DataModel = new LightFxDataModel();
+// ProcessNames.Add("LoL");
+//
+// // This model can enable itself by changing its process name to the currently running Light FX game.
+// pipeServer.PipeMessage += PipeServerOnPipeMessage;
+// }
+//
+// public override string Name => "LightFX";
+// public override bool IsOverlay => false;
+// public override bool IsBoundToProcess => true;
+//
+// private void PipeServerOnPipeMessage(string msg)
+// {
+// // Ensure it's Light FX JSON
+// if (!msg.Contains("lightFxState"))
+// return;
+//
+// // Deserialize and data
+// try
+// {
+// JsonConvert.PopulateObject(msg, DataModel);
+// }
+// catch (Exception ex)
+// {
+// Logger?.Error(ex, "Failed to deserialize LightFX JSON");
+// throw;
+// }
+//
+// // Setup process name
+// var processName = Path.GetFileNameWithoutExtension(((LightFxDataModel) DataModel).LightFxState.game);
+// if (!ProcessNames.Contains(processName))
+// ProcessNames.Add(processName);
+// }
+//
+// public override void Update()
+// {
+// }
+// }
+//}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/LightFx/LightFxView.xaml b/Artemis/Artemis/Modules/Games/LightFx/LightFxView.xaml
index 4a22f3531..f0ffbdb95 100644
--- a/Artemis/Artemis/Modules/Games/LightFx/LightFxView.xaml
+++ b/Artemis/Artemis/Modules/Games/LightFx/LightFxView.xaml
@@ -1,61 +1,45 @@
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="559.725" d:DesignWidth="882.696">
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/LightFx/LightFxViewModel.cs b/Artemis/Artemis/Modules/Games/LightFx/LightFxViewModel.cs
index 42cffd552..2583dc492 100644
--- a/Artemis/Artemis/Modules/Games/LightFx/LightFxViewModel.cs
+++ b/Artemis/Artemis/Modules/Games/LightFx/LightFxViewModel.cs
@@ -1,17 +1,17 @@
-using Artemis.Managers;
-using Artemis.Modules.Abstract;
-using Ninject;
-
-namespace Artemis.Modules.Games.LightFx
-{
- public sealed class LightFxViewModel : ModuleViewModel
- {
- public LightFxViewModel(MainManager mainManager, [Named(nameof(LightFxModel))] ModuleModel moduleModel,
- IKernel kernel) : base(mainManager, moduleModel, kernel)
- {
- DisplayName = "Light FX";
- }
-
- public override bool UsesProfileEditor => true;
- }
-}
\ No newline at end of file
+//using Artemis.Managers;
+//using Artemis.Modules.Abstract;
+//using Ninject;
+//
+//namespace Artemis.Modules.Games.LightFx
+//{
+// public sealed class LightFxViewModel : ModuleViewModel
+// {
+// public LightFxViewModel(MainManager mainManager, [Named(nameof(LightFxModel))] ModuleModel moduleModel,
+// IKernel kernel) : base(mainManager, moduleModel, kernel)
+// {
+// DisplayName = "Light FX";
+// }
+//
+// public override bool UsesProfileEditor => true;
+// }
+//}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchView.xaml b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchView.xaml
index 77a56a7df..7fa2840a1 100644
--- a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchView.xaml
+++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchView.xaml
@@ -1,88 +1,60 @@
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="410.933" d:DesignWidth="732.154">
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
-
- Note: If you're having trouble getting the profile to work, check out
-
- the wiki
-
-
-
-
-
-
+
+
+ Note: If you're having trouble getting the profile to work, check out the wiki.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchViewModel.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchViewModel.cs
index 53608861b..e5b6a7aee 100644
--- a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchViewModel.cs
+++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchViewModel.cs
@@ -15,6 +15,11 @@ namespace Artemis.Modules.Games.Overwatch
public override bool UsesProfileEditor => true;
+ public void PlaceDll()
+ {
+ ((OverwatchModel)ModuleModel).PlaceDll();
+ }
+
public void BrowseDirectory()
{
var dialog = new FolderBrowserDialog {SelectedPath = ((OverwatchSettings) Settings).GameDirectory};
diff --git a/Artemis/Artemis/Modules/Games/ProjectCars/Data/_pCarsAPIClass/Methods/pCarsAPI-MapStructToClass.cs b/Artemis/Artemis/Modules/Games/ProjectCars/Data/_pCarsAPIClass/Methods/pCarsAPI-MapStructToClass.cs
index f3b720188..aaf41e793 100644
--- a/Artemis/Artemis/Modules/Games/ProjectCars/Data/_pCarsAPIClass/Methods/pCarsAPI-MapStructToClass.cs
+++ b/Artemis/Artemis/Modules/Games/ProjectCars/Data/_pCarsAPIClass/Methods/pCarsAPI-MapStructToClass.cs
@@ -9,10 +9,13 @@ namespace Artemis.Modules.Games.ProjectCars.Data
{
public pCarsDataClass MapStructToClass(pCarsAPIStruct pcarsDataStruct, pCarsDataClass pCarsData)
{
- //pCarsDataClass pCarsData = new pCarsDataClass();
pCarsData.mVersion = pcarsDataStruct.mVersion;
pCarsData.mBuildVersion = pcarsDataStruct.mBuildVersion;
+ // The game isn't running if these are 0
+ if (pcarsDataStruct.mVersion == 0 && pcarsDataStruct.mBuildVersion == 0)
+ return pCarsData;
+
// Session type
pCarsData.mGameState = (eGameState) pcarsDataStruct.mGameState;
pCarsData.mSessionState = (eSessionState) pcarsDataStruct.mSessionState;
diff --git a/Artemis/Artemis/Modules/Games/ProjectCars/Data/_pCarsAPIStruct/pCarsAPI-ReadAPI.cs b/Artemis/Artemis/Modules/Games/ProjectCars/Data/_pCarsAPIStruct/pCarsAPI-ReadAPI.cs
index 8412d7363..e7d0a27c6 100644
--- a/Artemis/Artemis/Modules/Games/ProjectCars/Data/_pCarsAPIStruct/pCarsAPI-ReadAPI.cs
+++ b/Artemis/Artemis/Modules/Games/ProjectCars/Data/_pCarsAPIStruct/pCarsAPI-ReadAPI.cs
@@ -37,6 +37,10 @@ namespace Artemis.Modules.Games.ProjectCars.Data
if (memoryMappedFile == null)
InitialiseSharedMemory();
+ // If it's still null here the game isn't running
+ if (memoryMappedFile == null)
+ return new Tuple(true, _pcarsapistruct);
+
using (var sharedMemoryStreamView = memoryMappedFile.CreateViewStream())
{
var sharedMemoryStream = new BinaryReader(sharedMemoryStreamView);
diff --git a/Artemis/Artemis/Modules/Games/ProjectCars/ProjectCarsView.xaml b/Artemis/Artemis/Modules/Games/ProjectCars/ProjectCarsView.xaml
index 944b85242..9e1f9c44f 100644
--- a/Artemis/Artemis/Modules/Games/ProjectCars/ProjectCarsView.xaml
+++ b/Artemis/Artemis/Modules/Games/ProjectCars/ProjectCarsView.xaml
@@ -1,71 +1,50 @@
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="559.725" d:DesignWidth="882.696">
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
-
- The Project CARS module uses code from the
-
- pCars API Demo
-
- project by MikeyTT
-
-
-
-
-
-
+
+
+ The Project CARS module uses code from the pCars API Demo project by MikeyTT.
+
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
\ 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 34ae2f8b9..50d3dc7bc 100644
--- a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs
+++ b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs
@@ -1,10 +1,13 @@
-using System.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
using Artemis.DAL;
using Artemis.Managers;
using Artemis.Modules.Abstract;
using Artemis.Settings;
using Artemis.Utilities;
using Artemis.Utilities.Memory;
+using Newtonsoft.Json;
namespace Artemis.Modules.Games.RocketLeague
{
@@ -20,21 +23,21 @@ namespace Artemis.Modules.Games.RocketLeague
ProcessNames.Add("RocketLeague");
// Generate a new offset when the game is updated
- //var offset = new GamePointersCollection
- //{
- // Game = "RocketLeague",
- // GameVersion = "1.27",
- // GameAddresses = new List
- // {
- // new GamePointer
- // {
- // Description = "Boost",
- // BasePointer = new IntPtr(0x016D5084),
- // Offsets = new[] {0xC4, 0x214, 0x320, 0x73C, 0x224}
- // }
- // }
- //};
- //var res = JsonConvert.SerializeObject(offset, Formatting.Indented);
+ var offset = new GamePointersCollection
+ {
+ Game = "RocketLeague",
+ GameVersion = "1.30",
+ GameAddresses = new List
+ {
+ new GamePointer
+ {
+ Description = "Boost",
+ BasePointer = new IntPtr(0x016E00B4),
+ Offsets = new[] {0xC4, 0x18, 0x388, 0x73C, 0x224}
+ }
+ }
+ };
+ var res = JsonConvert.SerializeObject(offset, Formatting.Indented);
}
public override string Name => "RocketLeague";
diff --git a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueView.xaml b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueView.xaml
index c11bc6464..48f923d27 100644
--- a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueView.xaml
+++ b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueView.xaml
@@ -1,57 +1,48 @@
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="476.986" d:DesignWidth="538.772">
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
-
-
+
+
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueViewModel.cs b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueViewModel.cs
index 1f4370272..e46759d75 100644
--- a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueViewModel.cs
+++ b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueViewModel.cs
@@ -36,15 +36,13 @@ namespace Artemis.Modules.Games.RocketLeague
{
if (!SettingsProvider.Load().EnablePointersUpdate)
{
- VersionText = "Note: You disabled pointer updates, this could result in the " +
- "Rocket League effect not working after a game update.";
+ VersionText = "You disabled pointer updates, this could result in the Rocket League effect not working after a game update.";
return;
}
Updater.GetPointers();
var version = SettingsProvider.Load().RocketLeague.GameVersion;
- VersionText = $"Note: Requires patch {version}. When a new patch is released Artemis downloads " +
- "new pointers for the latest version (unless disabled in settings).";
+ VersionText = $"Requires patch {version}. When a new patch is released Artemis downloads new pointers for the latest version (unless disabled in settings).";
}
}
}
\ 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 d2a80a83d..d88d29715 100644
--- a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs
+++ b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs
@@ -1,138 +1,143 @@
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-using Artemis.DAL;
-using Artemis.Managers;
-using Artemis.Modules.Abstract;
-using Artemis.Utilities;
-using Artemis.Utilities.DataReaders;
-
-namespace Artemis.Modules.Games.TheDivision
-{
- public class TheDivisionModel : ModuleModel
- {
- private readonly PipeServer _pipeServer;
- private StickyValue _stickyAmmo;
- private StickyValue _stickyHp;
-
- public TheDivisionModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer)
- : base(deviceManager, luaManager)
- {
- _pipeServer = pipeServer;
-
- Settings = SettingsProvider.Load();
- DataModel = new TheDivisionDataModel();
- ProcessNames.Add("TheDivision");
- }
-
- public override string Name => "TheDivision";
- public override bool IsOverlay => false;
- public override bool IsBoundToProcess => true;
-
- public override void Dispose()
- {
- base.Dispose();
-
- // Delay restoring the DLL to allow The Division to release it
- Task.Factory.StartNew(() =>
- {
- Thread.Sleep(2000);
- DllManager.RestoreLogitechDll();
- });
-
- _stickyAmmo?.Dispose();
- _stickyHp?.Dispose();
- _pipeServer.PipeMessage -= PipeServerOnPipeMessage;
- }
-
- public override void Enable()
- {
- _stickyAmmo = new StickyValue(200);
- _stickyHp = new StickyValue(200);
-
- DllManager.PlaceLogitechDll();
-
- _pipeServer.PipeMessage += PipeServerOnPipeMessage;
-
- base.Enable();
- }
-
- private void PipeServerOnPipeMessage(string reply)
- {
- if (!IsInitialized)
- return;
-
- // Convert the given string to a list of ints
- var stringParts = reply.Split(' ');
- if (stringParts[0] != "1")
- return;
-
- // Parse into a list of ints and interpertrate
- var parts = new int[stringParts.Length];
- for (var i = 0; i < stringParts.Length; i++)
- parts[i] = int.Parse(stringParts[i]);
-
- InterpertrateDivisionKey(parts);
- }
-
- // Parses Division key data to game data
- private void InterpertrateDivisionKey(IReadOnlyList parts)
- {
- var gameDataModel = (TheDivisionDataModel) DataModel;
- var keyCode = parts[1];
- var rPer = parts[2];
- var gPer = parts[3];
- var bPer = parts[4];
-
- // F1 to F4 indicate the player and his party. Blinks red on damage taken
- if (keyCode >= 59 && keyCode <= 62)
- {
- var playerId = keyCode - 58;
-
- PlayerState newState;
- if (gPer > 10)
- newState = PlayerState.Online;
- else if (rPer > 10)
- newState = PlayerState.Hit;
- else
- newState = PlayerState.Offline;
-
- if (playerId == 1)
- gameDataModel.LowHp = newState == PlayerState.Hit;
- else if (playerId == 2)
- gameDataModel.PartyMember1 = newState;
- else if (playerId == 3)
- gameDataModel.PartyMember2 = newState;
- else if (playerId == 4)
- gameDataModel.PartyMember3 = newState;
- }
- // R blinks white when low on ammo
- else if (keyCode == 19)
- {
- _stickyAmmo.Value = rPer == 100 && gPer > 1 && bPer > 1;
- gameDataModel.LowAmmo = _stickyAmmo.Value;
- }
- // G turns white when holding a grenade, turns off when out of grenades
- else if (keyCode == 34)
- {
- if (rPer == 100 && gPer < 10 && bPer < 10)
- gameDataModel.GrenadeState = GrenadeState.HasGrenade;
- else if (rPer == 100 && gPer > 10 && bPer > 10)
- gameDataModel.GrenadeState = GrenadeState.GrenadeEquipped;
- else
- gameDataModel.GrenadeState = GrenadeState.HasNoGrenade;
- }
- // V blinks on low HP
- else if (keyCode == 47)
- {
- _stickyHp.Value = rPer == 100 && gPer > 1 && bPer > 1;
- gameDataModel.LowHp = _stickyHp.Value;
- }
- }
-
- public override void Update()
- {
- // DataModel updating is done whenever a pipe message is received
- }
- }
-}
\ No newline at end of file
+//using System.Collections.Generic;
+//using System.Linq;
+//using System.Threading;
+//using System.Threading.Tasks;
+//using Artemis.DAL;
+//using Artemis.DeviceProviders.Logitech.Utilities;
+//using Artemis.Managers;
+//using Artemis.Modules.Abstract;
+//using Artemis.Utilities;
+//using Artemis.Utilities.DataReaders;
+//
+//namespace Artemis.Modules.Games.TheDivision
+//{
+// public class TheDivisionModel : ModuleModel
+// {
+// private readonly PipeServer _pipeServer;
+// private StickyValue _stickyAmmo;
+// private StickyValue _stickyHp;
+//
+// public TheDivisionModel(DeviceManager deviceManager, LuaManager luaManager, PipeServer pipeServer)
+// : base(deviceManager, luaManager)
+// {
+// _pipeServer = pipeServer;
+//
+// Settings = SettingsProvider.Load();
+// DataModel = new TheDivisionDataModel();
+// ProcessNames.Add("TheDivision");
+// }
+//
+// public override string Name => "TheDivision";
+// public override bool IsOverlay => false;
+// public override bool IsBoundToProcess => true;
+//
+// public override void Dispose()
+// {
+// base.Dispose();
+//
+// // Delay restoring the DLL to allow The Division to release it
+// Task.Factory.StartNew(() =>
+// {
+// Thread.Sleep(2000);
+// DllManager.RestoreLogitechDll();
+// });
+//
+// _stickyAmmo?.Dispose();
+// _stickyHp?.Dispose();
+// _pipeServer.PipeMessage -= PipeServerOnPipeMessage;
+// }
+//
+// public override void Enable()
+// {
+// _stickyAmmo = new StickyValue(200);
+// _stickyHp = new StickyValue(200);
+//
+// var process = System.Diagnostics.Process.GetProcessesByName("TheDivision").First();
+// DllManager.PlaceLogitechDll();
+//
+// _pipeServer.PipeMessage += PipeServerOnPipeMessage;
+//
+// base.Enable();
+// }
+//
+// private void PipeServerOnPipeMessage(string reply)
+// {
+// if (!IsInitialized)
+// return;
+//
+// // Convert the given string to a list of ints
+// var stringParts = reply.Split(' ');
+// if (stringParts[0] != "1")
+// return;
+//
+// // Parse into a list of ints and interpertrate
+// var parts = new int[stringParts.Length];
+// for (var i = 0; i < stringParts.Length; i++)
+// parts[i] = int.Parse(stringParts[i]);
+//
+// InterpertrateDivisionKey(parts);
+// }
+//
+// // Parses Division key data to game data
+// private void InterpertrateDivisionKey(IReadOnlyList parts)
+// {
+// var gameDataModel = (TheDivisionDataModel) DataModel;
+// var keyCode = parts[1];
+// var rPer = parts[2];
+// var gPer = parts[3];
+// var bPer = parts[4];
+//
+// var keyEnum = (KeyboardNames) keyCode;
+//
+// // F1 to F4 indicate the player and his party. Blinks red on damage taken
+// if (keyCode >= 59 && keyCode <= 62)
+// {
+// var playerId = keyCode - 58;
+//
+// PlayerState newState;
+// if (gPer > 10)
+// newState = PlayerState.Online;
+// else if (rPer > 10)
+// newState = PlayerState.Hit;
+// else
+// newState = PlayerState.Offline;
+//
+// if (playerId == 1)
+// gameDataModel.LowHp = newState == PlayerState.Hit;
+// else if (playerId == 2)
+// gameDataModel.PartyMember1 = newState;
+// else if (playerId == 3)
+// gameDataModel.PartyMember2 = newState;
+// else if (playerId == 4)
+// gameDataModel.PartyMember3 = newState;
+// }
+// // R blinks white when low on ammo
+// else if (keyCode == 19)
+// {
+// _stickyAmmo.Value = rPer == 100 && gPer > 1 && bPer > 1;
+// gameDataModel.LowAmmo = _stickyAmmo.Value;
+// }
+// // G turns white when holding a grenade, turns off when out of grenades
+// else if (keyCode == 34)
+// {
+// if (rPer == 100 && gPer < 10 && bPer < 10)
+// gameDataModel.GrenadeState = GrenadeState.HasGrenade;
+// else if (rPer == 100 && gPer > 10 && bPer > 10)
+// gameDataModel.GrenadeState = GrenadeState.GrenadeEquipped;
+// else
+// gameDataModel.GrenadeState = GrenadeState.HasNoGrenade;
+// }
+// // V blinks on low HP
+// else if (keyCode == 47)
+// {
+// _stickyHp.Value = rPer == 100 && gPer > 1 && bPer > 1;
+// gameDataModel.LowHp = _stickyHp.Value;
+// }
+// }
+//
+// public override void Update()
+// {
+// // DataModel updating is done whenever a pipe message is received
+// }
+// }
+//}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionView.xaml b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionView.xaml
index 92e3ac7e8..cce9cf955 100644
--- a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionView.xaml
+++ b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionView.xaml
@@ -1,61 +1,51 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Artemis.Modules.Games.TheDivision"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="416.495" d:DesignWidth="553.608">
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
-
- For this game to work with Artemis, please open up your Division settings, navigate to 3rd Party
- and set LED keyboard support to Yes. (This only works if you have Artemis running before starting the game)
-
+
+
+ For this game to work with Artemis, please open up your Division settings, navigate to 3rd Party and set LED keyboard support to Yes. (This only works if you have Artemis running before starting the game)
+
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionViewModel.cs b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionViewModel.cs
index 1239cf98b..fa667a647 100644
--- a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionViewModel.cs
+++ b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionViewModel.cs
@@ -1,17 +1,17 @@
-using Artemis.Managers;
-using Artemis.Modules.Abstract;
-using Ninject;
-
-namespace Artemis.Modules.Games.TheDivision
-{
- public sealed class TheDivisionViewModel : ModuleViewModel
- {
- public TheDivisionViewModel(MainManager mainManager, [Named(nameof(TheDivisionModel))] ModuleModel moduleModel,
- IKernel kernel) : base(mainManager, moduleModel, kernel)
- {
- DisplayName = "The Division";
- }
-
- public override bool UsesProfileEditor => true;
- }
-}
\ No newline at end of file
+//using Artemis.Managers;
+//using Artemis.Modules.Abstract;
+//using Ninject;
+//
+//namespace Artemis.Modules.Games.TheDivision
+//{
+// public sealed class TheDivisionViewModel : ModuleViewModel
+// {
+// public TheDivisionViewModel(MainManager mainManager, [Named(nameof(TheDivisionModel))] ModuleModel moduleModel,
+// IKernel kernel) : base(mainManager, moduleModel, kernel)
+// {
+// DisplayName = "The Division";
+// }
+//
+// public override bool UsesProfileEditor => true;
+// }
+//}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/UnrealTournament/UnrealTournamentView.xaml b/Artemis/Artemis/Modules/Games/UnrealTournament/UnrealTournamentView.xaml
index d24410ab0..b796f07a8 100644
--- a/Artemis/Artemis/Modules/Games/UnrealTournament/UnrealTournamentView.xaml
+++ b/Artemis/Artemis/Modules/Games/UnrealTournament/UnrealTournamentView.xaml
@@ -1,70 +1,56 @@
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="476.986" d:DesignWidth="538.772">
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
-
-
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/UnrealTournament/UnrealTournamentViewModel.cs b/Artemis/Artemis/Modules/Games/UnrealTournament/UnrealTournamentViewModel.cs
index f10b4790b..3ed9edeee 100644
--- a/Artemis/Artemis/Modules/Games/UnrealTournament/UnrealTournamentViewModel.cs
+++ b/Artemis/Artemis/Modules/Games/UnrealTournament/UnrealTournamentViewModel.cs
@@ -32,6 +32,13 @@ namespace Artemis.Modules.Games.UnrealTournament
NotifyOfPropertyChange(() => Settings);
}
+ public void PlaceFiles()
+ {
+ ((UnrealTournamentModel)ModuleModel).PlaceFiles();
+ Settings.Save();
+ NotifyOfPropertyChange(() => Settings);
+ }
+
// Installing GIF on editor open to make sure the proper profiles are loaded
private void InstallGif()
{
diff --git a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3View.xaml b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3View.xaml
index 7243a8e37..a66e53f99 100644
--- a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3View.xaml
+++ b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3View.xaml
@@ -1,60 +1,55 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Artemis requires the latest Witcher 3 version and mod to be installed in order to work. If you don't use any (conflicting) Witcher 3 mods, the mod can automatically be installed.
-
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="386.842" d:DesignWidth="554.887">
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
+
+
+ Artemis requires the latest Witcher 3 version and mod to be installed in order to work. If you don't use any (conflicting) Witcher 3 mods, the mod can automatically be installed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/WoW/WoWView.xaml b/Artemis/Artemis/Modules/Games/WoW/WoWView.xaml
index b6e24f40a..9537d78fd 100644
--- a/Artemis/Artemis/Modules/Games/WoW/WoWView.xaml
+++ b/Artemis/Artemis/Modules/Games/WoW/WoWView.xaml
@@ -1,57 +1,51 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="476.986" d:DesignWidth="538.772">
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
-
-
+
+
+ This module hasn't been approved by Blizzard and could lead to an account ban. Even though the risk is minimal, it's still your own risk.
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/General/Bubbles/Bubble.cs b/Artemis/Artemis/Modules/General/Bubbles/Bubble.cs
index 8f4976c92..90fb662b6 100644
--- a/Artemis/Artemis/Modules/General/Bubbles/Bubble.cs
+++ b/Artemis/Artemis/Modules/General/Bubbles/Bubble.cs
@@ -1,5 +1,7 @@
-using System.Drawing;
-using System.Windows;
+using System.Windows;
+using System.Windows.Media;
+using Artemis.Utilities;
+using Color = System.Drawing.Color;
using Point = System.Windows.Point;
namespace Artemis.Modules.General.Bubbles
@@ -20,7 +22,7 @@ namespace Artemis.Modules.General.Bubbles
#region Properties & Fields
- private Brush _brush;
+ private SolidColorBrush _brush;
private Color _color;
@@ -30,7 +32,7 @@ namespace Artemis.Modules.General.Bubbles
set
{
_color = value;
- _brush = new SolidBrush(_color);
+ _brush = new SolidColorBrush(ColorHelpers.ToMediaColor(_color));
}
}
@@ -45,10 +47,10 @@ namespace Artemis.Modules.General.Bubbles
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()
@@ -56,11 +58,11 @@ namespace Artemis.Modules.General.Bubbles
Position += Direction;
}
- public void Draw(Graphics g)
+ public void Draw(DrawingContext drawingContext)
{
- g.FillEllipse(_brush, (float) Position.X - Radius, (float) Position.Y - Radius, Radius*2, Radius*2);
+ drawingContext.DrawEllipse(_brush, new Pen(_brush, 1), new Point((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/General/Bubbles/BubblesModel.cs b/Artemis/Artemis/Modules/General/Bubbles/BubblesModel.cs
index 06c45100d..d3f95b795 100644
--- a/Artemis/Artemis/Modules/General/Bubbles/BubblesModel.cs
+++ b/Artemis/Artemis/Modules/General/Bubbles/BubblesModel.cs
@@ -93,11 +93,9 @@ namespace Artemis.Modules.General.Bubbles
public override void Render(FrameModel frameModel, bool keyboardOnly)
{
- using (var g = Graphics.FromImage(frameModel.KeyboardBitmap))
- {
- foreach (var bubble in _bubbles)
- bubble.Draw(g);
- }
+ var c = frameModel.KeyboardModel.GetDrawingContext();
+ foreach (var bubble in _bubbles)
+ bubble.Draw(c);
}
#endregion
diff --git a/Artemis/Artemis/Modules/General/GeneralProfile/GeneralProfileView.xaml b/Artemis/Artemis/Modules/General/GeneralProfile/GeneralProfileView.xaml
index f6719e810..ba95e4a36 100644
--- a/Artemis/Artemis/Modules/General/GeneralProfile/GeneralProfileView.xaml
+++ b/Artemis/Artemis/Modules/General/GeneralProfile/GeneralProfileView.xaml
@@ -1,54 +1,45 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="476.986" d:DesignWidth="538.772">
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileView.xaml b/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileView.xaml
index 3ee631a95..99e9fd1e6 100644
--- a/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileView.xaml
+++ b/Artemis/Artemis/Modules/Overlays/OverlayProfile/OverlayProfileView.xaml
@@ -1,54 +1,45 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="476.986" d:DesignWidth="538.772">
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/NLog.xsd b/Artemis/Artemis/NLog.xsd
index 2c7d1ff23..78043e413 100644
--- a/Artemis/Artemis/NLog.xsd
+++ b/Artemis/Artemis/NLog.xsd
@@ -42,12 +42,32 @@
- Pass NLog internal exceptions to the application. Default value is: false.
+ Throw an exception when there is an internal error. Default value is: false.
+
+
+
+
+ Throw an exception when there is a configuration error. If not set, determined by throwExceptions.
+
+
+
+
+ Gets or sets a value indicating whether Variables should be kept on configuration reload. Default value is: false.
- Write internal NLog messages to the the System.Diagnostics.Trace. Default value is: false
+ Write internal NLog messages to the System.Diagnostics.Trace. Default value is: false.
+
+
+
+
+ Write timestamps for internal NLog messages. Default value is: true.
+
+
+
+
+ Use InvariantCulture as default culture instead of CurrentCulture. Default value is: false.
@@ -174,7 +194,7 @@
- Name of the file to be included. The name is relative to the name of the current config file.
+ Name of the file to be included. You could use * wildcard. The name is relative to the name of the current config file.
@@ -250,9 +270,11 @@
+
+
@@ -264,6 +286,11 @@
Number of log events that should be processed in a batch by the lazy writer thread.
+
+
+ Limit of full s to write before yielding into Performance is better when writing many small batches, than writing a single large batch
+
+
Action to be taken when the lazy writer thread request queue count exceeds the set limit.
@@ -279,6 +306,11 @@
Time in milliseconds to sleep between batches.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -295,6 +327,7 @@
+
@@ -306,6 +339,11 @@
Condition expression. Log events who meet this condition will cause a flush on the wrapped target.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -317,6 +355,7 @@
+
@@ -338,6 +377,11 @@
Indicates whether to use sliding timeout.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -353,19 +397,20 @@
+
-
-
-
+
+
+
-
-
+
+
@@ -407,6 +452,11 @@
Action that should be taken if the message is larger than maxMessageSize.
+
+
+ Maximum current connections. 0 = no maximum.
+
+
Indicates whether to keep connection open whenever possible.
@@ -417,11 +467,6 @@
Size of the connection cache (number of connections which are kept alive).
-
-
- Maximum current connections. 0 = no maximum.
-
-
Network address.
@@ -432,14 +477,19 @@
Maximum queue size.
+
+
+ Indicates whether to include dictionary contents.
+
+
Indicates whether to include source info (file name and line number) in the information sent over the network.
-
+
- NDC item separator.
+ Indicates whether to include NLog-specific extensions to log4j schema.
@@ -457,14 +507,14 @@
AppInfo field. By default it's the friendly name of the current AppDomain.
-
+
- Indicates whether to include NLog-specific extensions to log4j schema.
+ NDC item separator.
-
+
- Indicates whether to include dictionary contents.
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
@@ -514,6 +564,7 @@
+
@@ -555,6 +606,11 @@
Indicates whether the error stream (stderr) should be used instead of the output stream (stdout).
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -658,6 +714,7 @@
+
@@ -694,6 +751,11 @@
The encoding for writing messages to the .
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -702,77 +764,83 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
Name of the target.
-
-
- Connection string. When provided, it overrides the values specified in DBHost, DBUserName, DBPassword, DBDatabase.
-
-
-
-
- Name of the connection string (as specified in <connectionStrings> configuration section.
-
-
-
-
- Database name. If the ConnectionString is not provided this value will be used to construct the "Database=" part of the connection string.
-
-
-
-
- Database host name. If the ConnectionString is not provided this value will be used to construct the "Server=" part of the connection string.
-
-
-
-
- Database password. If the ConnectionString is not provided this value will be used to construct the "Password=" part of the connection string.
-
-
-
-
- Name of the database provider.
-
-
-
-
- Database user name. If the ConnectionString is not provided this value will be used to construct the "User ID=" part of the connection string.
-
-
-
-
- Indicates whether to keep the database connection open between the log events.
-
-
Obsolete - value will be ignored! The logging code always runs outside of transaction. Gets or sets a value indicating whether to use database transactions. Some data providers require this.
+
+
+ Database user name. If the ConnectionString is not provided this value will be used to construct the "User ID=" part of the connection string.
+
+
+
+
+ Name of the database provider.
+
+
+
+
+ Database password. If the ConnectionString is not provided this value will be used to construct the "Password=" part of the connection string.
+
+
+
+
+ Indicates whether to keep the database connection open between the log events.
+
+
+
+
+ Database name. If the ConnectionString is not provided this value will be used to construct the "Database=" part of the connection string.
+
+
+
+
+ Name of the connection string (as specified in <connectionStrings> configuration section.
+
+
+
+
+ Connection string. When provided, it overrides the values specified in DBHost, DBUserName, DBPassword, DBDatabase.
+
+
+
+
+ Database host name. If the ConnectionString is not provided this value will be used to construct the "Server=" part of the connection string.
+
+
Connection string using for installation and uninstallation. If not provided, regular ConnectionString is being used.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
Text of the SQL command to be run on each log level.
@@ -864,6 +932,7 @@
+
@@ -885,6 +954,11 @@
Footer.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -894,6 +968,7 @@
+
@@ -905,6 +980,11 @@
Layout used to format log messages.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -922,6 +1002,7 @@
+
@@ -973,6 +1054,11 @@
Message length limit to write to the Event Log.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -989,6 +1075,7 @@
+
@@ -1000,6 +1087,11 @@
Indicates whether to return to the first target after any successful write.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -1022,6 +1114,7 @@
+
@@ -1039,6 +1132,7 @@
+
@@ -1119,6 +1213,11 @@
Cleanup invalid values in a filename, e.g. slashes in a filename. If set to true, this can impact the performance of massive writes. If set to false, nothing gets written when the filename is wrong.
+
+
+ Whether or not this target should just discard all data that its asked to write. Mostly used for when testing NLog Stack except final write
+
+
Is the an absolute or relative path?
@@ -1204,6 +1303,11 @@
Maximum number of seconds that files are kept open. If this number is negative the files are not automatically closed after a period of inactivity.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
Log file buffer size in bytes.
@@ -1243,6 +1347,13 @@
+
+
+
+
+
+
+
@@ -1278,6 +1389,7 @@
+
@@ -1289,6 +1401,11 @@
Condition expression. Log events who meet this condition will be forwarded to the wrapped target.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -1304,6 +1421,7 @@
+
@@ -1345,6 +1463,11 @@
Username to change context to.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -1378,6 +1501,7 @@
+
@@ -1394,6 +1518,11 @@
Maximum allowed number of messages written per .
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -1409,6 +1538,7 @@
+
@@ -1445,6 +1575,11 @@
Indicates whether to use binary message encoding.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -1487,9 +1622,10 @@
-
-
+
+
+
@@ -1565,9 +1701,9 @@
Sender's email address (e.g. joe@domain.com).
-
+
- Indicates whether NewLine characters in the body should be replaced with tags.
+ Indicates the SMTP client timeout.
@@ -1575,9 +1711,14 @@
Priority used for sending mails.
-
+
- Indicates the SMTP client timeout.
+ Indicates whether NewLine characters in the body should be replaced with tags.
+
+
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
@@ -1648,6 +1789,7 @@
+
@@ -1659,6 +1801,11 @@
Layout used to format log messages.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -1671,6 +1818,7 @@
+
@@ -1701,6 +1849,11 @@
Indicates whether to check if a queue exists before writing to it.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
Indicates whether to create the queue if it doesn't exists.
@@ -1732,6 +1885,7 @@
+
@@ -1748,6 +1902,11 @@
Method name. The method must be public and static. Use the AssemblyQualifiedName , https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx e.g.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -1768,6 +1927,7 @@
+
@@ -1834,6 +1994,11 @@
Maximum queue size.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -1849,19 +2014,20 @@
+
-
-
-
+
+
+
-
-
+
+
@@ -1903,6 +2069,11 @@
Action that should be taken if the message is larger than maxMessageSize.
+
+
+ Maximum current connections. 0 = no maximum.
+
+
Indicates whether to keep connection open whenever possible.
@@ -1913,11 +2084,6 @@
Size of the connection cache (number of connections which are kept alive).
-
-
- Maximum current connections. 0 = no maximum.
-
-
Network address.
@@ -1928,14 +2094,19 @@
Maximum queue size.
+
+
+ Indicates whether to include dictionary contents.
+
+
Indicates whether to include source info (file name and line number) in the information sent over the network.
-
+
- NDC item separator.
+ Indicates whether to include NLog-specific extensions to log4j schema.
@@ -1953,14 +2124,14 @@
AppInfo field. By default it's the friendly name of the current AppDomain.
-
+
- Indicates whether to include NLog-specific extensions to log4j schema.
+ NDC item separator.
-
+
- Indicates whether to include dictionary contents.
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
@@ -1973,6 +2144,7 @@
+
@@ -1989,6 +2161,11 @@
Indicates whether to perform layout calculation.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -1998,6 +2175,7 @@
+
@@ -2009,6 +2187,11 @@
Layout used to format log messages.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -2024,6 +2207,7 @@
+
@@ -2065,6 +2249,11 @@
Performance counter instance name.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -2107,6 +2296,7 @@
+
@@ -2118,6 +2308,11 @@
Default filter to be applied when no specific rule matches.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -2142,12 +2337,18 @@
+
Name of the target.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -2156,6 +2357,7 @@
+
@@ -2163,6 +2365,11 @@
Name of the target.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
Number of times to repeat each log message.
@@ -2176,6 +2383,7 @@
+
@@ -2184,6 +2392,11 @@
Name of the target.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
Number of retries that should be attempted on the wrapped target in case of a failure.
@@ -2202,12 +2415,18 @@
+
Name of the target.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -2216,12 +2435,18 @@
+
Name of the target.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -2231,6 +2456,7 @@
+
@@ -2242,6 +2468,11 @@
Layout used to format log messages.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
@@ -2252,6 +2483,7 @@
+
@@ -2272,6 +2504,11 @@
Should we include the BOM (Byte-order-mark) for UTF? Influences the property. This will only work for UTF-8.
+
+
+ Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit
+
+
Encoding.
diff --git a/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerCondition.cs b/Artemis/Artemis/Profiles/Layers/Abstract/LayerCondition.cs
similarity index 81%
rename from Artemis/Artemis/Profiles/Layers/Interfaces/ILayerCondition.cs
rename to Artemis/Artemis/Profiles/Layers/Abstract/LayerCondition.cs
index ee2ff364b..1bc4a538a 100644
--- a/Artemis/Artemis/Profiles/Layers/Interfaces/ILayerCondition.cs
+++ b/Artemis/Artemis/Profiles/Layers/Abstract/LayerCondition.cs
@@ -1,10 +1,10 @@
using Artemis.Modules.Abstract;
using Artemis.Profiles.Layers.Models;
-namespace Artemis.Profiles.Layers.Interfaces
+namespace Artemis.Profiles.Layers.Abstract
{
public interface ILayerCondition
{
bool ConditionsMet(LayerModel layerModel, ModuleDataModel dataModel);
}
-}
\ No newline at end of file
+}
diff --git a/Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs b/Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs
index 52fbf1d88..e660e607b 100644
--- a/Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs
+++ b/Artemis/Artemis/Profiles/Layers/Animations/PulseAnimation.cs
@@ -2,34 +2,49 @@
using System.Windows.Media;
using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models;
+using Betwixt;
namespace Artemis.Profiles.Layers.Animations
{
public class PulseAnimation : ILayerAnimation
{
+ private bool _increase = true;
+
+ private Tweener _opacityTweener = new Tweener(0, 1000, 1000, Ease.Quad.InOut, LerpFuncFloat);
public string Name => "Pulse";
public void Update(LayerModel layerModel, bool updateAnimations)
{
+ var animationSpeed = 3.1 - layerModel.Properties.AnimationSpeed;
// TODO: Generic implementation
// Reset animation progress if layer wasn't drawn for 100ms
- if ((new TimeSpan(0, 0, 0, 0, 100) < DateTime.Now - layerModel.LastRender) && updateAnimations)
- layerModel.AnimationProgress = 0;
+ if (new TimeSpan(0, 0, 0, 0, 100) < DateTime.Now - layerModel.LastRender && updateAnimations || MustExpire(layerModel))
+ {
+ _opacityTweener = new Tweener(0, 1000, animationSpeed * 1000, Ease.Quad.InOut, LerpFuncFloat);
+ _increase = true;
+ }
- var progress = layerModel.AnimationProgress;
+ // Update animation progress
+ if (!updateAnimations)
+ return;
- if (MustExpire(layerModel))
- progress = 0;
- progress = progress + layerModel.Properties.AnimationSpeed/2;
+ if (!_opacityTweener.Running && _increase)
+ {
+ _opacityTweener = new Tweener(1000, 0, animationSpeed * 1000, Ease.Quad.InOut, LerpFuncFloat);
+ _increase = false;
+ }
- // If not previewing, store the animation progress in the actual model for the next frame
- if (updateAnimations)
- layerModel.AnimationProgress = progress;
+ _opacityTweener.Update(40);
+
+ if (_increase)
+ layerModel.AnimationProgress = _opacityTweener.Value / 1000;
+ else
+ layerModel.AnimationProgress = 1 + (1 - _opacityTweener.Value / 1000);
}
public void Draw(LayerModel layerModel, DrawingContext c, int drawScale)
{
- if (layerModel.Brush == null)
+ if (layerModel.Brush == null || _opacityTweener == null)
return;
// Set up variables for this frame
@@ -41,7 +56,7 @@ namespace Artemis.Profiles.Layers.Animations
// Can't meddle with the original brush because it's frozen.
var brush = layerModel.Brush.Clone();
- brush.Opacity = (Math.Sin(layerModel.AnimationProgress*Math.PI) + 1)*(layerModel.Opacity/2);
+ brush.Opacity = _opacityTweener.Value / 1000;
layerModel.Brush = brush;
c.PushClip(new RectangleGeometry(clip));
@@ -49,6 +64,11 @@ namespace Artemis.Profiles.Layers.Animations
c.Pop();
}
- public bool MustExpire(LayerModel layer) => layer.AnimationProgress > 2;
+ public bool MustExpire(LayerModel layer) => layer.AnimationProgress >= 2;
+
+ private static float LerpFuncFloat(float start, float end, float percent)
+ {
+ return start + (end - start) * percent;
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Artemis/Artemis/Profiles/Layers/Animations/RotateClockwiseAnimation.cs b/Artemis/Artemis/Profiles/Layers/Animations/RotateClockwiseAnimation.cs
new file mode 100644
index 000000000..2fd32a8d4
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Animations/RotateClockwiseAnimation.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Windows.Media;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Animations
+{
+ public class RotateClockwiseAnimation : ILayerAnimation
+ {
+ public string Name => "Rotate clockwise";
+
+ public void Update(LayerModel layerModel, bool updateAnimations)
+ {
+ var progress = layerModel.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.AnimationProgress = progress;
+ }
+
+ public void Draw(LayerModel layerModel, DrawingContext c, int drawScale)
+ {
+ if (layerModel.Brush == null)
+ return;
+
+ // Set up variables for this frame
+ var fillRect = layerModel.Properties.PropertiesRect(drawScale);
+ var fillSize = Math.Sqrt(fillRect.Width * fillRect.Width + fillRect.Height * fillRect.Height);
+ fillRect.Inflate(fillSize - fillRect.Width, fillSize - fillRect.Height);
+
+ var clip = layerModel.LayerRect(drawScale);
+
+ c.PushClip(new RectangleGeometry(clip));
+ c.PushTransform(new RotateTransform(36 * layerModel.AnimationProgress, fillRect.X + fillRect.Width / 2, fillRect.Y + fillRect.Height / 2));
+ c.DrawRectangle(layerModel.Brush, null, fillRect);
+ c.Pop();
+ c.Pop();
+ }
+
+ public bool MustExpire(LayerModel layer) => layer.AnimationProgress >= 10;
+ }
+}
diff --git a/Artemis/Artemis/Profiles/Layers/Animations/RotateCounterclockwiseAnimation.cs b/Artemis/Artemis/Profiles/Layers/Animations/RotateCounterclockwiseAnimation.cs
new file mode 100644
index 000000000..b79f2c2dc
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Animations/RotateCounterclockwiseAnimation.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Windows.Media;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Animations
+{
+ public class RotateCounterclockwiseAnimation : ILayerAnimation
+ {
+ public string Name => "Rotate counterclockwise";
+
+ public void Update(LayerModel layerModel, bool updateAnimations)
+ {
+ var progress = layerModel.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.AnimationProgress = progress;
+ }
+
+ public void Draw(LayerModel layerModel, DrawingContext c, int drawScale)
+ {
+ if (layerModel.Brush == null)
+ return;
+
+ // Set up variables for this frame
+ var fillRect = layerModel.Properties.PropertiesRect(drawScale);
+ var fillSize = Math.Sqrt(fillRect.Width * fillRect.Width + fillRect.Height * fillRect.Height);
+ fillRect.Inflate(fillSize - fillRect.Width, fillSize - fillRect.Height);
+
+ var clip = layerModel.LayerRect(drawScale);
+
+ c.PushClip(new RectangleGeometry(clip));
+ c.PushTransform(new RotateTransform(36 * layerModel.AnimationProgress*-1, fillRect.X + fillRect.Width / 2, fillRect.Y + fillRect.Height / 2));
+ c.DrawRectangle(layerModel.Brush, null, fillRect);
+ c.Pop();
+ c.Pop();
+ }
+
+ public bool MustExpire(LayerModel layer) => layer.AnimationProgress >= 10;
+ }
+}
diff --git a/Artemis/Artemis/Profiles/Layers/Animations/ShrinkAnimation.cs b/Artemis/Artemis/Profiles/Layers/Animations/ShrinkAnimation.cs
new file mode 100644
index 000000000..185821f0b
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Animations/ShrinkAnimation.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Windows.Media;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Animations
+{
+ public class ShrinkAnimation : ILayerAnimation
+ {
+ public string Name => "Shrink";
+
+ public void Update(LayerModel layerModel, bool updateAnimations)
+ {
+ // TODO: Generic implementation
+ // Reset animation progress if layer wasn't drawn for 100ms
+ if ((new TimeSpan(0, 0, 0, 0, 100) < DateTime.Now - layerModel.LastRender) && updateAnimations)
+ layerModel.AnimationProgress = 0;
+
+ var progress = layerModel.AnimationProgress;
+
+ if (MustExpire(layerModel))
+ progress = 10;
+ 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.AnimationProgress = progress;
+ }
+
+ public void Draw(LayerModel layerModel, DrawingContext c, int drawScale)
+ {
+ if (layerModel.Brush == null)
+ return;
+
+ // Set up variables for this frame
+ var rect = layerModel.Properties.Contain
+ ? layerModel.LayerRect(drawScale)
+ : layerModel.Properties.PropertiesRect(drawScale);
+
+ var clip = layerModel.LayerRect(drawScale);
+
+ // Take an offset of 4 to allow layers to slightly leave their bounds
+ var progress = (6.0 - layerModel.AnimationProgress)*10.0;
+ if (progress < 0)
+ {
+ // Can't meddle with the original brush because it's frozen.
+ var brush = layerModel.Brush.Clone();
+ brush.Opacity = 1 + 0.025*progress;
+ if (brush.Opacity < 0)
+ brush.Opacity = 0;
+ if (brush.Opacity > 1)
+ brush.Opacity = 1;
+ layerModel.Brush = brush;
+ }
+ rect.Inflate(-rect.Width/100.0*progress, -rect.Height/100.0*progress);
+ clip.Inflate(-clip.Width/100.0*progress, -clip.Height/100.0*progress);
+
+ c.PushClip(new RectangleGeometry(clip));
+ c.DrawRectangle(layerModel.Brush, null, rect);
+ c.Pop();
+ }
+
+ public bool MustExpire(LayerModel layer) => layer.AnimationProgress <= 0;
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs b/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs
index 255b059b8..31aafa17d 100644
--- a/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs
+++ b/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs
@@ -1,7 +1,6 @@
-using System;
-using System.Linq;
+using System.Linq;
using Artemis.Modules.Abstract;
-using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Abstract;
using Artemis.Profiles.Layers.Models;
namespace Artemis.Profiles.Layers.Conditions
@@ -12,18 +11,18 @@ namespace Artemis.Profiles.Layers.Conditions
{
lock (layerModel.Properties.Conditions)
{
+ var checkConditions = layerModel.Properties.Conditions.Where(c => c.Field != null).ToList();
switch (layerModel.Properties.ConditionType)
{
case ConditionType.AnyMet:
- return layerModel.Properties.Conditions.Any(cm => cm.ConditionMet(dataModel));
+ return checkConditions.Any(cm => cm.ConditionMet(dataModel));
case ConditionType.AllMet:
- return layerModel.Properties.Conditions.All(cm => cm.ConditionMet(dataModel));
+ return checkConditions.All(cm => cm.ConditionMet(dataModel));
case ConditionType.NoneMet:
- return !layerModel.Properties.Conditions.Any(cm => cm.ConditionMet(dataModel));
- default:
- return false;
+ return !checkConditions.Any(cm => cm.ConditionMet(dataModel));
}
+ return false;
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs b/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs
index 5db52f958..de5962b44 100644
--- a/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs
+++ b/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs
@@ -1,37 +1,50 @@
-using System;
-using System.Linq;
-using Artemis.Modules.Abstract;
-using Artemis.Profiles.Layers.Interfaces;
-using Artemis.Profiles.Layers.Models;
-
-namespace Artemis.Profiles.Layers.Conditions
-{
- public class EventCondition : ILayerCondition
- {
- public bool ConditionsMet(LayerModel layerModel, ModuleDataModel dataModel)
- {
- lock (layerModel.Properties.Conditions)
- {
- var conditionsMet = false;
- switch (layerModel.Properties.ConditionType)
- {
- case ConditionType.AnyMet:
- conditionsMet = layerModel.Properties.Conditions.Any(cm => cm.ConditionMet(dataModel));
- break;
- case ConditionType.AllMet:
- conditionsMet = layerModel.Properties.Conditions.All(cm => cm.ConditionMet(dataModel));
- break;
- case ConditionType.NoneMet:
- conditionsMet = !layerModel.Properties.Conditions.Any(cm => cm.ConditionMet(dataModel));
- break;
- }
- layerModel.EventProperties.Update(layerModel, conditionsMet);
-
- if (conditionsMet && layerModel.EventProperties.CanTrigger)
- layerModel.EventProperties.TriggerEvent(layerModel);
-
- return layerModel.EventProperties.MustDraw;
- }
- }
- }
-}
\ No newline at end of file
+using System.Linq;
+using Artemis.Modules.Abstract;
+using Artemis.Profiles.Layers.Abstract;
+using Artemis.Profiles.Layers.Models;
+
+namespace Artemis.Profiles.Layers.Conditions
+{
+ public class EventCondition : ILayerCondition
+ {
+ public bool ConditionsMet(LayerModel layerModel, ModuleDataModel dataModel)
+ {
+ lock (layerModel.Properties.Conditions)
+ {
+ var checkConditions = layerModel.Properties.Conditions.Where(c => c.Field != null).ToList();
+
+ // Don't trigger constantly when there are no conditions
+ if (!checkConditions.Any())
+ {
+ layerModel.EventProperties.Update(layerModel, false);
+ return layerModel.EventProperties.MustDraw;
+ }
+
+ // Determine whether conditions are met
+ var conditionsMet = false;
+ switch (layerModel.Properties.ConditionType)
+ {
+ case ConditionType.AnyMet:
+ conditionsMet = checkConditions.Any(cm => cm.ConditionMet(dataModel));
+ break;
+ case ConditionType.AllMet:
+ conditionsMet = checkConditions.All(cm => cm.ConditionMet(dataModel));
+ break;
+ case ConditionType.NoneMet:
+ conditionsMet = !checkConditions.Any(cm => cm.ConditionMet(dataModel));
+ break;
+ }
+
+ // Update the event properties
+ layerModel.EventProperties.Update(layerModel, conditionsMet);
+
+ // If conditions are met trigger the event, this won't do anything if the event isn't ready to be triggered yet
+ if (conditionsMet)
+ layerModel.EventProperties.TriggerEvent(layerModel);
+
+ // Return the event's MustDraw
+ return layerModel.EventProperties.MustDraw;
+ }
+ }
+ }
+}
diff --git a/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs
index d145bf7ae..07c36de83 100644
--- a/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs
+++ b/Artemis/Artemis/Profiles/Layers/Models/EventPropertiesModel.cs
@@ -1,4 +1,5 @@
using System;
+using System.Timers;
using Newtonsoft.Json;
namespace Artemis.Profiles.Layers.Models
@@ -10,7 +11,7 @@ namespace Artemis.Profiles.Layers.Models
public TimeSpan TriggerDelay { get; set; }
[JsonIgnore]
- public bool CanTrigger { get; set; }
+ public bool CanTrigger { get; set; } = true;
[JsonIgnore]
public DateTime EventTriggerTime { get; set; }
@@ -18,30 +19,46 @@ namespace Artemis.Profiles.Layers.Models
[JsonIgnore]
public bool MustDraw { get; set; }
- public DateTime EventCanTriggerTime { get; set; }
-
///
- /// Resets the event's properties and triggers it
+ /// If possible, triggers the event
///
public virtual void TriggerEvent(LayerModel layer)
{
if (!CanTrigger)
return;
+ // Don't allow any more triggering regardless of what happens next
+ CanTrigger = false;
+
+ // If there is a trigger delay, stop here and await that delay
if (TriggerDelay > TimeSpan.Zero)
{
- if (EventCanTriggerTime == DateTime.MinValue)
- EventCanTriggerTime = DateTime.Now;
+ var timer = new Timer(TriggerDelay.TotalMilliseconds) {AutoReset = false};
+ timer.Elapsed += (sender, args) =>
+ {
+ HardTrigger(layer);
+ timer.Dispose();
+ };
+ timer.Start();
- if (DateTime.Now - EventCanTriggerTime < TriggerDelay)
- return;
-
- EventCanTriggerTime = DateTime.MinValue;
+ return;
}
- CanTrigger = false;
+ // Trigger the event
+ HardTrigger(layer);
+ }
+
+ ///
+ /// Instantly trigger the event regardless of current state
+ ///
+ ///
+ public void HardTrigger(LayerModel layer)
+ {
MustDraw = true;
+ CanTrigger = false;
EventTriggerTime = DateTime.Now;
+
+ // Reset the animation in case it didn't finish before
layer.AnimationProgress = 0.0;
}
@@ -60,7 +77,7 @@ namespace Artemis.Profiles.Layers.Models
return DateTime.Now - EventTriggerTime > Length;
}
if (ExpirationType == ExpirationType.Animation)
- return (layer.LayerAnimation == null) || layer.LayerAnimation.MustExpire(layer);
+ return layer.LayerAnimation == null || layer.LayerAnimation.MustExpire(layer);
return true;
}
@@ -68,24 +85,17 @@ namespace Artemis.Profiles.Layers.Models
// Called every frame, if parent conditions met.
public void Update(LayerModel layerModel, bool conditionsMet)
{
- if (EventCanTriggerTime > DateTime.MinValue && (DateTime.Now - EventCanTriggerTime > TriggerDelay))
- {
- CanTrigger = true;
- TriggerEvent(layerModel);
+ // If the event isn't finished yet just keep going
+ if (MustDraw && !MustStop(layerModel))
return;
- }
- if (MustDraw && MustStop(layerModel))
- MustDraw = false;
+ // Otherwise make sure MustDraw is false
+ MustDraw = false;
+ // If the conditions aren't met and the event has finished it can be triggered again
if (!conditionsMet)
CanTrigger = true;
}
-
- protected bool DelayExpired()
- {
- return EventCanTriggerTime > DateTime.MinValue && DateTime.Now - EventCanTriggerTime >= TriggerDelay;
- }
}
public enum ExpirationType
@@ -93,4 +103,4 @@ namespace Artemis.Profiles.Layers.Models
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
index 76c9cfb08..e0d9a453a 100644
--- a/Artemis/Artemis/Profiles/Layers/Models/KeyboardEventPropertiesModel.cs
+++ b/Artemis/Artemis/Profiles/Layers/Models/KeyboardEventPropertiesModel.cs
@@ -7,7 +7,7 @@ namespace Artemis.Profiles.Layers.Models
{
public override void TriggerEvent(LayerModel layer)
{
- if (CanTrigger && DelayExpired())
+ if (CanTrigger)
{
if (layer.GifImage != null)
layer.GifImage.CurrentFrame = 0;
@@ -18,12 +18,10 @@ namespace Artemis.Profiles.Layers.Models
public override bool MustStop(LayerModel layer)
{
- if (ExpirationType != ExpirationType.Animation)
- return base.MustStop(layer);
-
- if (layer.LayerType is KeyboardGifType)
+ if (layer.LayerType is KeyboardGifType && ExpirationType == ExpirationType.Animation)
return layer.GifImage?.CurrentFrame >= layer.GifImage?.FrameCount - 1;
- return (layer.LayerAnimation == null) || layer.LayerAnimation.MustExpire(layer);
+
+ return base.MustStop(layer);
}
}
-}
\ No newline at end of file
+}
diff --git a/Artemis/Artemis/Profiles/Layers/Models/LayerConditionModel.cs b/Artemis/Artemis/Profiles/Layers/Models/LayerConditionModel.cs
index 71de0a2ce..560d74408 100644
--- a/Artemis/Artemis/Profiles/Layers/Models/LayerConditionModel.cs
+++ b/Artemis/Artemis/Profiles/Layers/Models/LayerConditionModel.cs
@@ -3,6 +3,7 @@ using System.Globalization;
using Artemis.Modules.Abstract;
using Artemis.Utilities;
using DynamicExpresso;
+using MahApps.Metro.Controls;
namespace Artemis.Profiles.Layers.Models
{
@@ -20,6 +21,7 @@ namespace Artemis.Profiles.Layers.Models
public string Value { get; set; }
public string Operator { get; set; }
public string Type { get; set; }
+ public HotKey HotKey { get; set; }
public bool ConditionMet(ModuleDataModel subject)
{
diff --git a/Artemis/Artemis/Profiles/Layers/Models/LayerKeybindModel.cs b/Artemis/Artemis/Profiles/Layers/Models/LayerKeybindModel.cs
new file mode 100644
index 000000000..087e506ec
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Layers/Models/LayerKeybindModel.cs
@@ -0,0 +1,126 @@
+using System;
+using System.Windows.Forms;
+using Artemis.Managers;
+using Artemis.Models;
+using Artemis.Profiles.Layers.Conditions;
+using MahApps.Metro.Controls;
+
+namespace Artemis.Profiles.Layers.Models
+{
+ public class LayerKeybindModel
+ {
+ private KeybindModel _downKeybind;
+ private KeybindModel _upKeybind;
+
+ public ToggleType ToggleType { get; set; }
+ public HotKey HotKey { get; set; }
+ public MouseButtons? MouseButtons { get; set; }
+
+ public void Unregister()
+ {
+ if (_downKeybind != null)
+ {
+ KeybindManager.Remove(_downKeybind);
+ _downKeybind = null;
+ }
+ if (_upKeybind != null)
+ {
+ KeybindManager.Remove(_upKeybind);
+ _upKeybind = null;
+ }
+ }
+
+ internal void Register(LayerModel layerModel, int index)
+ {
+ Unregister();
+
+ if (layerModel.IsEvent)
+ RegisterEvent(layerModel, index);
+ else if (ToggleType == ToggleType.EnableHeldDown || ToggleType == ToggleType.DisableHeldDown)
+ RegisterToggle(layerModel, index);
+ else
+ RegisterRegular(layerModel, index);
+ }
+
+ private void RegisterEvent(LayerModel layerModel, int index)
+ {
+ Action action = () =>
+ {
+ layerModel.EventProperties.TriggerEvent(layerModel);
+ };
+ // Either bind HotKey or mouse buttons depending on what isn't null
+ if (HotKey != null)
+ _downKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-down", HotKey, PressType.Down, action);
+ else if (MouseButtons != null)
+ _downKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-down", MouseButtons.Value, PressType.Down, action);
+ KeybindManager.AddOrUpdate(_downKeybind);
+ }
+
+ private void RegisterRegular(LayerModel layerModel, int index)
+ {
+ // Bind Enable, Disable or Toggle
+ Action action = null;
+ switch (ToggleType)
+ {
+ case ToggleType.Enable:
+ action = () => layerModel.RenderAllowed = true;
+ break;
+ case ToggleType.Disable:
+ action = () => layerModel.RenderAllowed = false;
+ break;
+ case ToggleType.Toggle:
+ action = () => layerModel.RenderAllowed = !layerModel.RenderAllowed;
+ break;
+ }
+
+ // Either bind HotKey or mouse buttons depending on what isn't null
+ if (HotKey != null)
+ _downKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-down", HotKey, PressType.Down, action);
+ else if (MouseButtons != null)
+ _downKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-down", MouseButtons.Value, PressType.Down, action);
+ KeybindManager.AddOrUpdate(_downKeybind);
+ }
+
+ private void RegisterToggle(LayerModel layerModel, int index)
+ {
+ Action downAction = null;
+ Action upAction = null;
+ switch (ToggleType)
+ {
+ case ToggleType.EnableHeldDown:
+ layerModel.RenderAllowed = false;
+ downAction = () => layerModel.RenderAllowed = true;
+ upAction = () => layerModel.RenderAllowed = false;
+ break;
+ case ToggleType.DisableHeldDown:
+ downAction = () => layerModel.RenderAllowed = false;
+ upAction = () => layerModel.RenderAllowed = true;
+ break;
+ }
+
+ // Either bind HotKey or mouse buttons depending on what isn't null
+ if (HotKey != null)
+ {
+ _downKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-down", HotKey, PressType.Down, downAction);
+ _upKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-up", HotKey, PressType.Up, upAction);
+ }
+ else if (MouseButtons != null)
+ {
+ _downKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-down", MouseButtons.Value, PressType.Down, downAction);
+ _upKeybind = new KeybindModel($"{layerModel.GetHashCode()}-{layerModel.Name}-{index}-up", MouseButtons.Value, PressType.Up, upAction);
+ }
+ KeybindManager.AddOrUpdate(_downKeybind);
+ KeybindManager.AddOrUpdate(_upKeybind);
+ return;
+ }
+ }
+
+ public enum ToggleType
+ {
+ Enable,
+ Disable,
+ Toggle,
+ EnableHeldDown,
+ DisableHeldDown
+ }
+}
diff --git a/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs b/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs
index e04354364..8007936f5 100644
--- a/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs
+++ b/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Windows;
using System.Windows.Media;
using Artemis.Modules.Abstract;
+using Artemis.Profiles.Layers.Abstract;
using Artemis.Profiles.Layers.Animations;
using Artemis.Profiles.Layers.Conditions;
using Artemis.Profiles.Layers.Interfaces;
@@ -20,10 +21,11 @@ namespace Artemis.Profiles.Layers.Models
{
Children = new ChildItemCollection(this);
TweenModel = new TweenModel(this);
+ RenderAllowed = true;
var model = Properties as KeyboardPropertiesModel;
if (model != null)
- GifImage = new GifImage(model.GifFile);
+ GifImage = new GifImage(model.GifFile, Properties.AnimationSpeed);
}
[JsonIgnore]
@@ -38,7 +40,7 @@ namespace Artemis.Profiles.Layers.Models
///
///
///
- public bool ConditionsMet(ModuleDataModel dataModel)
+ public bool AreConditionsMet(ModuleDataModel dataModel)
{
// Conditions are not even checked if the layer isn't enabled
return Enabled && LayerCondition.ConditionsMet(this, dataModel);
@@ -91,7 +93,7 @@ namespace Artemis.Profiles.Layers.Models
///
public void Draw(ModuleDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations)
{
- if (Brush == null)
+ if (Brush == null || !preview && !RenderAllowed)
return;
LayerType.Draw(this, c);
@@ -106,14 +108,12 @@ namespace Artemis.Profiles.Layers.Models
// 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)
};
- }
}
///
@@ -220,19 +220,15 @@ namespace Artemis.Profiles.Layers.Models
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);
}
}
@@ -246,9 +242,10 @@ namespace Artemis.Profiles.Layers.Models
if (height < 0)
height = 0;
- return new Rect(X*scale, Y*scale, width*scale, height*scale);
+ return new Rect(X * scale, Y * scale, width * scale, height * scale);
}
+ // TODO: Make this and ProfileModel's GetRenderLayers the same through inheritance
///
/// 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
@@ -259,22 +256,22 @@ namespace Artemis.Profiles.Layers.Models
/// A flat list containing all layers that must be rendered
public List GetRenderLayers(ModuleDataModel dataModel, bool keyboardOnly, bool ignoreConditions = false)
{
- var layers = new List();
- foreach (var layerModel in Children.OrderByDescending(l => l.Order))
- {
- if (!layerModel.Enabled || keyboardOnly && layerModel.LayerType.DrawType != DrawType.Keyboard)
- continue;
-
- if (!ignoreConditions)
- {
- if (!layerModel.ConditionsMet(dataModel))
- continue;
- }
-
- layers.Add(layerModel);
- layers.AddRange(layerModel.GetRenderLayers(dataModel, keyboardOnly, ignoreConditions));
- }
-
+ var layers = new List();
+ foreach (var layerModel in Children.OrderByDescending(l => l.Order))
+ {
+ if (!layerModel.Enabled || keyboardOnly && layerModel.LayerType.DrawType != DrawType.Keyboard)
+ continue;
+
+ if (!ignoreConditions)
+ {
+ if (!layerModel.AreConditionsMet(dataModel) || !layerModel.RenderAllowed)
+ continue;
+ }
+
+ layers.Add(layerModel);
+ layers.AddRange(layerModel.GetRenderLayers(dataModel, keyboardOnly, ignoreConditions));
+ }
+
return layers;
}
@@ -286,6 +283,26 @@ namespace Artemis.Profiles.Layers.Models
LayerCondition = new DataModelCondition();
}
+ public void SetupKeybinds()
+ {
+ RenderAllowed = true;
+
+ // Clean up old keybinds
+ RemoveKeybinds();
+
+ for (var index = 0; index < Properties.LayerKeybindModels.Count; index++)
+ {
+ var keybindModel = Properties.LayerKeybindModels[index];
+ keybindModel.Register(this, index);
+ }
+ }
+
+ public void RemoveKeybinds()
+ {
+ foreach (var keybindModel in Properties.LayerKeybindModels)
+ keybindModel.Unregister();
+ }
+
#region Properties
#region Layer type properties
@@ -301,6 +318,7 @@ namespace Artemis.Profiles.Layers.Models
public string Name { get; set; }
public int Order { get; set; }
public bool Enabled { get; set; }
+ public bool RenderAllowed { get; set; }
public bool Expanded { get; set; }
public bool IsEvent { get; set; }
public LayerPropertiesModel Properties { get; set; }
@@ -390,7 +408,13 @@ namespace Artemis.Profiles.Layers.Models
get { return Profile; }
set { Profile = value; }
}
-
+
#endregion
+
+ ///
+ public override string ToString()
+ {
+ return $"{nameof(Name)}: {Name}, {nameof(Order)}: {Order}, {nameof(X)}: {X}, {nameof(Y)}: {Y}, {nameof(Width)}: {Width}, {nameof(Height)}: {Height}";
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Artemis/Artemis/Profiles/Layers/Models/LayerPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Models/LayerPropertiesModel.cs
index c8720f1a4..c1ec39f17 100644
--- a/Artemis/Artemis/Profiles/Layers/Models/LayerPropertiesModel.cs
+++ b/Artemis/Artemis/Profiles/Layers/Models/LayerPropertiesModel.cs
@@ -25,6 +25,7 @@ namespace Artemis.Profiles.Layers.Models
Opacity = source.Opacity;
AnimationSpeed = source.AnimationSpeed;
Conditions = source.Conditions;
+ LayerKeybindModels = source.LayerKeybindModels;
ConditionType = source.ConditionType;
DynamicProperties = source.DynamicProperties;
Brush = source.Brush;
@@ -50,7 +51,8 @@ namespace Artemis.Profiles.Layers.Models
public string HeightEase { get; set; }
public string OpacityEase { get; set; }
public ConditionType ConditionType { get; set; }
- public List Conditions { get; set; } = new List();
+ public List Conditions { get; set; } = new List();
+ public List LayerKeybindModels { get; set; } = new List();
public List DynamicProperties { get; set; } = new List();
[JsonConverter(typeof(BrushJsonConverter))]
diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesView.xaml
index 8201fe8d9..f56ea2b83 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesView.xaml
+++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightPropertiesView.xaml
@@ -1,15 +1,15 @@
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:converters="clr-namespace:Artemis.Utilities.Converters"
+ xmlns:system="clr-namespace:System;assembly=mscorlib"
+ xmlns:model="clr-namespace:Artemis.Profiles.Layers.Types.AmbientLight.Model"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:helper="clr-namespace:Artemis.Profiles.Layers.Types.AmbientLight.Helper"
+ mc:Ignorable="d"
+ d:DesignHeight="600" d:DesignWidth="500">
@@ -29,135 +29,101 @@
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Helper/CheckboxEnumFlagHelper.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Helper/ToggleSwitchButtonEnumFlagHelper.cs
similarity index 52%
rename from Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Helper/CheckboxEnumFlagHelper.cs
rename to Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Helper/ToggleSwitchButtonEnumFlagHelper.cs
index b6157ad68..f1c499721 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Helper/CheckboxEnumFlagHelper.cs
+++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Helper/ToggleSwitchButtonEnumFlagHelper.cs
@@ -1,18 +1,18 @@
using System;
using System.Windows;
-using System.Windows.Controls;
using Artemis.Profiles.Layers.Types.AmbientLight.Model.Extensions;
+using MahApps.Metro.Controls;
namespace Artemis.Profiles.Layers.Types.AmbientLight.Helper
{
- public class CheckboxEnumFlagHelper
+ public class ToggleSwitchButtonEnumFlagHelper
{
#region DependencyProperties
// ReSharper disable InconsistentNaming
public static readonly DependencyProperty FlagsProperty = DependencyProperty.RegisterAttached(
- "Flags", typeof(Enum), typeof(CheckboxEnumFlagHelper),
+ "Flags", typeof(Enum), typeof(ToggleSwitchButtonEnumFlagHelper),
new FrameworkPropertyMetadata(default(Enum), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
FlagsChanged));
@@ -27,7 +27,7 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Helper
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.RegisterAttached(
- "Value", typeof(Enum), typeof(CheckboxEnumFlagHelper), new PropertyMetadata(default(Enum), ValueChanged));
+ "Value", typeof(Enum), typeof(ToggleSwitchButtonEnumFlagHelper), new PropertyMetadata(default(Enum), ValueChanged));
public static void SetValue(DependencyObject element, Enum value)
{
@@ -48,50 +48,54 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Helper
private static void FlagsChanged(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
- UpdateTarget(dependencyObject as CheckBox, dependencyPropertyChangedEventArgs.NewValue as Enum);
+ UpdateTarget(dependencyObject as ToggleSwitchButton, dependencyPropertyChangedEventArgs.NewValue as Enum);
}
private static void ValueChanged(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
- var checkbox = dependencyObject as CheckBox;
- if (checkbox == null) return;
+ var toggleSwitchButton = dependencyObject as ToggleSwitchButton;
+ if (toggleSwitchButton == null)
+ return;
- checkbox.Checked -= UpdateSource;
- checkbox.Unchecked -= UpdateSource;
+ toggleSwitchButton.Checked -= UpdateSource;
+ toggleSwitchButton.Unchecked -= UpdateSource;
if (dependencyPropertyChangedEventArgs.NewValue != null)
{
- checkbox.Checked += UpdateSource;
- checkbox.Unchecked += UpdateSource;
+ toggleSwitchButton.Checked += UpdateSource;
+ toggleSwitchButton.Unchecked += UpdateSource;
}
- UpdateTarget(checkbox, GetFlags(checkbox));
+ UpdateTarget(toggleSwitchButton, GetFlags(toggleSwitchButton));
}
- private static void UpdateTarget(CheckBox checkbox, Enum flags)
+ private static void UpdateTarget(ToggleSwitchButton toggleSwitchButton, Enum flags)
{
- if (checkbox == null) return;
+ if (toggleSwitchButton == null)
+ return;
- var value = GetValue(checkbox);
- checkbox.IsChecked = value != null && (flags?.HasFlag(value) ?? false);
+ var value = GetValue(toggleSwitchButton);
+ toggleSwitchButton.IsChecked = value != null && (flags?.HasFlag(value) ?? false);
}
private static void UpdateSource(object sender, RoutedEventArgs routedEventArgs)
{
- var checkbox = sender as CheckBox;
- if (checkbox == null) return;
+ var toggleSwitchButton = sender as ToggleSwitchButton;
+ if (toggleSwitchButton == null)
+ return;
- var flags = GetFlags(checkbox);
- var value = GetValue(checkbox);
- if (value == null) return;
+ var flags = GetFlags(toggleSwitchButton);
+ var value = GetValue(toggleSwitchButton);
+ if (value == null)
+ return;
- if (checkbox.IsChecked ?? false)
- SetFlags(checkbox, flags == null ? value : flags.SetFlag(value, true, flags.GetType()));
+ if (toggleSwitchButton.IsChecked ?? false)
+ SetFlags(toggleSwitchButton, flags == null ? value : flags.SetFlag(value, true, flags.GetType()));
else
- SetFlags(checkbox, flags?.SetFlag(value, false, flags.GetType()));
+ SetFlags(toggleSwitchButton, flags?.SetFlag(value, false, flags.GetType()));
}
#endregion
}
-}
\ No newline at end of file
+}
diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesView.xaml
index 00ec05a65..52dd1d2b4 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesView.xaml
+++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesView.xaml
@@ -1,26 +1,26 @@
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:ncore="http://schemas.ncore.com/wpf/xaml/colorbox"
+ xmlns:properties="clr-namespace:Artemis.Profiles.Layers.Types.Audio"
+ xmlns:system="clr-namespace:System;assembly=mscorlib"
+ xmlns:converters="clr-namespace:Artemis.Utilities.Converters"
+ mc:Ignorable="d"
+ d:DesignHeight="600" d:DesignWidth="500">
+ ObjectType="{x:Type system:Enum}"
+ x:Key="MmDeviceTypeEnumValues">
+ ObjectType="{x:Type system:Enum}"
+ x:Key="DirectionEnumValues">
@@ -28,25 +28,22 @@
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
@@ -55,53 +52,38 @@
-
-
+
+
-
-
+
+
-
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
-
-
+
+
-
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Types/ConicalBrush/ConicalBrushPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/ConicalBrush/ConicalBrushPropertiesView.xaml
index d2a9ad61b..b406c297d 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/ConicalBrush/ConicalBrushPropertiesView.xaml
+++ b/Artemis/Artemis/Profiles/Layers/Types/ConicalBrush/ConicalBrushPropertiesView.xaml
@@ -10,27 +10,23 @@
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
@@ -39,42 +35,29 @@
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
+
+
+
-
+
+
diff --git a/Artemis/Artemis/Profiles/Layers/Types/ConicalBrush/ConicalBrushType.cs b/Artemis/Artemis/Profiles/Layers/Types/ConicalBrush/ConicalBrushType.cs
index cb2e4cff2..f96b597ee 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/ConicalBrush/ConicalBrushType.cs
+++ b/Artemis/Artemis/Profiles/Layers/Types/ConicalBrush/ConicalBrushType.cs
@@ -36,7 +36,7 @@ namespace Artemis.Profiles.Layers.Types.ConicalBrush
public ImageSource DrawThumbnail(LayerModel layer)
{
- _conicalGradientDrawerThumbnail.GradientStops = GetGradientStops(layer.Brush).Select(x => new Tuple(x.Offset, x.Color)).ToList();
+ _conicalGradientDrawerThumbnail.GradientStops = GetGradientStops(layer.Properties.Brush).Select(x => new Tuple(x.Offset, x.Color)).ToList();
_conicalGradientDrawerThumbnail.Update();
Rect thumbnailRect = new Rect(0, 0, 18, 18);
diff --git a/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesView.xaml
index 7745310f3..a093f1de5 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesView.xaml
+++ b/Artemis/Artemis/Profiles/Layers/Types/Generic/GenericPropertiesView.xaml
@@ -4,73 +4,57 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ncore="http://schemas.ncore.com/wpf/xaml/colorbox"
- xmlns:ObjectModel="clr-namespace:System.Collections.ObjectModel;assembly=System"
x:Class="Artemis.Profiles.Layers.Types.Generic.GenericPropertiesView"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="500">
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
-
+
-
+
-
+
-
+
diff --git a/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetPropertiesView.xaml
index c6189cbb0..217146e3e 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetPropertiesView.xaml
+++ b/Artemis/Artemis/Profiles/Layers/Types/Headset/HeadsetPropertiesView.xaml
@@ -7,26 +7,23 @@
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
-
-
+
+
@@ -35,35 +32,26 @@
-
-
+
+
-
-
-
-
-
-
+
+
+
+
-
+
-
+
-
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs
index f0b463067..cb7d09f1d 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs
+++ b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs
@@ -12,7 +12,6 @@ using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models;
using Artemis.Properties;
using Artemis.Utilities;
-using Artemis.Utilities.Keyboard;
using Artemis.ViewModels;
using Artemis.ViewModels.Profiles;
@@ -30,7 +29,7 @@ namespace Artemis.Profiles.Layers.Types.KeyPress
_deviceManager = deviceManager;
_keyPressLayers = new List();
- KeyboardHook.KeyDownCallback += KeyboardHookOnKeyDownCallback;
+ InputHook.KeyDownCallback += KeyboardHookOnKeyDownCallback;
}
public RadialGradientBrush TempBrush { get; set; }
@@ -140,6 +139,9 @@ namespace Artemis.Profiles.Layers.Types.KeyPress
lock (_keyPressLayers)
{
+ // Ensure the layer has keypress properties
+ SetupProperties(_layerModel);
+
var properties = (KeyPressPropertiesModel) _layerModel.Properties;
var layer = LayerModel.CreateLayer();
layer.Properties.X = keyMatch.Value.X - properties.Scale/2;
diff --git a/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesView.xaml
index 64b806c84..cd413e413 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesView.xaml
+++ b/Artemis/Artemis/Profiles/Layers/Types/Keyboard/KeyboardPropertiesView.xaml
@@ -1,36 +1,33 @@
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:ncore="http://schemas.ncore.com/wpf/xaml/colorbox"
+ mc:Ignorable="d"
+ d:DesignHeight="500" d:DesignWidth="500">
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
@@ -39,32 +36,19 @@
-
-
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
@@ -78,28 +62,25 @@
-
-
-
-
+
+
+
+
-
+
+
+
-
+
-
+
+
\ 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
index 19c0f5611..c8d2d7c22 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs
+++ b/Artemis/Artemis/Profiles/Layers/Types/KeyboardGif/KeyboardGifType.cs
@@ -42,9 +42,9 @@ namespace Artemis.Profiles.Layers.Types.KeyboardGif
// Only reconstruct GifImage if the underlying source has changed
if (layerModel.GifImage == null)
- layerModel.GifImage = new GifImage(props.GifFile);
+ layerModel.GifImage = new GifImage(props.GifFile, props.AnimationSpeed);
if (layerModel.GifImage.Source != props.GifFile)
- layerModel.GifImage = new GifImage(props.GifFile);
+ layerModel.GifImage = new GifImage(props.GifFile, props.AnimationSpeed);
var rect = new Rect(layerModel.X*4, layerModel.Y*4, layerModel.Width*4, layerModel.Height*4);
@@ -61,6 +61,9 @@ namespace Artemis.Profiles.Layers.Types.KeyboardGif
public void Update(LayerModel layerModel, ModuleDataModel dataModel, bool isPreview = false)
{
layerModel.ApplyProperties(true);
+ if (layerModel.GifImage != null)
+ layerModel.GifImage.AnimationSpeed = layerModel.Properties.AnimationSpeed;
+
if (isPreview || dataModel == null)
return;
@@ -74,7 +77,8 @@ namespace Artemis.Profiles.Layers.Types.KeyboardGif
if (layerModel.Properties is KeyboardPropertiesModel)
return;
- layerModel.Properties = new KeyboardPropertiesModel(layerModel.Properties);
+ // Set animation speed to 1.5, this translates back to a GIF playback rate of x1
+ layerModel.Properties = new KeyboardPropertiesModel(layerModel.Properties) {AnimationSpeed = 1.5};
}
public LayerPropertiesViewModel SetupViewModel(LayerEditorViewModel layerEditorViewModel,
diff --git a/Artemis/Artemis/Profiles/Layers/Types/Mouse/MousePropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/Mouse/MousePropertiesView.xaml
index 66aa011a1..1f7956062 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/Mouse/MousePropertiesView.xaml
+++ b/Artemis/Artemis/Profiles/Layers/Types/Mouse/MousePropertiesView.xaml
@@ -1,32 +1,29 @@
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:ncore="http://schemas.ncore.com/wpf/xaml/colorbox"
+ mc:Ignorable="d"
+ d:DesignHeight="300" d:DesignWidth="300">
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
-
-
+
+
@@ -35,35 +32,25 @@
-
-
+
+
-
-
-
-
-
-
+
+
+
+
-
+
-
+
-
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematPropertiesView.xaml b/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematPropertiesView.xaml
index 13c490273..810ab9845 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematPropertiesView.xaml
+++ b/Artemis/Artemis/Profiles/Layers/Types/Mousemat/MousematPropertiesView.xaml
@@ -1,32 +1,29 @@
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:ncore="http://schemas.ncore.com/wpf/xaml/colorbox"
+ mc:Ignorable="d"
+ d:DesignHeight="300" d:DesignWidth="300">
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
-
-
+
+
@@ -35,35 +32,25 @@
-
-
+
+
-
-
-
-
-
-
+
+
+
+
-
+
-
+
-
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/Modules/LuaEventsModule.cs b/Artemis/Artemis/Profiles/Lua/Modules/LuaEventsModule.cs
index d2c313886..02abc90dd 100644
--- a/Artemis/Artemis/Profiles/Lua/Modules/LuaEventsModule.cs
+++ b/Artemis/Artemis/Profiles/Lua/Modules/LuaEventsModule.cs
@@ -5,7 +5,7 @@ using Artemis.Events;
using Artemis.Managers;
using Artemis.Profiles.Lua.Modules.Events;
using Artemis.Profiles.Lua.Wrappers;
-using Artemis.Utilities.Keyboard;
+using Artemis.Utilities;
using MoonSharp.Interpreter;
using NLog;
@@ -23,7 +23,7 @@ namespace Artemis.Profiles.Lua.Modules
_profileModel = luaManager.ProfileModel;
_profileModel.OnDeviceUpdatedEvent += OnDeviceUpdatedEvent;
_profileModel.OnDeviceDrawnEvent += OnDeviceDrawnEvent;
- KeyboardHook.KeyDownCallback += KeyboardHookOnKeyDownCallback;
+ InputHook.KeyDownCallback += KeyboardHookOnKeyDownCallback;
}
public override string ModuleName => "Events";
@@ -118,7 +118,7 @@ namespace Artemis.Profiles.Lua.Modules
{
_profileModel.OnDeviceUpdatedEvent -= OnDeviceUpdatedEvent;
_profileModel.OnDeviceDrawnEvent -= OnDeviceDrawnEvent;
- KeyboardHook.KeyDownCallback -= KeyboardHookOnKeyDownCallback;
+ InputHook.KeyDownCallback -= KeyboardHookOnKeyDownCallback;
}
#endregion
diff --git a/Artemis/Artemis/Profiles/Lua/Modules/LuaKeybindModule.cs b/Artemis/Artemis/Profiles/Lua/Modules/LuaKeybindModule.cs
new file mode 100644
index 000000000..82fab31b8
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Lua/Modules/LuaKeybindModule.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Input;
+using Artemis.Managers;
+using Artemis.Models;
+using MahApps.Metro.Controls;
+using MoonSharp.Interpreter;
+
+namespace Artemis.Profiles.Lua.Modules
+{
+ [MoonSharpUserData]
+ public class LuaKeybindModule : LuaModule
+ {
+ private readonly List _keybindModels;
+
+ public LuaKeybindModule(LuaManager luaManager) : base(luaManager)
+ {
+ _keybindModels = new List();
+ LuaManager.ProfileModel.OnProfileUpdatedEvent += ProfileModelOnOnProfileUpdatedEvent;
+ }
+
+ public override string ModuleName => "Keybind";
+
+ private void ProfileModelOnOnProfileUpdatedEvent(object sender, EventArgs e)
+ {
+ foreach (var keybindModel in _keybindModels)
+ KeybindManager.AddOrUpdate(keybindModel);
+ }
+
+ ///
+ /// Sets a keybind to call the provided function
+ ///
+ /// Name of the keybind
+ /// Hotkey in string format, per example: ALT+CTRL+SHIFT+D
+ /// The key type, either key up or key down
+ /// LUA function to call
+ /// Optional arguments for the passed function
+ public void SetKeybind(string name, string hotKey, PressType pressType, DynValue function, params DynValue[] args)
+ {
+ if (pressType != PressType.Down && pressType != PressType.Up)
+ throw new ScriptRuntimeException("Key type must either be Down or Up.");
+
+ var modifierKeys = ModifierKeys.None;
+ var key = Key.System;
+ var hotKeyParts = hotKey.Split('+').Select(p => p.Trim());
+ foreach (var hotKeyPart in hotKeyParts)
+ if (hotKeyPart == "ALT")
+ modifierKeys |= ModifierKeys.Alt;
+ else if (hotKeyPart == "CTRL")
+ modifierKeys |= ModifierKeys.Control;
+ else if (hotKeyPart == "SHIFT")
+ modifierKeys |= ModifierKeys.Shift;
+ else
+ Enum.TryParse(hotKeyPart, true, out key);
+
+ if (key == Key.System)
+ throw new ScriptRuntimeException($"Hotkey '{hotKey}' couldn't be parsed.");
+
+ var hk = new HotKey(key, modifierKeys);
+ var model = args != null
+ ? new KeybindModel("LUA-" + name, hk, pressType, () => LuaManager.Call(function, args))
+ : new KeybindModel("LUA-" + name, hk, pressType, () => LuaManager.Call(function));
+
+ KeybindManager.AddOrUpdate(model);
+
+ var existing = _keybindModels.FirstOrDefault(k => k.Name == model.Name);
+ if (existing != null)
+ _keybindModels.Remove(existing);
+
+ _keybindModels.Add(model);
+ }
+
+ ///
+ /// If found, removes a keybind with the given name
+ ///
+ ///
+ public void RemoveKeybind(string name)
+ {
+ var existing = _keybindModels.FirstOrDefault(k => k.Name == name);
+ if (existing != null)
+ _keybindModels.Remove(existing);
+
+ KeybindManager.Remove(name);
+ }
+
+ public override void Dispose()
+ {
+ foreach (var keybindModel in _keybindModels)
+ KeybindManager.Remove(keybindModel);
+
+ LuaManager.ProfileModel.OnProfileUpdatedEvent -= ProfileModelOnOnProfileUpdatedEvent;
+ }
+ }
+}
diff --git a/Artemis/Artemis/Profiles/Lua/Wrappers/LuaDrawWrapper.cs b/Artemis/Artemis/Profiles/Lua/Wrappers/LuaDrawWrapper.cs
index c66b33234..32a034d95 100644
--- a/Artemis/Artemis/Profiles/Lua/Wrappers/LuaDrawWrapper.cs
+++ b/Artemis/Artemis/Profiles/Lua/Wrappers/LuaDrawWrapper.cs
@@ -22,7 +22,7 @@ namespace Artemis.Profiles.Lua.Wrappers
public LuaDrawWrapper(DrawingContext ctx, string updateType)
{
_ctx = ctx;
- _scale = updateType == "keyboard" ? 4 : 2;
+ _scale = updateType == "keyboard" || updateType == "preview" ? 4 : 2;
}
public void DrawEllipse(LuaBrush luaBrush, double x, double y, double height, double width)
diff --git a/Artemis/Artemis/Profiles/ProfileModel.cs b/Artemis/Artemis/Profiles/ProfileModel.cs
index 610e44749..f54714c0f 100644
--- a/Artemis/Artemis/Profiles/ProfileModel.cs
+++ b/Artemis/Artemis/Profiles/ProfileModel.cs
@@ -1,243 +1,274 @@
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.IO;
-using System.Linq;
-using System.Windows;
-using System.Windows.Media;
-using Artemis.DeviceProviders;
-using Artemis.Events;
-using Artemis.Managers;
-using Artemis.Models;
-using Artemis.Modules.Abstract;
-using Artemis.Profiles.Layers.Interfaces;
-using Artemis.Profiles.Layers.Models;
-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
- {
- private readonly char[] _invalidFileNameChars;
-
- public ProfileModel()
- {
- _invalidFileNameChars = Path.GetInvalidFileNameChars();
- Layers = new ChildItemCollection(this);
- }
-
- public ChildItemCollection Layers { get; }
- public string Name { get; set; }
- public bool IsDefault { get; set; }
- public string KeyboardSlug { get; set; }
- public string GameName { get; set; }
- public int Width { get; set; }
- public int Height { get; set; }
- public string LuaScript { get; set; }
-
- [JsonIgnore]
- public string Slug => new string(Name.Where(ch => !_invalidFileNameChars.Contains(ch)).ToArray());
-
- public event EventHandler OnDeviceUpdatedEvent;
- public event EventHandler OnDeviceDrawnEvent;
-
- public void FixOrder()
- {
- Layers.Sort(l => l.Order);
- for (var i = 0; i < Layers.Count; i++)
- Layers[i].Order = i;
- }
-
- ///
- /// Gives all the layers and their children in a flat list
- ///
- public List GetLayers()
- {
- var layers = new List();
- foreach (var layerModel in Layers.OrderBy(l => l.Order))
- {
- 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
- ///
- /// Instance of said game data model
- /// Whether or not to ignore anything but keyboards
- ///
- /// A flat list containing all layers that must be rendered
- public List GetRenderLayers(ModuleDataModel dataModel, bool keyboardOnly,
- bool ignoreConditions = false)
- {
- var layers = new List();
- foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
- {
- if (!layerModel.Enabled || keyboardOnly && layerModel.LayerType.DrawType != DrawType.Keyboard)
- continue;
-
- if (!ignoreConditions)
- if (!layerModel.ConditionsMet(dataModel))
- continue;
-
- layers.Add(layerModel);
- layers.AddRange(layerModel.GetRenderLayers(dataModel, keyboardOnly, ignoreConditions));
- }
-
- return layers;
- }
-
- ///
- /// Draw all the given layers on the given rect
- ///
- ///
- /// The layers to render
- /// The data model to base the layer's properties on
- /// Indicates wheter the layer is drawn as a preview, ignoring dynamic properties
- internal void DrawLayers(DeviceVisualModel deviceVisualModel, List renderLayers,
- ModuleDataModel dataModel, bool preview)
- {
- renderLayers = renderLayers.Where(rl => rl.LayerType.DrawType == deviceVisualModel.DrawType).ToList();
- if (!renderLayers.Any())
- return;
-
- // Setup the DrawingVisual's size
- var c = deviceVisualModel.GetDrawingContext();
-
- c.PushClip(new RectangleGeometry(deviceVisualModel.Rect));
- c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, deviceVisualModel.Rect);
-
- // Update the layers
- foreach (var layerModel in renderLayers)
- layerModel.Update(dataModel, preview, true);
- RaiseDeviceUpdatedEvent(new ProfileDeviceEventsArg(deviceVisualModel.DrawType, dataModel, preview, null));
-
- // Draw the layers
- foreach (var layerModel in renderLayers)
- layerModel.Draw(dataModel, c, preview, true);
- RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(deviceVisualModel.DrawType, dataModel, preview, c));
-
- // Remove the clip
- c.Pop();
- }
-
- private void RaiseDeviceUpdatedEvent(ProfileDeviceEventsArg e)
- {
- var handler = OnDeviceUpdatedEvent;
- handler?.Invoke(this, e);
- }
-
- public void RaiseDeviceDrawnEvent(ProfileDeviceEventsArg e)
- {
- var handler = OnDeviceDrawnEvent;
- handler?.Invoke(this, e);
- }
-
- ///
- /// 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.ShowInEdtor)
- continue;
-
- var props = 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;
- }
- }
-
- ///
- /// Resizes layers that are shown in the editor and match exactly the full keyboard widht and height
- ///
- /// The new keyboard to adjust the layers for
- public void ResizeLayers(KeyboardProvider target)
- {
- foreach (var layer in GetLayers())
- {
- if (!layer.LayerType.ShowInEdtor ||
- !(Math.Abs(layer.Properties.Width - Width) < 0.01) ||
- !(Math.Abs(layer.Properties.Height - Height) < 0.01))
- continue;
-
- layer.Properties.Width = target.Width;
- layer.Properties.Height = target.Height;
- }
- }
-
- public void Activate(LuaManager luaManager)
- {
- luaManager.SetupLua(this);
- }
-
- public void Deactivate(LuaManager luaManager)
- {
- luaManager.ClearLua();
- }
-
- public LayerModel AddLayer(LayerModel afterLayer)
- {
- // Create a new layer
- var layer = LayerModel.CreateLayer();
-
- if (afterLayer != null)
- {
- afterLayer.InsertAfter(layer);
- }
- else
- {
- Layers.Add(layer);
- FixOrder();
- }
-
- return layer;
- }
-
- #region Compare
-
- protected bool Equals(ProfileModel other)
- {
- return string.Equals(Slug, other.Slug) &&
- 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 = Slug?.GetHashCode() ?? 0;
- hashCode = (hashCode * 397) ^ (KeyboardSlug?.GetHashCode() ?? 0);
- hashCode = (hashCode * 397) ^ (GameName?.GetHashCode() ?? 0);
- return hashCode;
- }
- }
-
- #endregion
- }
-}
\ No newline at end of file
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Windows;
+using System.Windows.Media;
+using Artemis.DeviceProviders;
+using Artemis.Events;
+using Artemis.Managers;
+using Artemis.Models;
+using Artemis.Modules.Abstract;
+using Artemis.Profiles.Layers.Interfaces;
+using Artemis.Profiles.Layers.Models;
+using Artemis.Utilities.ParentChild;
+using Newtonsoft.Json;
+
+namespace Artemis.Profiles
+{
+ public class ProfileModel
+ {
+ private readonly char[] _invalidFileNameChars;
+ private List _profileBinds;
+
+ public ProfileModel()
+ {
+ _invalidFileNameChars = Path.GetInvalidFileNameChars();
+ _profileBinds = new List();
+
+ Layers = new ChildItemCollection(this);
+ OnProfileUpdatedEvent += OnOnProfileUpdatedEvent;
+ }
+
+ public ChildItemCollection Layers { get; }
+ public string Name { get; set; }
+ public bool IsDefault { get; set; }
+ public string KeyboardSlug { get; set; }
+ public string GameName { get; set; }
+ public int Width { get; set; }
+ public int Height { get; set; }
+ public string LuaScript { get; set; }
+
+ [JsonIgnore]
+ public string Slug => new string(Name.Where(ch => !_invalidFileNameChars.Contains(ch)).ToArray());
+
+ private void OnOnProfileUpdatedEvent(object sender, EventArgs e)
+ {
+ ClearKeybinds();
+ ApplyKeybinds();
+ }
+
+ public event EventHandler OnDeviceUpdatedEvent;
+ public event EventHandler OnDeviceDrawnEvent;
+ public event EventHandler OnProfileUpdatedEvent;
+
+ public void FixOrder()
+ {
+ Layers.Sort(l => l.Order);
+ for (var i = 0; i < Layers.Count; i++)
+ Layers[i].Order = i;
+ }
+
+ ///
+ /// Gives all the layers and their children in a flat list
+ ///
+ public List GetLayers()
+ {
+ var layers = new List();
+ foreach (var layerModel in Layers.OrderBy(l => l.Order))
+ {
+ layers.Add(layerModel);
+ layers.AddRange(layerModel.GetLayers());
+ }
+
+ return layers;
+ }
+
+ // TODO: Make this and LayerModel's GetRenderLayers the same through inheritance
+ ///
+ /// 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
+ ///
+ /// Instance of said game data model
+ /// Whether or not to ignore anything but keyboards
+ ///
+ /// A flat list containing all layers that must be rendered
+ public List GetRenderLayers(ModuleDataModel dataModel, bool keyboardOnly, bool ignoreConditions = false)
+ {
+ var layers = new List();
+ foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
+ {
+ if (!layerModel.Enabled || keyboardOnly && layerModel.LayerType.DrawType != DrawType.Keyboard)
+ continue;
+
+ if (!ignoreConditions)
+ {
+ if (!layerModel.AreConditionsMet(dataModel) || !layerModel.RenderAllowed)
+ continue;
+ }
+
+ layers.Add(layerModel);
+ layers.AddRange(layerModel.GetRenderLayers(dataModel, keyboardOnly, ignoreConditions));
+ }
+
+ return layers;
+ }
+
+ ///
+ /// Draw all the given layers on the given rect
+ ///
+ ///
+ /// The layers to render
+ /// The data model to base the layer's properties on
+ /// Indicates wheter the layer is drawn as a preview, ignoring dynamic properties
+ internal void DrawLayers(DeviceVisualModel deviceVisualModel, List renderLayers, ModuleDataModel dataModel, bool preview)
+ {
+ renderLayers = renderLayers.Where(rl => rl.LayerType.DrawType == deviceVisualModel.DrawType).ToList();
+ if (!renderLayers.Any())
+ return;
+
+ // Setup the DrawingVisual's size
+ var c = deviceVisualModel.GetDrawingContext();
+
+ c.PushClip(new RectangleGeometry(deviceVisualModel.Rect));
+ c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, deviceVisualModel.Rect);
+
+ // Update the layers
+ foreach (var layerModel in renderLayers)
+ layerModel.Update(dataModel, preview, true);
+ RaiseDeviceUpdatedEvent(new ProfileDeviceEventsArg(deviceVisualModel.DrawType, dataModel, preview, null));
+
+ // Draw the layers
+ foreach (var layerModel in renderLayers)
+ layerModel.Draw(dataModel, c, preview, true);
+ RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(deviceVisualModel.DrawType, dataModel, preview, c));
+
+ // Remove the clip
+ c.Pop();
+ }
+
+ private void RaiseDeviceUpdatedEvent(ProfileDeviceEventsArg e)
+ {
+ OnDeviceUpdatedEvent?.Invoke(this, e);
+ }
+
+ public void RaiseDeviceDrawnEvent(ProfileDeviceEventsArg e)
+ {
+ OnDeviceDrawnEvent?.Invoke(this, e);
+ }
+
+ public virtual void OnOnProfileUpdatedEvent()
+ {
+ OnProfileUpdatedEvent?.Invoke(this, EventArgs.Empty);
+ }
+
+ ///
+ /// 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.ShowInEdtor)
+ continue;
+
+ var props = 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;
+ }
+ }
+
+ ///
+ /// Resizes layers that are shown in the editor and match exactly the full keyboard widht and height
+ ///
+ /// The new keyboard to adjust the layers for
+ public void ResizeLayers(KeyboardProvider target)
+ {
+ foreach (var layer in GetLayers())
+ {
+ if (!layer.LayerType.ShowInEdtor ||
+ !(Math.Abs(layer.Properties.Width - Width) < 0.01) ||
+ !(Math.Abs(layer.Properties.Height - Height) < 0.01))
+ continue;
+
+ layer.Properties.Width = target.Width;
+ layer.Properties.Height = target.Height;
+ }
+ }
+
+ public void Activate(LuaManager luaManager)
+ {
+ ApplyKeybinds();
+ luaManager.SetupLua(this);
+ }
+
+ public void Deactivate(LuaManager luaManager)
+ {
+ ClearKeybinds();
+ luaManager.ClearLua();
+ }
+
+ public LayerModel AddLayer(LayerModel afterLayer)
+ {
+ // Create a new layer
+ var layer = LayerModel.CreateLayer();
+
+ if (afterLayer != null)
+ afterLayer.InsertAfter(layer);
+ else
+ {
+ Layers.Add(layer);
+ FixOrder();
+ }
+
+ return layer;
+ }
+
+ public void ApplyKeybinds()
+ {
+ foreach (var layerModel in GetLayers())
+ layerModel.SetupKeybinds();
+ }
+
+ public void ClearKeybinds()
+ {
+ foreach (var layerModel in GetLayers())
+ layerModel.RemoveKeybinds();
+ }
+
+ ///
+ public override string ToString()
+ {
+ return $"{nameof(Name)}: {Name}, {nameof(KeyboardSlug)}: {KeyboardSlug}, {nameof(GameName)}: {GameName}";
+ }
+
+ #region Compare
+
+ protected bool Equals(ProfileModel other)
+ {
+ return string.Equals(Slug, other.Slug) &&
+ 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 = Slug?.GetHashCode() ?? 0;
+ hashCode = (hashCode * 397) ^ (KeyboardSlug?.GetHashCode() ?? 0);
+ hashCode = (hashCode * 397) ^ (GameName?.GetHashCode() ?? 0);
+ return hashCode;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Artemis/Artemis/Properties/AssemblyInfo.cs b/Artemis/Artemis/Properties/AssemblyInfo.cs
index fd3331164..44b0032cb 100644
--- a/Artemis/Artemis/Properties/AssemblyInfo.cs
+++ b/Artemis/Artemis/Properties/AssemblyInfo.cs
@@ -12,7 +12,7 @@ using System.Windows;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("SpoinkyNL")]
[assembly: AssemblyProduct("Artemis")]
-[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -53,7 +53,7 @@ using System.Windows;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.8.1.0")]
-[assembly: AssemblyFileVersion("1.8.1.0")]
+[assembly: AssemblyVersion("1.9.0.0")]
+[assembly: AssemblyFileVersion("1.9.0.0")]
[assembly: InternalsVisibleTo("Artemis.Explorables")]
diff --git a/Artemis/Artemis/Properties/Resources.Designer.cs b/Artemis/Artemis/Properties/Resources.Designer.cs
index a77b26a2d..2ae2a31ad 100644
--- a/Artemis/Artemis/Properties/Resources.Designer.cs
+++ b/Artemis/Artemis/Properties/Resources.Designer.cs
@@ -22,7 +22,7 @@ namespace Artemis.Properties {
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- public class Resources {
+ internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
@@ -278,6 +278,16 @@ namespace Artemis.Properties {
}
}
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap k95_platinum {
+ get {
+ object obj = ResourceManager.GetObject("k95_platinum", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
diff --git a/Artemis/Artemis/Properties/Resources.resx b/Artemis/Artemis/Properties/Resources.resx
index fe9b237c2..fa4d5de48 100644
--- a/Artemis/Artemis/Properties/Resources.resx
+++ b/Artemis/Artemis/Properties/Resources.resx
@@ -220,4 +220,7 @@
..\Resources\Keyboards\masterkeys-pro-s.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Resources\Keyboards\k95-platinum.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Resources/CounterStrike/csgoGamestateConfiguration.txt b/Artemis/Artemis/Resources/CounterStrike/csgoGamestateConfiguration.txt
index 6263805ee..1ddb49d11 100644
--- a/Artemis/Artemis/Resources/CounterStrike/csgoGamestateConfiguration.txt
+++ b/Artemis/Artemis/Resources/CounterStrike/csgoGamestateConfiguration.txt
@@ -2,6 +2,7 @@
{
"uri" "http://localhost:{{port}}/csgo_game_event"
"timeout" "0.1"
+ "heartbeat" "0.1"
"data"
{
"provider" "1"
diff --git a/Artemis/Artemis/Resources/Keyboards/default-profiles.zip b/Artemis/Artemis/Resources/Keyboards/default-profiles.zip
index 6e056031f..298df243e 100644
Binary files a/Artemis/Artemis/Resources/Keyboards/default-profiles.zip and b/Artemis/Artemis/Resources/Keyboards/default-profiles.zip differ
diff --git a/Artemis/Artemis/Resources/Keyboards/k95-platinum.png b/Artemis/Artemis/Resources/Keyboards/k95-platinum.png
new file mode 100644
index 000000000..8c430db2b
Binary files /dev/null and b/Artemis/Artemis/Resources/Keyboards/k95-platinum.png differ
diff --git a/Artemis/Artemis/Services/WindowService.cs b/Artemis/Artemis/Services/WindowService.cs
index f9041df73..4b419a1f7 100644
--- a/Artemis/Artemis/Services/WindowService.cs
+++ b/Artemis/Artemis/Services/WindowService.cs
@@ -1,4 +1,5 @@
-using Caliburn.Micro;
+using System.Dynamic;
+using Caliburn.Micro;
using Ninject;
using Ninject.Parameters;
@@ -13,21 +14,25 @@ namespace Artemis.Services
_kernel = kernel;
}
- public T ShowWindow(params IParameter[] param) where T : class
+ public T ShowWindow(string windowName, params IParameter[] param) where T : class
{
var windowManager = new WindowManager();
- var viewModel = _kernel.Get(param);
-
- windowManager.ShowWindow(viewModel);
+ var viewModel = _kernel.Get(param);
+
+ dynamic settings = new ExpandoObject();
+ settings.Title = windowName;
+ windowManager.ShowWindow(viewModel, null, settings);
return viewModel;
}
- public T ShowDialog(params IParameter[] param) where T : class
+ public T ShowDialog(string dialogName, params IParameter[] param) where T : class
{
var windowManager = new WindowManager();
var viewModel = _kernel.Get(param);
- windowManager.ShowDialog(viewModel);
+ dynamic settings = new ExpandoObject();
+ settings.Title = dialogName;
+ windowManager.ShowDialog(viewModel, null, settings);
return viewModel;
}
}
diff --git a/Artemis/Artemis/Settings/GeneralSettings.cs b/Artemis/Artemis/Settings/GeneralSettings.cs
index f56dbf807..b304c114d 100644
--- a/Artemis/Artemis/Settings/GeneralSettings.cs
+++ b/Artemis/Artemis/Settings/GeneralSettings.cs
@@ -73,11 +73,12 @@ namespace Artemis.Settings
public void Save()
{
SettingsProvider.Save(this);
+
+ Logging.SetupLogging(LogLevel);
ApplyAutorun();
ApplyTheme();
ApplyGamestatePort();
ApplyScreenCaptureFPS();
- Logging.SetupLogging(LogLevel);
}
public void Reset(bool save = false)
diff --git a/Artemis/Artemis/Utilities/DataReaders/DllManager.cs b/Artemis/Artemis/Utilities/DataReaders/DllManager.cs
index e803449c6..e1f1802a9 100644
--- a/Artemis/Artemis/Utilities/DataReaders/DllManager.cs
+++ b/Artemis/Artemis/Utilities/DataReaders/DllManager.cs
@@ -29,87 +29,36 @@ namespace Artemis.Utilities.DataReaders
#region Logitech
- private const string LogitechPath = @"C:\Program Files\Logitech Gaming Software\SDK\LED\x64\";
-
- public static bool RestoreLogitechDll()
- {
- if (!DllPlaced())
- return false;
-
- try
- {
- // Get rid of our own DLL
- File.Delete(LogitechPath + @"\LogitechLed.dll");
-
- // Restore the backup
- if (File.Exists(LogitechPath + @"\LogitechLed.dll.bak"))
- File.Copy(LogitechPath + @"\LogitechLed.dll.bak", LogitechPath + @"\LogitechLed.dll");
-
- File.Delete(LogitechPath + @"\artemis.txt");
-
- return true;
- }
- catch (Exception)
- {
- return false;
- }
- }
+ private static readonly string LogitechPath = @"C:\Program Files\Logitech Gaming Software\SDK\LED\x64\";
+ private static readonly string DllPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Artemis\dll";
public static void PlaceLogitechDll()
{
- if (DllPlaced())
- return;
-
- // Create directory structure, just in case
- Directory.CreateDirectory(LogitechPath + @"");
-
- // Backup the existing DLL
- if (File.Exists(LogitechPath + @"\LogitechLed.dll"))
+ try
{
- if (File.Exists(LogitechPath + @"\LogitechLed.dll.bak"))
- File.Delete(LogitechPath + @"\LogitechLed.dll.bak");
- File.Move(LogitechPath + @"\LogitechLed.dll", LogitechPath + @"\LogitechLed.dll.bak");
+ // Change the registry key to point to the fake DLL
+ var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary", true);
+ key?.SetValue(null, DllPath + @"\LogitechLed.dll");
+
+ // Make sure the fake DLL is in place
+ if (!Directory.Exists(DllPath))
+ Directory.CreateDirectory(DllPath);
+ if (!File.Exists(DllPath + @"\LogitechLed.dll"))
+ File.WriteAllBytes(DllPath + @"\LogitechLED.dll", Resources.LogitechLED);
+ }
+ catch (Exception e)
+ {
+ Logger.Error(e, "Failed to place Logitech DLL");
}
-
- // Copy our own DLL in place
- File.WriteAllBytes(LogitechPath + @"\LogitechLED.dll",
- Resources.LogitechLED);
-
- // A token to show the file is placed
- File.Create(LogitechPath + @"\artemis.txt");
-
- // If the user doesn't have a Logitech device, the CLSID will be missing
- // and we should create it ourselves.
- if (!RegistryKeyPlaced())
- PlaceRegistryKey();
}
- public static bool DllPlaced()
+ public static void RestoreLogitechDll()
{
- if (!Directory.Exists(LogitechPath + @""))
- return false;
- if (!RegistryKeyPlaced())
- return false;
-
- return File.Exists(LogitechPath + @"\artemis.txt");
- }
-
- private static bool RegistryKeyPlaced()
- {
- var key = Registry
- .LocalMachine.OpenSubKey(
- @"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary");
- return key != null;
- }
-
- private static void PlaceRegistryKey()
- {
- var key = Registry
- .LocalMachine.OpenSubKey(
- @"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary", true);
+ // Change the registry key to point to the real DLL
+ var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary", true);
key?.SetValue(null, LogitechPath + @"\LogitechLed.dll");
}
#endregion
}
-}
\ No newline at end of file
+}
diff --git a/Artemis/Artemis/Utilities/EditorHelper.cs b/Artemis/Artemis/Utilities/EditorHelper.cs
deleted file mode 100644
index ba7ab2eb1..000000000
--- a/Artemis/Artemis/Utilities/EditorHelper.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Artemis.Utilities
-{
- public static class EditorHelper
- {
- }
-}
diff --git a/Artemis/Artemis/Utilities/GeneralHelpers.cs b/Artemis/Artemis/Utilities/GeneralHelpers.cs
index bc2b49cd6..afc5be9d5 100644
--- a/Artemis/Artemis/Utilities/GeneralHelpers.cs
+++ b/Artemis/Artemis/Utilities/GeneralHelpers.cs
@@ -4,6 +4,8 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
+using System.Threading;
+using System.Windows;
using Microsoft.Win32;
using Newtonsoft.Json;
using static System.String;
@@ -126,5 +128,13 @@ namespace Artemis.Utilities
public List Children { get; set; }
public string DisplayType { get; set; }
}
+
+ public static void ExecuteSta(Action action)
+ {
+ var thread = new Thread(action.Invoke);
+ thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
+ thread.Start();
+ thread.Join();
+ }
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Utilities/GifImage.cs b/Artemis/Artemis/Utilities/GifImage.cs
index 085e51165..738c9c183 100644
--- a/Artemis/Artemis/Utilities/GifImage.cs
+++ b/Artemis/Artemis/Utilities/GifImage.cs
@@ -6,23 +6,22 @@ namespace Artemis.Utilities
{
public class GifImage
{
- private readonly int _delay;
private readonly FrameDimension _dimension;
private readonly Image _gifImage;
+ private readonly PropertyItem _gifProperties;
private DateTime _lastRequest;
private int _step = 1;
- public GifImage(string path)
+ public GifImage(string path, double animationSpeed)
{
_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
+ _gifProperties = _gifImage.GetPropertyItem(0x5100); // FrameDelay in libgdiplus
Source = path;
-
- var item = _gifImage.GetPropertyItem(0x5100); // FrameDelay in libgdiplus
- _delay = (item.Value[0] + item.Value[1]*256)*10; // Time is in 1/100th of a second
+ AnimationSpeed = animationSpeed;
+ FrameCount = _gifImage.GetFrameCount(_dimension); //total frames in the animation
}
///
@@ -30,6 +29,8 @@ namespace Artemis.Utilities
///
public string Source { get; private set; }
+ public double AnimationSpeed { get; set; }
+
///
/// Gets or sets the current frame, set to -1 to reset
///
@@ -47,8 +48,16 @@ namespace Artemis.Utilities
public Image GetNextFrame()
{
+ var animationSpeed = 2 - AnimationSpeed/3 * 2;
+ var fileDelay = (_gifProperties.Value[0] + _gifProperties.Value[1] * 256) * 10;
+ // If the file is missing this metadata such as in #319 then default to 100
+ if (fileDelay == 0)
+ fileDelay = 100;
+ // Apply the animation speed to the delay
+ var delay = fileDelay * animationSpeed;
+
// Only pass the next frame if the proper amount of time has passed
- if ((DateTime.Now - _lastRequest).Milliseconds > _delay)
+ if ((DateTime.Now - _lastRequest).Milliseconds > delay)
{
CurrentFrame += _step;
_lastRequest = DateTime.Now;
@@ -75,4 +84,4 @@ namespace Artemis.Utilities
return _gifImage;
}
}
-}
\ No newline at end of file
+}
diff --git a/Artemis/Artemis/Utilities/ImageUtilities.cs b/Artemis/Artemis/Utilities/ImageUtilities.cs
index 71bc16df9..79a202919 100644
--- a/Artemis/Artemis/Utilities/ImageUtilities.cs
+++ b/Artemis/Artemis/Utilities/ImageUtilities.cs
@@ -54,7 +54,7 @@ namespace Artemis.Utilities
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
-
+
return bitmapImage;
}
}
diff --git a/Artemis/Artemis/Utilities/InputHook.cs b/Artemis/Artemis/Utilities/InputHook.cs
new file mode 100644
index 000000000..b1ba31c3b
--- /dev/null
+++ b/Artemis/Artemis/Utilities/InputHook.cs
@@ -0,0 +1,73 @@
+using System.Diagnostics;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Gma.System.MouseKeyHook;
+using NLog;
+
+namespace Artemis.Utilities
+{
+ public static class InputHook
+ {
+ public delegate void KeyCallbackHandler(KeyEventArgs e);
+
+ public delegate void MouseCallbackHandler(MouseEventArgs e);
+
+ private static IKeyboardMouseEvents _globalHook;
+
+ public static void Start()
+ {
+ _globalHook = Hook.GlobalEvents();
+
+ // When hitting breakpoints all user input freezes for ~10 seconds due to Windows waiting on the hooks to time out.
+ // By simply not hooking when the debugger is attached this no longer happens but keybinds obviously wont work.
+ if (Debugger.IsAttached)
+ {
+ LogManager.GetCurrentClassLogger().Fatal("Debugger attached so not enabling any global hooks, keybinds won't work!");
+ return;
+ }
+
+ _globalHook.KeyDown += GlobalHookOnKeyDown;
+ _globalHook.KeyUp += GlobalHookOnKeyUp;
+ _globalHook.MouseDown += GlobalHookOnMouseDown;
+ _globalHook.MouseUp += GlobalHookOnMouseUp;
+ }
+
+ public static void Stop()
+ {
+ if (_globalHook == null)
+ return;
+
+ _globalHook.KeyDown -= GlobalHookOnKeyDown;
+ _globalHook.KeyUp -= GlobalHookOnKeyUp;
+ _globalHook.MouseDown -= GlobalHookOnMouseDown;
+ _globalHook.MouseUp -= GlobalHookOnMouseUp;
+ _globalHook.Dispose();
+ _globalHook = null;
+ }
+
+ private static async void GlobalHookOnMouseDown(object sender, MouseEventArgs e)
+ {
+ await Task.Factory.StartNew(() => { MouseDownCallback?.Invoke(e); });
+ }
+
+ private static async void GlobalHookOnMouseUp(object sender, MouseEventArgs e)
+ {
+ await Task.Factory.StartNew(() => { MouseUpCallback?.Invoke(e); });
+ }
+
+ private static async void GlobalHookOnKeyDown(object sender, KeyEventArgs e)
+ {
+ await Task.Factory.StartNew(() => { KeyDownCallback?.Invoke(e); });
+ }
+
+ private static async void GlobalHookOnKeyUp(object sender, KeyEventArgs e)
+ {
+ await Task.Factory.StartNew(() => { KeyUpCallback?.Invoke(e); });
+ }
+
+ public static event KeyCallbackHandler KeyDownCallback;
+ public static event KeyCallbackHandler KeyUpCallback;
+ public static event MouseCallbackHandler MouseDownCallback;
+ public static event MouseCallbackHandler MouseUpCallback;
+ }
+}
diff --git a/Artemis/Artemis/Utilities/Keyboard/KeyboardHook.cs b/Artemis/Artemis/Utilities/Keyboard/KeyboardHook.cs
deleted file mode 100644
index 0fabc9f6a..000000000
--- a/Artemis/Artemis/Utilities/Keyboard/KeyboardHook.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System.Threading.Tasks;
-using System.Windows.Forms;
-using Open.WinKeyboardHook;
-
-namespace Artemis.Utilities.Keyboard
-{
- public static class KeyboardHook
- {
- private static KeyboardInterceptor _interceptor;
-
- public delegate void KeyDownCallbackHandler(KeyEventArgs e);
-
- public static void SetupKeyboardHook()
- {
- _interceptor = new KeyboardInterceptor();
- _interceptor.KeyDown += VirtualKeyboardOnKeyDown;
- _interceptor.StartCapturing();
- }
-
- private static async void VirtualKeyboardOnKeyDown(object sender, KeyEventArgs keyEventArgs)
- {
- await Task.Factory.StartNew(() => { KeyDownCallback?.Invoke(keyEventArgs); });
- }
-
- public static event KeyDownCallbackHandler KeyDownCallback;
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs
index fbce0198c..a6169b985 100644
--- a/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Flyouts/FlyoutSettingsViewModel.cs
@@ -1,35 +1,33 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
-using System.Dynamic;
using System.Linq;
using System.Reflection;
using Artemis.DAL;
using Artemis.Events;
using Artemis.Managers;
+using Artemis.Services;
using Artemis.Settings;
-using Artemis.Utilities;
using Caliburn.Micro;
using MahApps.Metro.Controls;
using NLog;
using ILogger = Ninject.Extensions.Logging.ILogger;
-using Process = System.Diagnostics.Process;
namespace Artemis.ViewModels.Flyouts
{
public sealed class FlyoutSettingsViewModel : FlyoutBaseViewModel
{
- private readonly DebugViewModel _debugViewModel;
private readonly ILogger _logger;
+ private readonly WindowService _windowService;
private string _activeEffectName;
private bool _enableDebug;
private GeneralSettings _generalSettings;
private string _selectedKeyboardProvider;
- public FlyoutSettingsViewModel(MainManager mainManager, ILogger logger, DebugViewModel debugViewModel)
+ public FlyoutSettingsViewModel(MainManager mainManager, ILogger logger, WindowService windowService)
{
_logger = logger;
- _debugViewModel = debugViewModel;
+ _windowService = windowService;
MainManager = mainManager;
Header = "Settings";
@@ -196,7 +194,9 @@ namespace Artemis.ViewModels.Flyouts
MainManager.LoopManager.StartAsync();
}
else
+ {
MainManager.DeviceManager.ReleaseActiveKeyboard(true);
+ }
}
public void ToggleEnabled()
@@ -215,14 +215,7 @@ namespace Artemis.ViewModels.Flyouts
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);
+ _windowService.ShowWindow("Artemis | Debugger");
}
public void ResetSettings()
@@ -248,4 +241,4 @@ namespace Artemis.ViewModels.Flyouts
: GeneralSettings.LastKeyboard;
}
}
-}
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/GeneralViewModel.cs b/Artemis/Artemis/ViewModels/GeneralViewModel.cs
index c32531bf1..b19fe1aa6 100644
--- a/Artemis/Artemis/ViewModels/GeneralViewModel.cs
+++ b/Artemis/Artemis/ViewModels/GeneralViewModel.cs
@@ -14,7 +14,8 @@ namespace Artemis.ViewModels
{
DisplayName = "General";
_vms = moduleViewModels.Where(m => !m.ModuleModel.IsOverlay && !m.ModuleModel.IsBoundToProcess)
- .OrderBy(m => m.DisplayName).ToList();
+ .OrderByDescending(m => m.DisplayName == "General profile")
+ .ThenBy(m => m.DisplayName).ToList();
previewManager.PreviewViewModules.Clear();
previewManager.PreviewViewModules.AddRange(moduleViewModels.Where(m => m.UsesProfileEditor));
diff --git a/Artemis/Artemis/ViewModels/LayerEditorViewModel.cs b/Artemis/Artemis/ViewModels/LayerEditorViewModel.cs
index 8d89ea92b..e4091b62e 100644
--- a/Artemis/Artemis/ViewModels/LayerEditorViewModel.cs
+++ b/Artemis/Artemis/ViewModels/LayerEditorViewModel.cs
@@ -44,7 +44,9 @@ namespace Artemis.ViewModels
// Setup existing conditions
var conditions = ProposedLayer.Properties.Conditions.Select(c => new LayerConditionViewModel(this, c));
+ var keyBinds = ProposedLayer.Properties.LayerKeybindModels.Select(c => new LayerKeybindViewModel(this, c));
LayerConditionVms = new BindableCollection(conditions);
+ LayerKeybindVms = new BindableCollection(keyBinds);
PropertyChanged += PropertiesViewModelHandler;
@@ -60,6 +62,7 @@ namespace Artemis.ViewModels
public BindableCollection LayerTypes { get; set; }
public BindableCollection DataModelProps { get; set; }
public BindableCollection LayerConditionVms { get; set; }
+ public BindableCollection LayerKeybindVms { get; set; }
public bool KeyboardGridIsVisible => ProposedLayer.LayerType is KeyboardType;
public bool GifGridIsVisible => ProposedLayer.LayerType is KeyboardGifType;
@@ -68,7 +71,8 @@ namespace Artemis.ViewModels
get { return _layer; }
set
{
- if (Equals(value, _layer)) return;
+ if (Equals(value, _layer))
+ return;
_layer = value;
NotifyOfPropertyChange(() => Layer);
}
@@ -81,7 +85,8 @@ namespace Artemis.ViewModels
get { return _proposedLayer; }
set
{
- if (Equals(value, _proposedLayer)) return;
+ if (Equals(value, _proposedLayer))
+ return;
_proposedLayer = value;
NotifyOfPropertyChange(() => ProposedLayer);
}
@@ -92,7 +97,8 @@ namespace Artemis.ViewModels
get { return _layerPropertiesViewModel; }
set
{
- if (Equals(value, _layerPropertiesViewModel)) return;
+ if (Equals(value, _layerPropertiesViewModel))
+ return;
_layerPropertiesViewModel = value;
NotifyOfPropertyChange(() => LayerPropertiesViewModel);
}
@@ -103,7 +109,8 @@ namespace Artemis.ViewModels
get { return _eventPropertiesViewModel; }
set
{
- if (Equals(value, _eventPropertiesViewModel)) return;
+ if (Equals(value, _eventPropertiesViewModel))
+ return;
_eventPropertiesViewModel = value;
NotifyOfPropertyChange(() => EventPropertiesViewModel);
}
@@ -114,7 +121,8 @@ namespace Artemis.ViewModels
get { return _selectedLayerType; }
set
{
- if (Equals(value, _selectedLayerType)) return;
+ if (Equals(value, _selectedLayerType))
+ return;
_selectedLayerType = value;
NotifyOfPropertyChange(() => SelectedLayerType);
}
@@ -167,15 +175,27 @@ namespace Artemis.ViewModels
LayerConditionVms.Add(new LayerConditionViewModel(this, condition));
}
+ public void AddKeybind()
+ {
+ var keybind = new LayerKeybindModel();
+ LayerKeybindVms.Add(new LayerKeybindViewModel(this, keybind));
+ }
+
public void Apply()
{
LayerPropertiesViewModel?.ApplyProperties();
Layer.Properties.DynamicProperties.Clear();
JsonConvert.PopulateObject(JsonConvert.SerializeObject(ProposedLayer), Layer);
+
Layer.Properties.Conditions.Clear();
foreach (var conditionViewModel in LayerConditionVms)
- Layer.Properties.Conditions.Add(conditionViewModel.ConditionModel);
+ Layer.Properties.Conditions.Add(conditionViewModel.ConditionModel);
+
+ Layer.Properties.LayerKeybindModels.Clear();
+ foreach (var layerKeybindViewModel in LayerKeybindVms)
+ Layer.Properties.LayerKeybindModels.Add(layerKeybindViewModel.LayerKeybindModel);
+
// TODO: EventPropVM must have layer too
if (EventPropertiesViewModel != null)
@@ -190,13 +210,6 @@ namespace Artemis.ViewModels
DialogService.ShowErrorMessageBox("Couldn't find or access the provided GIF file.");
}
- public void DeleteCondition(LayerConditionViewModel layerConditionViewModel,
- LayerConditionModel layerConditionModel)
- {
- LayerConditionVms.Remove(layerConditionViewModel);
- Layer.Properties.Conditions.Remove(layerConditionModel);
- }
-
public override async void CanClose(Action callback)
{
// Create a fake layer and apply the properties to it
@@ -204,9 +217,17 @@ namespace Artemis.ViewModels
// TODO: EventPropVM must have layer too
if (EventPropertiesViewModel != null)
ProposedLayer.EventProperties = EventPropertiesViewModel.GetAppliedProperties();
+
ProposedLayer.Properties.Conditions.Clear();
foreach (var conditionViewModel in LayerConditionVms)
- ProposedLayer.Properties.Conditions.Add(conditionViewModel.ConditionModel);
+ ProposedLayer.Properties.Conditions.Add(conditionViewModel.ConditionModel);
+
+ ProposedLayer.Properties.LayerKeybindModels.Clear();
+ foreach (var layerKeybindViewModel in LayerKeybindVms)
+ ProposedLayer.Properties.LayerKeybindModels.Add(layerKeybindViewModel.LayerKeybindModel);
+
+ // Ignore this property as it isn't user input
+ ProposedLayer.RenderAllowed = Layer.RenderAllowed;
// If not a keyboard, ignore size and position
if ((ProposedLayer.LayerType.DrawType != DrawType.Keyboard) || !ProposedLayer.LayerType.ShowInEdtor)
@@ -236,9 +257,8 @@ namespace Artemis.ViewModels
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);
}
}
-}
\ No newline at end of file
+}
diff --git a/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs b/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs
index 5fbb1bfed..3f6ee7588 100644
--- a/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs
+++ b/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
+using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -28,9 +29,12 @@ using Caliburn.Micro;
using Castle.Components.DictionaryAdapter;
using GongSolutions.Wpf.DragDrop;
using MahApps.Metro;
+using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;
+using Newtonsoft.Json;
using NuGet;
using Application = System.Windows.Application;
+using Clipboard = System.Windows.Clipboard;
using Cursor = System.Windows.Input.Cursor;
using Cursors = System.Windows.Input.Cursors;
using DragDropEffects = System.Windows.DragDropEffects;
@@ -46,8 +50,10 @@ namespace Artemis.ViewModels
private readonly MetroDialogService _dialogService;
private readonly LoopManager _loopManager;
private readonly ModuleModel _moduleModel;
+ private readonly KeybindModel _copyKeybind;
private ImageSource _keyboardPreview;
private ObservableCollection _layers;
+ private readonly KeybindModel _pasteKeybind;
private ObservableCollection _profileNames;
private bool _saving;
private LayerModel _selectedLayer;
@@ -60,7 +66,9 @@ namespace Artemis.ViewModels
_loopManager = loopManager;
_moduleModel = moduleModel;
_dialogService = dialogService;
-
+ _copyKeybind = new KeybindModel("copy", new HotKey(Key.C, ModifierKeys.Control), PressType.Down, LayerToClipboard);
+ _pasteKeybind = new KeybindModel("paste", new HotKey(Key.V, ModifierKeys.Control), PressType.Up, ClipboardToLayer);
+ _placeholderKeyboard = KeyboardPreview = ImageUtilities.BitmapToBitmapImage(Resources.none);
ProfileNames = new ObservableCollection();
Layers = new ObservableCollection();
ProfileEditorModel = profileEditorModel;
@@ -69,6 +77,7 @@ namespace Artemis.ViewModels
PropertyChanged += EditorStateHandler;
_deviceManager.OnKeyboardChanged += DeviceManagerOnOnKeyboardChanged;
_moduleModel.ProfileChanged += ModuleModelOnProfileChanged;
+
LoadProfiles();
}
@@ -77,6 +86,8 @@ namespace Artemis.ViewModels
base.OnActivate();
_loopManager.RenderCompleted += LoopManagerOnRenderCompleted;
+ KeybindManager.AddOrUpdate(_copyKeybind);
+ KeybindManager.AddOrUpdate(_pasteKeybind);
}
public new void OnDeactivate(bool close)
@@ -85,6 +96,8 @@ namespace Artemis.ViewModels
SaveSelectedProfile();
_loopManager.RenderCompleted -= LoopManagerOnRenderCompleted;
+ KeybindManager.Remove(_copyKeybind);
+ KeybindManager.Remove(_pasteKeybind);
}
#region LUA
@@ -116,7 +129,8 @@ namespace Artemis.ViewModels
get { return _profileNames; }
set
{
- if (Equals(value, _profileNames)) return;
+ if (Equals(value, _profileNames))
+ return;
_profileNames = value;
NotifyOfPropertyChange(() => ProfileNames);
}
@@ -127,7 +141,8 @@ namespace Artemis.ViewModels
get { return _layers; }
set
{
- if (Equals(value, _layers)) return;
+ if (Equals(value, _layers))
+ return;
_layers = value;
NotifyOfPropertyChange(() => Layers);
}
@@ -139,7 +154,8 @@ namespace Artemis.ViewModels
get { return _keyboardPreview; }
set
{
- if (Equals(value, _keyboardPreview)) return;
+ if (Equals(value, _keyboardPreview))
+ return;
_keyboardPreview = value;
NotifyOfPropertyChange(() => KeyboardPreview);
}
@@ -150,7 +166,8 @@ namespace Artemis.ViewModels
get { return _showAll; }
set
{
- if (value == _showAll) return;
+ if (value == _showAll)
+ return;
_showAll = value;
NotifyOfPropertyChange();
}
@@ -181,20 +198,18 @@ namespace Artemis.ViewModels
NotifyOfPropertyChange(() => LayerSelected);
}
}
-
- public ImageSource KeyboardImage => ImageUtilities.BitmapToBitmapImage(
- _deviceManager.ActiveKeyboard?.PreviewSettings.Image ?? Resources.none);
-
+
public ProfileModel SelectedProfile => _moduleModel?.ProfileModel;
- public PreviewSettings? PreviewSettings => _deviceManager.ActiveKeyboard?.PreviewSettings;
public bool ProfileSelected => SelectedProfile != null;
public bool LayerSelected => SelectedProfile != null && SelectedLayer != null;
-
- public bool EditorEnabled => SelectedProfile != null && !SelectedProfile.IsDefault &&
- _deviceManager.ActiveKeyboard != null;
-
+ public bool EditorEnabled => SelectedProfile != null && !SelectedProfile.IsDefault && _deviceManager.ActiveKeyboard != null;
public bool LuaButtonVisible => !_moduleModel.IsOverlay;
+ ///
+ /// Set to true to keep the preview active if using the profile editor
+ ///
+ public bool KeepActive { get; set; }
+
#endregion
#region Layers
@@ -212,8 +227,10 @@ namespace Artemis.ViewModels
if (SelectedLayer == null)
return;
+ KeepActive = true;
ProfileEditorModel.EditLayer(SelectedLayer, _moduleModel.DataModel);
UpdateLayerList(SelectedLayer);
+ KeepActive = false;
}
public void EditLayer(LayerModel layerModel)
@@ -221,8 +238,10 @@ namespace Artemis.ViewModels
if (layerModel == null)
return;
+ KeepActive = true;
ProfileEditorModel.EditLayer(layerModel, _moduleModel.DataModel);
UpdateLayerList(layerModel);
+ KeepActive = false;
}
public LayerModel AddLayer()
@@ -268,6 +287,7 @@ namespace Artemis.ViewModels
if (layer == null)
return;
+ KeepActive = true;
var newName = await _dialogService.ShowInputDialog("Rename layer", "Please enter a name for the layer",
new MetroDialogSettings {DefaultText = layer.Name});
@@ -277,6 +297,7 @@ namespace Artemis.ViewModels
layer.Name = newName;
UpdateLayerList(layer);
+ KeepActive = false;
}
///
@@ -302,6 +323,43 @@ namespace Artemis.ViewModels
UpdateLayerList(clone);
}
+ public void LayerToClipboard()
+ {
+ if (SelectedLayer == null || !ActiveWindowHelper.MainWindowActive)
+ return;
+
+ // Probably not how the cool kids do it but leveraging on JsonConvert gives flawless serialization
+ GeneralHelpers.ExecuteSta(() => Clipboard.SetData("layer", JsonConvert.SerializeObject(SelectedLayer)));
+ }
+
+ public void ClipboardToLayer()
+ {
+ if (!ActiveWindowHelper.MainWindowActive)
+ return;
+
+ GeneralHelpers.ExecuteSta(() =>
+ {
+ var data = (string) Clipboard.GetData("layer");
+ if (data == null)
+ return;
+
+ var layerModel = JsonConvert.DeserializeObject(data);
+ if (layerModel == null)
+ return;
+
+ if (SelectedLayer != null)
+ {
+ SelectedLayer.InsertAfter(layerModel);
+ }
+ else
+ {
+ SelectedProfile.Layers.Add(layerModel);
+ SelectedProfile.FixOrder();
+ }
+ Execute.OnUIThread(() => UpdateLayerList(layerModel));
+ });
+ }
+
private void UpdateLayerList(LayerModel selectModel)
{
// Update the UI
@@ -319,6 +377,7 @@ namespace Artemis.ViewModels
{
Thread.Sleep(100);
SelectedLayer = selectModel;
+ SelectedProfile?.OnOnProfileUpdatedEvent();
});
}
@@ -447,21 +506,45 @@ namespace Artemis.ViewModels
#region Rendering
+ private readonly ImageSource _placeholderKeyboard;
+
private void LoopManagerOnRenderCompleted(object sender, EventArgs eventArgs)
{
// Besides the usual checks, also check if the ActiveKeyboard isn't the NoneKeyboard
- if (SelectedProfile == null || _deviceManager.ActiveKeyboard == null ||
- _deviceManager.ActiveKeyboard.Slug == "none")
+ if (SelectedProfile == null || _deviceManager.ActiveKeyboard == null || _deviceManager.ActiveKeyboard.Slug == "none")
{
- KeyboardPreview = null;
-
// Setup layers for the next frame
if (_moduleModel.IsInitialized && ActiveWindowHelper.MainWindowActive)
_moduleModel.PreviewLayers = new List();
+ if (!Equals(KeyboardPreview, _placeholderKeyboard))
+ KeyboardPreview = _placeholderKeyboard;
+
return;
}
+ var renderedLayers = RenderLayers();
+ var visual = new DrawingVisual();
+ var previewSettings = _deviceManager.ActiveKeyboard.PreviewSettings;
+ using (var drawingContext = visual.RenderOpen())
+ {
+ var baseRect = new Rect(0, 0, previewSettings.BackgroundRectangle.Width, previewSettings.BackgroundRectangle.Height);
+ drawingContext.PushClip(new RectangleGeometry(baseRect));
+ // Draw the keyboard image
+ drawingContext.DrawImage(previewSettings.Image, baseRect);
+ // Draw the layers semi-transparent
+ drawingContext.PushOpacity(0.8);
+ drawingContext.DrawImage(renderedLayers, previewSettings.OverlayRectangle);
+ drawingContext.Pop();
+ drawingContext.Pop();
+ }
+ var drawnPreview = new DrawingImage(visual.Drawing);
+ drawnPreview.Freeze();
+ KeyboardPreview = drawnPreview;
+ }
+
+ private DrawingImage RenderLayers()
+ {
var renderLayers = GetRenderLayers();
// Draw the current frame to the preview
var keyboardRect = _deviceManager.ActiveKeyboard.KeyboardRectangle();
@@ -487,7 +570,7 @@ namespace Artemis.ViewModels
var preview = new DrawingImage();
preview.Freeze();
KeyboardPreview = preview;
- return;
+ return new DrawingImage();
}
var pen = new Pen(new SolidColorBrush((Color) accentColor), 0.4);
@@ -521,11 +604,12 @@ namespace Artemis.ViewModels
}
var drawnPreview = new DrawingImage(visual.Drawing);
drawnPreview.Freeze();
- KeyboardPreview = drawnPreview;
// Setup layers for the next frame
if (_moduleModel.IsInitialized && ActiveWindowHelper.MainWindowActive)
_moduleModel.PreviewLayers = renderLayers;
+
+ return drawnPreview;
}
public List GetRenderLayers()
@@ -581,13 +665,8 @@ namespace Artemis.ViewModels
if (_draggingLayer != null)
return;
- var keyboard = _deviceManager.ActiveKeyboard;
- var pos = e.GetPosition((Image) e.OriginalSource);
- var x = pos.X / ((double) keyboard.PreviewSettings.Width / keyboard.Width);
- var y = pos.Y / ((double) keyboard.PreviewSettings.Height / keyboard.Height);
-
- var hoverLayer = GetLayers().Where(l => l.MustDraw())
- .FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(x, y));
+ var pos = GetScaledPosition(e);
+ var hoverLayer = GetLayers().Where(l => l.MustDraw()).FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(pos.X, pos.Y));
if (hoverLayer != null)
SelectedLayer = hoverLayer;
@@ -602,14 +681,10 @@ namespace Artemis.ViewModels
if (SelectedProfile == null)
return;
- var pos = e.GetPosition((Image) e.OriginalSource);
- var keyboard = _deviceManager.ActiveKeyboard;
- var x = pos.X / ((double) keyboard.PreviewSettings.Width / keyboard.Width);
- var y = pos.Y / ((double) keyboard.PreviewSettings.Height / keyboard.Height);
- var hoverLayer = GetLayers().Where(l => l.MustDraw())
- .FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(x, y));
+ var pos = GetScaledPosition(e);
+ var hoverLayer = GetLayers().Where(l => l.MustDraw()).FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(pos.X, pos.Y));
- HandleDragging(e, x, y, hoverLayer);
+ HandleDragging(e, pos.X, pos.Y, hoverLayer);
if (hoverLayer == null)
{
@@ -621,10 +696,9 @@ namespace Artemis.ViewModels
if (hoverLayer == SelectedLayer)
{
var rect = hoverLayer.Properties.PropertiesRect(1);
- KeyboardPreviewCursor =
- Math.Sqrt(Math.Pow(x - rect.BottomRight.X, 2) + Math.Pow(y - rect.BottomRight.Y, 2)) < 0.6
- ? Cursors.SizeNWSE
- : Cursors.SizeAll;
+ KeyboardPreviewCursor = Math.Sqrt(Math.Pow(pos.X - rect.BottomRight.X, 2) + Math.Pow(pos.Y - rect.BottomRight.Y, 2)) < 0.6
+ ? Cursors.SizeNWSE
+ : Cursors.SizeAll;
}
else
{
@@ -632,12 +706,33 @@ namespace Artemis.ViewModels
}
}
+ private Point GetScaledPosition(MouseEventArgs e)
+ {
+ var previewSettings = _deviceManager.ActiveKeyboard.PreviewSettings;
+
+ var sourceImage = (Image) e.OriginalSource;
+ var pos = e.GetPosition(sourceImage);
+ var widthScale = sourceImage.ActualWidth / _deviceManager.ActiveKeyboard.PreviewSettings.BackgroundRectangle.Width;
+ var heightScale = sourceImage.ActualHeight / _deviceManager.ActiveKeyboard.PreviewSettings.BackgroundRectangle.Height;
+
+ // Remove the preview settings' offset from the cursor postion
+ pos.X = pos.X - (previewSettings.OverlayRectangle.X * widthScale);
+ pos.Y = pos.Y - (previewSettings.OverlayRectangle.Y * heightScale);
+
+ // Scale the X and Y position down to match the keyboard's physical size and thus the layer positions
+ pos.X = pos.X * (SelectedProfile.Width / (previewSettings.OverlayRectangle.Width*widthScale));
+ pos.Y = pos.Y * (SelectedProfile.Height / (previewSettings.OverlayRectangle.Height * heightScale));
+
+ return pos;
+ }
+
public Cursor KeyboardPreviewCursor
{
get { return _keyboardPreviewCursor; }
set
{
- if (Equals(value, _keyboardPreviewCursor)) return;
+ if (Equals(value, _keyboardPreviewCursor))
+ return;
_keyboardPreviewCursor = value;
NotifyOfPropertyChange(() => KeyboardPreviewCursor);
}
@@ -806,12 +901,10 @@ namespace Artemis.ViewModels
}
///
- /// Handles chaning the active keyboard, updating the preview image and profiles collection
+ /// Handles chaning the active keyboard, updating the profiles collection
///
private void DeviceManagerOnOnKeyboardChanged(object sender, KeyboardChangedEventArgs e)
{
- NotifyOfPropertyChange(() => PreviewSettings);
- NotifyOfPropertyChange(() => KeyboardImage);
LoadProfiles();
}
@@ -833,4 +926,4 @@ namespace Artemis.ViewModels
#endregion
}
-}
\ No newline at end of file
+}
diff --git a/Artemis/Artemis/ViewModels/Profiles/LayerConditionViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/LayerConditionViewModel.cs
index d20f93dfc..596b6b1ea 100644
--- a/Artemis/Artemis/ViewModels/Profiles/LayerConditionViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Profiles/LayerConditionViewModel.cs
@@ -3,6 +3,7 @@ using System.Linq;
using Artemis.Profiles.Layers.Models;
using Artemis.Utilities;
using Caliburn.Micro;
+using MahApps.Metro.Controls;
namespace Artemis.ViewModels.Profiles
{
@@ -40,10 +41,12 @@ namespace Artemis.ViewModels.Profiles
new NamedOperator("Ends with", ".EndsWith")
};
- private bool _enumValueIsVisible;
+ private HotKey _hotKey;
+ private bool _keybindIsVisible;
private GeneralHelpers.PropertyCollection _selectedDataModelProp;
- private string _selectedEnum;
+ private string _selectedDropdownValue;
private NamedOperator _selectedOperator;
+ private bool _userDropdownValueIsVisible;
private string _userValue;
private bool _userValueIsVisible;
@@ -52,38 +55,51 @@ namespace Artemis.ViewModels.Profiles
_editorViewModel = editorViewModel;
ConditionModel = conditionModel;
- DataModelProps = editorViewModel.DataModelProps;
Operators = new BindableCollection();
- Enums = new BindableCollection();
+ DropdownValues = new BindableCollection();
+ DataModelProps = new BindableCollection();
+ DataModelProps.AddRange(editorViewModel.DataModelProps);
PropertyChanged += MapViewToModel;
MapModelToView();
}
public LayerConditionModel ConditionModel { get; set; }
-
public BindableCollection DataModelProps { get; set; }
-
public BindableCollection Operators { get; set; }
- public BindableCollection Enums { get; set; }
+ public BindableCollection DropdownValues { get; set; }
public string UserValue
{
get { return _userValue; }
set
{
- if (value == _userValue) return;
+ if (value == _userValue)
+ return;
_userValue = value;
NotifyOfPropertyChange(() => UserValue);
}
}
+ public HotKey HotKey
+ {
+ get { return _hotKey; }
+ set
+ {
+ if (Equals(value, _hotKey))
+ return;
+ _hotKey = value;
+ NotifyOfPropertyChange(() => HotKey);
+ }
+ }
+
public GeneralHelpers.PropertyCollection SelectedDataModelProp
{
get { return _selectedDataModelProp; }
set
{
- if (value.Equals(_selectedDataModelProp)) return;
+ if (value.Equals(_selectedDataModelProp))
+ return;
_selectedDataModelProp = value;
SetupPropertyInput();
NotifyOfPropertyChange(() => SelectedDataModelProp);
@@ -95,20 +111,34 @@ namespace Artemis.ViewModels.Profiles
get { return _userValueIsVisible; }
set
{
- if (value == _userValueIsVisible) return;
+ if (value == _userValueIsVisible)
+ return;
_userValueIsVisible = value;
NotifyOfPropertyChange(() => UserValueIsVisible);
}
}
- public bool EnumValueIsVisible
+ public bool UserDropdownValueIsVisible
{
- get { return _enumValueIsVisible; }
+ get { return _userDropdownValueIsVisible; }
set
{
- if (value == _enumValueIsVisible) return;
- _enumValueIsVisible = value;
- NotifyOfPropertyChange(() => EnumValueIsVisible);
+ if (value == _userDropdownValueIsVisible)
+ return;
+ _userDropdownValueIsVisible = value;
+ NotifyOfPropertyChange(() => UserDropdownValueIsVisible);
+ }
+ }
+
+ public bool KeybindIsVisible
+ {
+ get { return _keybindIsVisible; }
+ set
+ {
+ if (value == _keybindIsVisible)
+ return;
+ _keybindIsVisible = value;
+ NotifyOfPropertyChange();
}
}
@@ -123,14 +153,15 @@ namespace Artemis.ViewModels.Profiles
}
}
- public string SelectedEnum
+ public string SelectedDropdownValue
{
- get { return _selectedEnum; }
+ get { return _selectedDropdownValue; }
set
{
- if (value == _selectedEnum) return;
- _selectedEnum = value;
- NotifyOfPropertyChange(() => SelectedEnum);
+ if (value == _selectedDropdownValue)
+ return;
+ _selectedDropdownValue = value;
+ NotifyOfPropertyChange(() => SelectedDropdownValue);
}
}
@@ -142,9 +173,10 @@ namespace Artemis.ViewModels.Profiles
SelectedDataModelProp = DataModelProps.FirstOrDefault(m => m.Path == ConditionModel.Field);
// Select the operator
SelectedOperator = Operators.FirstOrDefault(o => o.Value == ConditionModel.Operator);
+ HotKey = ConditionModel.HotKey;
if (ConditionModel.Type == "Enum" || ConditionModel.Type == "Boolean")
- SelectedEnum = ConditionModel.Value;
+ SelectedDropdownValue = ConditionModel.Value;
else
UserValue = ConditionModel.Value;
@@ -156,9 +188,10 @@ namespace Artemis.ViewModels.Profiles
ConditionModel.Field = SelectedDataModelProp.Path;
ConditionModel.Operator = SelectedOperator.Value;
ConditionModel.Type = SelectedDataModelProp.Type;
+ ConditionModel.HotKey = HotKey;
if (ConditionModel.Type == "Enum" || ConditionModel.Type == "Boolean")
- ConditionModel.Value = SelectedEnum;
+ ConditionModel.Value = SelectedDropdownValue;
else
ConditionModel.Value = UserValue;
}
@@ -171,7 +204,7 @@ namespace Artemis.ViewModels.Profiles
public void SetupPropertyInput()
{
Operators.Clear();
- Enums.Clear();
+ DropdownValues.Clear();
switch (SelectedDataModelProp.Type)
{
@@ -182,9 +215,9 @@ namespace Artemis.ViewModels.Profiles
break;
case "Boolean":
Operators.AddRange(_boolOperators);
- Enums.Add("True");
- Enums.Add("False");
- EnumValueIsVisible = true;
+ DropdownValues.Add("True");
+ DropdownValues.Add("False");
+ UserDropdownValueIsVisible = true;
break;
case "String":
Operators.AddRange(_stringOperators);
@@ -214,22 +247,31 @@ namespace Artemis.ViewModels.Profiles
private void SetupUserValueInput()
{
UserValueIsVisible = false;
- EnumValueIsVisible = false;
+ UserDropdownValueIsVisible = false;
+ KeybindIsVisible = false;
- if (SelectedOperator.Value == "changed" || SelectedOperator.Value == "decreased" ||
- SelectedOperator.Value == "increased")
+ // Event operators don't have any form of input
+ if (SelectedOperator.Value == "changed" || SelectedOperator.Value == "decreased" || SelectedOperator.Value == "increased")
return;
- if (SelectedDataModelProp.Type == "Boolean")
- EnumValueIsVisible = true;
+ if (SelectedDataModelProp.Type != null && SelectedDataModelProp.Type.Contains("hotkey"))
+ {
+ KeybindIsVisible = true;
+ }
+ else if (SelectedDataModelProp.Type == "Boolean")
+ {
+ UserDropdownValueIsVisible = true;
+ }
else if (SelectedDataModelProp.EnumValues != null)
{
- Enums.Clear();
- Enums.AddRange(SelectedDataModelProp.EnumValues);
- EnumValueIsVisible = true;
+ DropdownValues.Clear();
+ DropdownValues.AddRange(SelectedDataModelProp.EnumValues);
+ UserDropdownValueIsVisible = true;
}
else
+ {
UserValueIsVisible = true;
+ }
}
///
@@ -237,7 +279,7 @@ namespace Artemis.ViewModels.Profiles
///
public void Delete()
{
- _editorViewModel.DeleteCondition(this, ConditionModel);
+ _editorViewModel.LayerConditionVms.Remove(this);
}
public struct NamedOperator
@@ -252,4 +294,4 @@ namespace Artemis.ViewModels.Profiles
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Artemis/Artemis/ViewModels/Profiles/LayerKeybindViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/LayerKeybindViewModel.cs
new file mode 100644
index 000000000..e756c111c
--- /dev/null
+++ b/Artemis/Artemis/ViewModels/Profiles/LayerKeybindViewModel.cs
@@ -0,0 +1,160 @@
+using System.ComponentModel;
+using System.Windows.Forms;
+using Artemis.Profiles.Layers.Models;
+using MahApps.Metro.Controls;
+using Screen = Caliburn.Micro.Screen;
+
+namespace Artemis.ViewModels.Profiles
+{
+ public sealed class LayerKeybindViewModel : Screen
+ {
+ private readonly LayerEditorViewModel _editorViewModel;
+ private bool _canToggleType;
+
+ private HotKey _hotKey;
+ private MouseButtons _mouseButtons;
+ private ToggleType _toggleType;
+
+ public LayerKeybindViewModel(LayerEditorViewModel editorViewModel, LayerKeybindModel layerKeybindModel)
+ {
+ _editorViewModel = editorViewModel;
+ LayerKeybindModel = layerKeybindModel;
+ CanToggleType = !editorViewModel.ProposedLayer.IsEvent;
+
+ PropertyChanged += MapViewToModel;
+ editorViewModel.PropertyChanged += EditorViewModelOnPropertyChanged;
+ MapModelToView();
+ }
+
+ public bool CanToggleType
+ {
+ get { return _canToggleType; }
+ set
+ {
+ if (value == _canToggleType)
+ return;
+ _canToggleType = value;
+ NotifyOfPropertyChange(() => CanToggleType);
+ }
+ }
+
+ public LayerKeybindModel LayerKeybindModel { get; set; }
+
+
+ public bool MouseButtonsVisible => LayerKeybindModel.MouseButtons != null;
+ public bool HotkeyVisible => LayerKeybindModel.MouseButtons == null;
+
+ public MouseButtons MouseButtons
+ {
+ get { return _mouseButtons; }
+ set
+ {
+ if (value == _mouseButtons)
+ return;
+ _mouseButtons = value;
+ NotifyOfPropertyChange(() => MouseButtons);
+ }
+ }
+
+ public HotKey HotKey
+ {
+ get { return _hotKey; }
+ set
+ {
+ if (Equals(value, _hotKey))
+ return;
+ _hotKey = value;
+ NotifyOfPropertyChange(() => HotKey);
+ }
+ }
+
+ public ToggleType ToggleType
+ {
+ get { return _toggleType; }
+ set
+ {
+ if (value == _toggleType)
+ return;
+ _toggleType = value;
+ NotifyOfPropertyChange(() => ToggleType);
+ }
+ }
+
+ ///
+ /// Responds to the EventPropertiesViewModel being changed
+ ///
+ ///
+ ///
+ private void EditorViewModelOnPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName != "EventPropertiesViewModel")
+ return;
+
+ if (_editorViewModel.ProposedLayer.IsEvent)
+ {
+ CanToggleType = false;
+ ToggleType = ToggleType.Enable;
+ }
+ else
+ CanToggleType = true;
+ }
+
+ private void MapViewToModel(object sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == "MouseButtonsVisible" || e.PropertyName == "HotkeyVisible")
+ return;
+
+ if (MouseButtonsVisible)
+ SetMouseBind();
+ else
+ SetKeyBind();
+ }
+
+ private void MapModelToView()
+ {
+ PropertyChanged -= MapViewToModel;
+
+ if (LayerKeybindModel.MouseButtons != null)
+ MouseButtons = LayerKeybindModel.MouseButtons.Value;
+ HotKey = LayerKeybindModel.HotKey;
+ ToggleType = LayerKeybindModel.ToggleType;
+
+ PropertyChanged += MapViewToModel;
+ }
+
+ public void ToggleBindType()
+ {
+ if (MouseButtonsVisible)
+ SetKeyBind();
+ else
+ SetMouseBind();
+ }
+
+ public void SetMouseBind()
+ {
+ LayerKeybindModel.Unregister();
+ LayerKeybindModel.HotKey = null;
+ LayerKeybindModel.MouseButtons = MouseButtons;
+ LayerKeybindModel.ToggleType = ToggleType;
+
+ NotifyOfPropertyChange(() => HotkeyVisible);
+ NotifyOfPropertyChange(() => MouseButtonsVisible);
+ }
+
+ public void SetKeyBind()
+ {
+ LayerKeybindModel.Unregister();
+ LayerKeybindModel.HotKey = HotKey;
+ LayerKeybindModel.MouseButtons = null;
+ LayerKeybindModel.ToggleType = ToggleType;
+
+ NotifyOfPropertyChange(() => HotkeyVisible);
+ NotifyOfPropertyChange(() => MouseButtonsVisible);
+ }
+
+ public void Delete()
+ {
+ _editorViewModel.LayerKeybindVms.Remove(this);
+ }
+ }
+}
diff --git a/Artemis/Artemis/ViewModels/ShellViewModel.cs b/Artemis/Artemis/ViewModels/ShellViewModel.cs
index 4d59daf60..9c11c7d18 100644
--- a/Artemis/Artemis/ViewModels/ShellViewModel.cs
+++ b/Artemis/Artemis/ViewModels/ShellViewModel.cs
@@ -147,7 +147,11 @@ namespace Artemis.ViewModels
private void ActivateViews()
{
- var vms = _kernel.GetAll().ToList();
+ var vms = _kernel.GetAll()
+ .OrderBy(v => v.DisplayName != "Welcome")
+ .ThenBy(v => v.DisplayName)
+ .ToList();
+
Items.Clear();
Items.AddRange(vms);
ActivateItem(vms.FirstOrDefault());
diff --git a/Artemis/Artemis/Views/GamesView.xaml b/Artemis/Artemis/Views/GamesView.xaml
index 08ada4886..99d29d004 100644
--- a/Artemis/Artemis/Views/GamesView.xaml
+++ b/Artemis/Artemis/Views/GamesView.xaml
@@ -3,10 +3,9 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
-
+
diff --git a/Artemis/Artemis/Views/GeneralView.xaml b/Artemis/Artemis/Views/GeneralView.xaml
index a2e24e6f8..644409a1f 100644
--- a/Artemis/Artemis/Views/GeneralView.xaml
+++ b/Artemis/Artemis/Views/GeneralView.xaml
@@ -8,7 +8,7 @@
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
-
+
diff --git a/Artemis/Artemis/Views/LayerEditorView.xaml b/Artemis/Artemis/Views/LayerEditorView.xaml
index 772c9630a..4895a6fa6 100644
--- a/Artemis/Artemis/Views/LayerEditorView.xaml
+++ b/Artemis/Artemis/Views/LayerEditorView.xaml
@@ -1,18 +1,17 @@
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
+ mc:Ignorable="d"
+ Title="Artemis | Edit Layer" Height="640" Width="1100"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:converters="clr-namespace:Artemis.Utilities.Converters"
+ xmlns:models="clr-namespace:Artemis.Profiles.Layers.Models"
+ GlowBrush="{DynamicResource AccentColorBrush}" Icon="../../Resources/bow.png"
+ ResizeMode="CanResizeWithGrip">
@@ -24,111 +23,113 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/Artemis/Artemis/Views/OverlaysView.xaml b/Artemis/Artemis/Views/OverlaysView.xaml
index a7cbb3882..c85da1fbc 100644
--- a/Artemis/Artemis/Views/OverlaysView.xaml
+++ b/Artemis/Artemis/Views/OverlaysView.xaml
@@ -3,11 +3,9 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:local="clr-namespace:Artemis.Views"
- xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
-
+
diff --git a/Artemis/Artemis/Views/ProfileEditorView.xaml b/Artemis/Artemis/Views/ProfileEditorView.xaml
index b5166c220..73bb14f49 100644
--- a/Artemis/Artemis/Views/ProfileEditorView.xaml
+++ b/Artemis/Artemis/Views/ProfileEditorView.xaml
@@ -1,65 +1,41 @@
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
+ xmlns:itemBehaviours="clr-namespace:Artemis.ItemBehaviours"
+ xmlns:dragDrop="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop"
+ xmlns:converters="clr-namespace:Artemis.Utilities.Converters"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="400" d:DesignWidth="1060">
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
+
-
-
+
-
+
-
+
-
-
+
+
-
+
-
-
-
-
+
@@ -68,11 +44,9 @@
-
-
+
+ Height="26" HorizontalAlignment="Right">
+ Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" IsEnabled="{Binding ProfileSelected}">
+ HorizontalAlignment="Right" Margin="10,0,0,0" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"
+ Visibility="{Binding Path=LuaButtonVisible, Converter={StaticResource BoolToVis} }">
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
+
-
+
@@ -227,14 +184,12 @@
-
+
+ Style="{DynamicResource SquareButtonStyle}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"
+ Width="26" Height="26" ToolTip="Add layer" HorizontalAlignment="Left">
-
+
@@ -242,12 +197,10 @@
+ Style="{DynamicResource SquareButtonStyle}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"
+ Width="26" Height="26" ToolTip="Add folder" HorizontalAlignment="Left" Margin="10,0,0,0">
-
+
@@ -255,12 +208,10 @@
+ Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Edit layer"
+ IsEnabled="{Binding Path=LayerSelected}">
-
+
@@ -268,12 +219,10 @@
+ Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Duplicate layer"
+ IsEnabled="{Binding Path=LayerSelected}">
-
+
@@ -281,12 +230,10 @@
+ Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Delete layer"
+ IsEnabled="{Binding Path=LayerSelected}">
-
+
diff --git a/Artemis/Artemis/Views/ProfileEditorView.xaml.cs b/Artemis/Artemis/Views/ProfileEditorView.xaml.cs
index 35d68c535..44009b45f 100644
--- a/Artemis/Artemis/Views/ProfileEditorView.xaml.cs
+++ b/Artemis/Artemis/Views/ProfileEditorView.xaml.cs
@@ -12,4 +12,4 @@ namespace Artemis.Views
InitializeComponent();
}
}
-}
\ No newline at end of file
+}
diff --git a/Artemis/Artemis/Views/Profiles/LayerConditionView.xaml b/Artemis/Artemis/Views/Profiles/LayerConditionView.xaml
index 0b62d71cc..30a9d769f 100644
--- a/Artemis/Artemis/Views/Profiles/LayerConditionView.xaml
+++ b/Artemis/Artemis/Views/Profiles/LayerConditionView.xaml
@@ -1,11 +1,10 @@
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d" d:DesignWidth="600">
@@ -13,63 +12,58 @@
-
+
-
-
+
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
-
-
-
-
-
+
+
+
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Views/Profiles/LayerDynamicPropertiesView.xaml b/Artemis/Artemis/Views/Profiles/LayerDynamicPropertiesView.xaml
index 70ea80c43..a81344761 100644
--- a/Artemis/Artemis/Views/Profiles/LayerDynamicPropertiesView.xaml
+++ b/Artemis/Artemis/Views/Profiles/LayerDynamicPropertiesView.xaml
@@ -1,16 +1,14 @@
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:models="clr-namespace:Artemis.Profiles.Layers.Models"
+ xmlns:converters="clr-namespace:Artemis.Utilities.Converters"
+ mc:Ignorable="d"
+ d:DesignWidth="500">
@@ -19,20 +17,19 @@
-
+
-
+
-
+
-
+
@@ -41,18 +38,14 @@
-
+
-
+
@@ -62,8 +55,7 @@
-
+
@@ -72,8 +64,7 @@
-
+
@@ -82,16 +73,11 @@
-
+
-
+
diff --git a/Artemis/Artemis/Views/Profiles/LayerKeybindView.xaml b/Artemis/Artemis/Views/Profiles/LayerKeybindView.xaml
new file mode 100644
index 000000000..742a7913d
--- /dev/null
+++ b/Artemis/Artemis/Views/Profiles/LayerKeybindView.xaml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Views/Profiles/LayerKeybindView.xaml.cs b/Artemis/Artemis/Views/Profiles/LayerKeybindView.xaml.cs
new file mode 100644
index 000000000..8b11d18a3
--- /dev/null
+++ b/Artemis/Artemis/Views/Profiles/LayerKeybindView.xaml.cs
@@ -0,0 +1,15 @@
+using System.Windows.Controls;
+
+namespace Artemis.Views.Profiles
+{
+ ///
+ /// Interaction logic for LayerKeybindView.xaml
+ ///
+ public partial class LayerKeybindView : UserControl
+ {
+ public LayerKeybindView()
+ {
+ InitializeComponent();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Views/Profiles/LayerTweenView.xaml b/Artemis/Artemis/Views/Profiles/LayerTweenView.xaml
index 0f9c51660..4410f77ef 100644
--- a/Artemis/Artemis/Views/Profiles/LayerTweenView.xaml
+++ b/Artemis/Artemis/Views/Profiles/LayerTweenView.xaml
@@ -1,47 +1,58 @@
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Artemis.Views.Profiles"
+ xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
+ mc:Ignorable="d"
+ d:DesignHeight="300" d:DesignWidth="900">
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Views/ShellView.xaml b/Artemis/Artemis/Views/ShellView.xaml
index 9697d638b..ab1bde511 100644
--- a/Artemis/Artemis/Views/ShellView.xaml
+++ b/Artemis/Artemis/Views/ShellView.xaml
@@ -1,26 +1,23 @@
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:dialogs="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
+ xmlns:viewModels="clr-namespace:Artemis.ViewModels"
+ xmlns:tb="http://www.hardcodet.net/taskbar"
+ dialogs:DialogParticipation.Register="{Binding RelativeSource={RelativeSource Self}, Path=DataContext}"
+ mc:Ignorable="d" d:DataContext="{d:DesignInstance viewModels:ShellViewModel}"
+ Title="Artemis" Height="800" Width="1210" MinHeight="600" MinWidth="1000" GlowBrush="{DynamicResource AccentColorBrush}" Icon="../logo.ico">
-
+
@@ -60,17 +57,17 @@
+ IconSource="{Binding Path=ActiveIcon, Mode=OneWay}"
+ ToolTipText="Artemis"
+ cal:Message.Attach="[Event TrayMouseDoubleClick] = [Action ShowWindow]"
+ ContextMenu="{StaticResource MainSysTrayMenu}" />
+ Height="{TemplateBinding Height}"
+ Background="Transparent"
+ RenderOptions.BitmapScalingMode="HighQuality" Margin="0,0,-10,0">
@@ -83,7 +80,7 @@
+ Fill="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}">
@@ -116,11 +113,10 @@
-
+
-
+
diff --git a/Artemis/Artemis/Views/WelcomeView.xaml b/Artemis/Artemis/Views/WelcomeView.xaml
index f0e2d9d70..51d6a13df 100644
--- a/Artemis/Artemis/Views/WelcomeView.xaml
+++ b/Artemis/Artemis/Views/WelcomeView.xaml
@@ -22,7 +22,7 @@
Hello,
Thanks a bunch for downloading this application. You're going to enjoy this! :)
- To get started you can click any of the categories on the left and browse through the effects.
+ To get started you can click any of the categories on the top and browse through the modules.
Some games require a bit of setting up, so be sure to take a look at everything you want to use.
diff --git a/Artemis/Artemis/lib/AssettoCorsaSharedMemory.dll b/Artemis/Artemis/lib/AssettoCorsaSharedMemory.dll
new file mode 100644
index 000000000..e56aae8dc
Binary files /dev/null and b/Artemis/Artemis/lib/AssettoCorsaSharedMemory.dll differ
diff --git a/Artemis/Artemis/lib/SDKDLL.dll b/Artemis/Artemis/lib/SDKDLL.dll
index 279981433..a71619198 100644
Binary files a/Artemis/Artemis/lib/SDKDLL.dll and b/Artemis/Artemis/lib/SDKDLL.dll differ
diff --git a/Artemis/Artemis/packages.config b/Artemis/Artemis/packages.config
index d78a83092..d4e1ed0f9 100644
--- a/Artemis/Artemis/packages.config
+++ b/Artemis/Artemis/packages.config
@@ -3,32 +3,32 @@
-
+
-
-
+
+
-
-
+
+
+
-
-
-
+
+
-
+
\ No newline at end of file