mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
commit
2edbf093a7
@ -384,6 +384,13 @@
|
||||
<DependentUpon>AssettoCorsaView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Modules\Games\AssettoCorsa\AssettoCorsaViewModel.cs" />
|
||||
<Compile Include="Modules\Games\Terraria\TerrariaDataModel.cs" />
|
||||
<Compile Include="Modules\Games\Terraria\TerrariaSettings.cs" />
|
||||
<Compile Include="Modules\Games\Terraria\TerrariaModel.cs" />
|
||||
<Compile Include="Modules\Games\Terraria\TerrariaView.xaml.cs">
|
||||
<DependentUpon>TerrariaView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Modules\Games\Terraria\TerrariaViewModel.cs" />
|
||||
<Compile Include="Modules\General\GeneralProfile\PerformanceInfo.cs" />
|
||||
<Compile Include="Modules\Games\EurotruckSimulator2\Data\Ets2TelemetryData.cs" />
|
||||
<Compile Include="Modules\Games\EurotruckSimulator2\Data\Ets2TelemetryDataReader.cs" />
|
||||
@ -561,15 +568,27 @@
|
||||
<Compile Include="Profiles\Lua\Modules\Events\LuaKeyPressEventArgs.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\Events\LuaDeviceDrawingEventArgs.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\Events\LuaDeviceUpdatingEventArgs.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\Gui\EditorButton.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\Gui\LuaButton.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\Gui\LuaCheckBox.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\Gui\LuaComboBox.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\Gui\LuaLabel.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\Gui\LuaTextBox.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\Gui\LuaWindowView.xaml.cs">
|
||||
<DependentUpon>LuaWindowView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Profiles\Lua\Modules\Gui\LuaWindowViewModel.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\LuaEventsModule.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\LuaBrushesModule.cs" />
|
||||
<Compile Include="Profiles\Lua\LuaModule.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\Brushes\LuaSolidColorBrush.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\LuaGuiModule.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\LuaKeybindModule.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\LuaKeyboardModule.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\LuaLayerModule.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\LuaMouseModule.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\LuaProfileModule.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\LuaStorageModule.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\Timer\LuaTimer.cs" />
|
||||
<Compile Include="Profiles\Lua\Modules\LuaTimerModule.cs" />
|
||||
<Compile Include="Profiles\Lua\Wrappers\LuaDrawWrapper.cs" />
|
||||
@ -645,6 +664,7 @@
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Services\CompatibilityService.cs" />
|
||||
<Compile Include="Services\DialogService.cs" />
|
||||
<Compile Include="Services\MetroDialogService.cs" />
|
||||
<Compile Include="Services\WindowService.cs" />
|
||||
@ -653,7 +673,11 @@
|
||||
<Compile Include="Settings\OffsetSettings.cs" />
|
||||
<Compile Include="Styles\DropTargetAdorners\DropTargetMetroHighlightAdorner.cs" />
|
||||
<Compile Include="Styles\DropTargetAdorners\DropTargetMetroInsertionAdorner.cs" />
|
||||
<Compile Include="Utilities\ActiveWindowHelper.cs" />
|
||||
<Compile Include="Utilities\ActiveWindowDetection\ActiveWindowDetectionType.cs" />
|
||||
<Compile Include="Utilities\ActiveWindowDetection\ActiveWindowHelper.cs" />
|
||||
<Compile Include="Utilities\ActiveWindowDetection\EventActiveWindowDetector.cs" />
|
||||
<Compile Include="Utilities\ActiveWindowDetection\IActiveWindowDetector.cs" />
|
||||
<Compile Include="Utilities\ActiveWindowDetection\TimerActiveWindowDetector.cs" />
|
||||
<Compile Include="Utilities\ColorHelpers.cs" />
|
||||
<Compile Include="Utilities\Converters\JsonConverters.cs" />
|
||||
<Compile Include="Utilities\Converters\NinjectCustomConverter.cs" />
|
||||
@ -856,6 +880,10 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Modules\Games\Terraria\TerrariaView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Modules\General\Bubbles\BubblesView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
@ -924,6 +952,10 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Profiles\Lua\Modules\Gui\LuaWindowView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Resources\Icons.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
|
||||
@ -8,8 +8,10 @@ using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using Artemis.DAL;
|
||||
using Artemis.InjectionModules;
|
||||
using Artemis.Services;
|
||||
using Artemis.Settings;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.ActiveWindowDetection;
|
||||
using Artemis.Utilities.Converters;
|
||||
using Artemis.Utilities.DataReaders;
|
||||
using Artemis.ViewModels;
|
||||
@ -31,10 +33,11 @@ namespace Artemis
|
||||
Logging.SetupLogging(SettingsProvider.Load<GeneralSettings>().LogLevel);
|
||||
// Restore DDLs before interacting with any SDKs
|
||||
DllManager.RestoreLogitechDll();
|
||||
// Check compatibility before trying to boot further
|
||||
CompatibilityService.CheckRivaTuner();
|
||||
|
||||
Initialize();
|
||||
BindSpecialValues();
|
||||
InputHook.Start();
|
||||
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
|
||||
}
|
||||
@ -61,7 +64,7 @@ namespace Artemis
|
||||
}
|
||||
|
||||
// If there is another type of of IInputControl get the non-scaled position - or do some processing to get a scaled position, whatever needs to happen
|
||||
if ((e != null) && (input != null))
|
||||
if (e != null && input != null)
|
||||
return e.GetPosition(input).X;
|
||||
|
||||
// Return 0 if no processing could be done
|
||||
@ -98,6 +101,7 @@ namespace Artemis
|
||||
logger.Info("Artemis was run using the autorun shortcut, sleeping for 15 sec.");
|
||||
Thread.Sleep(15000);
|
||||
}
|
||||
|
||||
_kernel = new StandardKernel(new BaseModules(), new ManagerModules());
|
||||
|
||||
_kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
|
||||
@ -113,7 +117,7 @@ namespace Artemis
|
||||
|
||||
//TODO DarthAffe 17.12.2016: Is this the right location for this?
|
||||
//TODO Move to Mainmanager and make disposable
|
||||
ActiveWindowHelper.Initialize();
|
||||
ActiveWindowHelper.SetActiveWindowDetectionType(SettingsProvider.Load<GeneralSettings>().ActiveWindowDetection);
|
||||
}
|
||||
|
||||
protected override void OnExit(object sender, EventArgs e)
|
||||
@ -144,6 +148,7 @@ namespace Artemis
|
||||
protected override void OnStartup(object sender, StartupEventArgs e)
|
||||
{
|
||||
DisplayRootViewFor<ShellViewModel>();
|
||||
InputHook.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -134,7 +134,7 @@ namespace Artemis.DAL
|
||||
return null;
|
||||
return prof;
|
||||
}
|
||||
catch (JsonSerializationException)
|
||||
catch (JsonException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System.Drawing;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
@ -67,6 +68,8 @@ namespace Artemis.DeviceProviders.CoolerMaster
|
||||
for (var y = 0; y < Height; y++)
|
||||
{
|
||||
var c = b.GetPixel(x, y);
|
||||
if (c.R != 0)
|
||||
Console.WriteLine();
|
||||
matrix.KeyColor[y, x] = new KEY_COLOR(c.R, c.G, c.B);
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,9 +42,16 @@ namespace Artemis.DeviceProviders.CoolerMaster
|
||||
CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MMouse_L);
|
||||
|
||||
// Doesn't seem reliable but better than nothing I suppose
|
||||
CanUse = CmSdk.IsDevicePlug();
|
||||
if (CanUse)
|
||||
CmSdk.EnableLedControl(true);
|
||||
try
|
||||
{
|
||||
CanUse = CmSdk.IsDevicePlug();
|
||||
if (CanUse)
|
||||
CmSdk.EnableLedControl(true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
CanUse = false;
|
||||
}
|
||||
|
||||
Logger.Debug("Attempted to enable Mastermouse Pro L. CanUse: {0}", CanUse);
|
||||
return CanUse;
|
||||
|
||||
@ -38,10 +38,17 @@ namespace Artemis.DeviceProviders.CoolerMaster
|
||||
CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MMouse_S);
|
||||
|
||||
// Doesn't seem reliable but better than nothing I suppose
|
||||
CanUse = CmSdk.IsDevicePlug();
|
||||
if (CanUse)
|
||||
CmSdk.EnableLedControl(true);
|
||||
|
||||
try
|
||||
{
|
||||
CanUse = CmSdk.IsDevicePlug();
|
||||
if (CanUse)
|
||||
CmSdk.EnableLedControl(true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
CanUse = false;
|
||||
}
|
||||
|
||||
Logger.Debug("Attempted to enable Mastermouse Pro S. CanUse: {0}", CanUse);
|
||||
return CanUse;
|
||||
}
|
||||
|
||||
@ -81,10 +81,10 @@ namespace Artemis.DeviceProviders.Corsair
|
||||
PreviewSettings = new PreviewSettings(new Rect(15, 30, 751, 284), Resources.k65);
|
||||
break;
|
||||
case "STRAFE RGB":
|
||||
Height = 7;
|
||||
Height = 8;
|
||||
Width = 22;
|
||||
Slug = "corsair-strafe-rgb";
|
||||
PreviewSettings = new PreviewSettings(new Rect(23, 30, 940, 303), Resources.strafe);
|
||||
PreviewSettings = new PreviewSettings(new Rect(23, 12, 937, 324), Resources.strafe);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -114,29 +114,8 @@ namespace Artemis.DeviceProviders.Corsair
|
||||
/// <param name="bitmap"></param>
|
||||
public override void DrawBitmap(Bitmap bitmap)
|
||||
{
|
||||
|
||||
// For STRAFE, stretch the image on row 2.
|
||||
if (_keyboard.DeviceInfo.Model == "STRAFE RGB")
|
||||
{
|
||||
using (var strafeBitmap = new Bitmap(22, 8))
|
||||
{
|
||||
using (var g = Graphics.FromImage(strafeBitmap))
|
||||
{
|
||||
g.DrawImage(bitmap, new Point(0, 0));
|
||||
g.DrawImage(bitmap, new Rectangle(0, 3, 22, 7), new Rectangle(0, 2, 22, 7),
|
||||
GraphicsUnit.Pixel);
|
||||
|
||||
_keyboardBrush.Image = strafeBitmap;
|
||||
_keyboard.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_keyboardBrush.Image = bitmap;
|
||||
_keyboard.Update();
|
||||
}
|
||||
|
||||
_keyboardBrush.Image = bitmap;
|
||||
_keyboard.Update();
|
||||
}
|
||||
|
||||
public override KeyMatch? GetKeyPosition(Keys keyCode)
|
||||
|
||||
@ -14,8 +14,7 @@ namespace Artemis.DeviceProviders.Logitech
|
||||
DllManager.RestoreLogitechDll();
|
||||
|
||||
// Check to see if VC++ 2012 x64 is installed.
|
||||
if (Registry.LocalMachine.OpenSubKey(
|
||||
@"SOFTWARE\Classes\Installer\Dependencies\{ca67548a-5ebe-413a-b50c-4b9ceb6d66c6}") == null)
|
||||
if (Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\Installer\Dependencies\{ca67548a-5ebe-413a-b50c-4b9ceb6d66c6}") == null)
|
||||
{
|
||||
CantEnableText = "Couldn't connect to your Logitech keyboard.\n" +
|
||||
"The Visual C++ 2012 Redistributable v11.0.61030.0 could not be found, which is required.\n" +
|
||||
|
||||
@ -37,8 +37,11 @@ namespace Artemis.DeviceProviders.Razer
|
||||
return false;
|
||||
|
||||
// Some people have Synapse installed, but not a Chroma keyboard, deal with this
|
||||
Chroma.Instance.Initialize();
|
||||
var blackWidowFound = Chroma.Instance.Query(Devices.Blackwidow).Connected;
|
||||
var blackWidowTeFound = Chroma.Instance.Query(Devices.BlackwidowTe).Connected;
|
||||
Chroma.Instance.Uninitialize();
|
||||
|
||||
return blackWidowFound || blackWidowTeFound;
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ using Artemis.Profiles.Layers.Abstract;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Types.Audio.AudioCapturing;
|
||||
using Artemis.Profiles.Lua;
|
||||
using Artemis.Profiles.Lua.Modules.Gui;
|
||||
using Artemis.Services;
|
||||
using Artemis.Utilities.DataReaders;
|
||||
using Artemis.Utilities.GameState;
|
||||
@ -116,6 +117,8 @@ namespace Artemis.InjectionModules
|
||||
.InheritedFrom<LuaModule>()
|
||||
.BindAllBaseClasses());
|
||||
|
||||
Bind<LuaWindowViewModel>().ToSelf();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Artemis.DeviceProviders;
|
||||
using Artemis.Profiles;
|
||||
using Artemis.Profiles.Lua;
|
||||
using Artemis.Profiles.Lua.Modules;
|
||||
using Artemis.Profiles.Lua.Modules.Gui;
|
||||
using Castle.Core.Internal;
|
||||
using MoonSharp.Interpreter;
|
||||
using Ninject;
|
||||
@ -17,7 +19,6 @@ namespace Artemis.Managers
|
||||
private readonly DeviceManager _deviceManager;
|
||||
private readonly IKernel _kernel;
|
||||
private readonly ILogger _logger;
|
||||
private readonly Script _luaScript;
|
||||
private List<LuaModule> _luaModules;
|
||||
|
||||
public LuaManager(IKernel kernel, ILogger logger, DeviceManager deviceManager)
|
||||
@ -25,13 +26,17 @@ namespace Artemis.Managers
|
||||
_kernel = kernel;
|
||||
_logger = logger;
|
||||
_deviceManager = deviceManager;
|
||||
_luaScript = new Script(CoreModules.Preset_SoftSandbox);
|
||||
|
||||
EditorButtons = new ObservableCollection<EditorButton>();
|
||||
LuaScript = new Script(CoreModules.Preset_SoftSandbox);
|
||||
}
|
||||
|
||||
public ProfileModel ProfileModel { get; private set; }
|
||||
public KeyboardProvider KeyboardProvider { get; private set; }
|
||||
public LuaProfileModule ProfileModule { get; private set; }
|
||||
public LuaEventsModule EventsModule { get; private set; }
|
||||
public Script LuaScript { get; }
|
||||
public ObservableCollection<EditorButton> EditorButtons { get; set; }
|
||||
|
||||
public void SetupLua(ProfileModel profileModel)
|
||||
{
|
||||
@ -52,11 +57,11 @@ namespace Artemis.Managers
|
||||
EventsModule = (LuaEventsModule) _luaModules.First(m => m.ModuleName == "Events");
|
||||
|
||||
// Setup new state
|
||||
_luaScript.Options.DebugPrint = LuaPrint;
|
||||
LuaScript.Options.DebugPrint = LuaPrint;
|
||||
|
||||
// Insert each module into the script's globals
|
||||
foreach (var luaModule in _luaModules)
|
||||
_luaScript.Globals[luaModule.ModuleName] = luaModule;
|
||||
// Insert each module with a ModuleName into the script's globals
|
||||
foreach (var luaModule in _luaModules.Where(m => m.ModuleName != null))
|
||||
LuaScript.Globals[luaModule.ModuleName] = luaModule;
|
||||
|
||||
// If there is no LUA script, don't bother executing the string
|
||||
if (ProfileModel.LuaScript.IsNullOrEmpty())
|
||||
@ -66,9 +71,9 @@ namespace Artemis.Managers
|
||||
{
|
||||
lock (EventsModule.InvokeLock)
|
||||
{
|
||||
lock (_luaScript)
|
||||
lock (LuaScript)
|
||||
{
|
||||
_luaScript.DoString(ProfileModel.LuaScript);
|
||||
LuaScript.DoString(ProfileModel.LuaScript);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -97,12 +102,12 @@ namespace Artemis.Managers
|
||||
|
||||
try
|
||||
{
|
||||
_luaScript.Globals.Clear();
|
||||
_luaScript.Registry.Clear();
|
||||
_luaScript.Registry.RegisterConstants();
|
||||
_luaScript.Registry.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
|
||||
_luaScript.Globals.RegisterConstants();
|
||||
_luaScript.Globals.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
|
||||
LuaScript.Globals.Clear();
|
||||
LuaScript.Registry.Clear();
|
||||
LuaScript.Registry.RegisterConstants();
|
||||
LuaScript.Registry.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
|
||||
LuaScript.Globals.RegisterConstants();
|
||||
LuaScript.Globals.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
|
||||
}
|
||||
catch (NullReferenceException)
|
||||
{
|
||||
@ -112,15 +117,15 @@ namespace Artemis.Managers
|
||||
if (EventsModule != null)
|
||||
lock (EventsModule.InvokeLock)
|
||||
{
|
||||
lock (_luaScript)
|
||||
lock (LuaScript)
|
||||
{
|
||||
_luaScript.DoString("");
|
||||
LuaScript.DoString("");
|
||||
}
|
||||
}
|
||||
else
|
||||
lock (_luaScript)
|
||||
lock (LuaScript)
|
||||
{
|
||||
_luaScript.DoString("");
|
||||
LuaScript.DoString("");
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,12 +143,12 @@ namespace Artemis.Managers
|
||||
{
|
||||
lock (EventsModule.InvokeLock)
|
||||
{
|
||||
lock (_luaScript)
|
||||
lock (LuaScript)
|
||||
{
|
||||
if (args != null)
|
||||
_luaScript.Call(function, args);
|
||||
LuaScript.Call(function, args);
|
||||
else
|
||||
_luaScript.Call(function);
|
||||
LuaScript.Call(function);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,6 +108,7 @@ namespace Artemis.Managers
|
||||
public async void EnableProgram()
|
||||
{
|
||||
Logger.Debug("Enabling program");
|
||||
|
||||
ProgramEnabled = true;
|
||||
await LoopManager.StartAsync();
|
||||
|
||||
@ -121,9 +122,12 @@ namespace Artemis.Managers
|
||||
public void DisableProgram()
|
||||
{
|
||||
Logger.Debug("Disabling program");
|
||||
|
||||
foreach (var overlayModule in ModuleManager.OverlayModules)
|
||||
{
|
||||
if (overlayModule.Settings.IsEnabled)
|
||||
overlayModule.Dispose();
|
||||
}
|
||||
LoopManager.Stop();
|
||||
ProgramEnabled = false;
|
||||
RaiseEnabledChangedEvent(new EnabledChangedEventArgs(ProgramEnabled));
|
||||
@ -178,4 +182,4 @@ namespace Artemis.Managers
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ using Artemis.DAL;
|
||||
using Artemis.Modules.Abstract;
|
||||
using Artemis.Settings;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.ActiveWindowDetection;
|
||||
using Ninject.Extensions.Logging;
|
||||
|
||||
namespace Artemis.Managers
|
||||
|
||||
@ -27,8 +27,7 @@ namespace Artemis.Models
|
||||
private FileSystemWatcher _watcher;
|
||||
private ModuleModel _luaModule;
|
||||
|
||||
public ProfileEditorModel(WindowService windowService, MetroDialogService dialogService,
|
||||
DeviceManager deviceManager, LuaManager luaManager)
|
||||
public ProfileEditorModel(WindowService windowService, MetroDialogService dialogService, DeviceManager deviceManager, LuaManager luaManager)
|
||||
{
|
||||
_windowService = windowService;
|
||||
_dialogService = dialogService;
|
||||
@ -50,7 +49,7 @@ namespace Artemis.Models
|
||||
new ConstructorArgument("dataModel", dataModel),
|
||||
new ConstructorArgument("layer", layer)
|
||||
};
|
||||
_windowService.ShowDialog<LayerEditorViewModel>("Artemis | Edit layer", args);
|
||||
_windowService.ShowDialog<LayerEditorViewModel>("Artemis | Edit layer", null, args);
|
||||
|
||||
// If the layer was a folder, but isn't anymore, assign it's children to it's parent.
|
||||
if (layer.LayerType is FolderType || !layer.Children.Any())
|
||||
@ -345,7 +344,8 @@ namespace Artemis.Models
|
||||
|
||||
private void DisposeLuaWatcher()
|
||||
{
|
||||
if (_watcher == null) return;
|
||||
if (_watcher == null)
|
||||
return;
|
||||
_watcher.Changed -= LuaFileChanged;
|
||||
_watcher.Dispose();
|
||||
_watcher = null;
|
||||
@ -360,8 +360,6 @@ namespace Artemis.Models
|
||||
|
||||
#region Rendering
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<!-- Header -->
|
||||
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontSize="20" HorizontalAlignment="Left">
|
||||
<Label.Content>
|
||||
<AccessText TextWrapping="Wrap" Text="By default shows RPM on the F-keys, gear on the other keys and track flags on the numpad." />
|
||||
<AccessText TextWrapping="Wrap" Text="By default shows RPM on bottom half of the keyboard, engine stats on the top half and DRS on the numpad" />
|
||||
</Label.Content>
|
||||
</Label>
|
||||
|
||||
|
||||
@ -29,7 +29,6 @@ namespace Artemis.Modules.Games.GtaV
|
||||
|
||||
public override void Enable()
|
||||
{
|
||||
var process = System.Diagnostics.Process.GetProcessesByName("GTA5").First();
|
||||
DllManager.PlaceLogitechDll();
|
||||
_pipeServer.PipeMessage += PipeServerOnPipeMessage;
|
||||
base.Enable();
|
||||
|
||||
@ -36,7 +36,7 @@ namespace Artemis.Modules.Games.RocketLeague
|
||||
{
|
||||
if (!SettingsProvider.Load<GeneralSettings>().EnablePointersUpdate)
|
||||
{
|
||||
VersionText = "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 module not working after a game update.";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
18
Artemis/Artemis/Modules/Games/Terraria/TerrariaDataModel.cs
Normal file
18
Artemis/Artemis/Modules/Games/Terraria/TerrariaDataModel.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using Artemis.Modules.Abstract;
|
||||
using MoonSharp.Interpreter;
|
||||
|
||||
namespace Artemis.Modules.Games.Terraria
|
||||
{
|
||||
[MoonSharpUserData]
|
||||
public class TerrariaDataModel : ModuleDataModel
|
||||
{
|
||||
public int Hp { get; set; }
|
||||
public int MaxHp { get; set; }
|
||||
public int Mana { get; set; }
|
||||
public int MaxMana { get; set; }
|
||||
public int Breath { get; set; }
|
||||
public int MaxBreath { get; set; }
|
||||
public bool InWater { get; set; }
|
||||
public bool InLava { get; set; }
|
||||
}
|
||||
}
|
||||
91
Artemis/Artemis/Modules/Games/Terraria/TerrariaModel.cs
Normal file
91
Artemis/Artemis/Modules/Games/Terraria/TerrariaModel.cs
Normal file
@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Artemis.DAL;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Modules.Abstract;
|
||||
using Artemis.Settings;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.Memory;
|
||||
|
||||
namespace Artemis.Modules.Games.Terraria
|
||||
{
|
||||
public class TerrariaModel : ModuleModel
|
||||
{
|
||||
private Memory _memory;
|
||||
private GamePointersCollection _pointer;
|
||||
|
||||
public TerrariaModel(DeviceManager deviceManager, LuaManager luaManager) : base(deviceManager, luaManager)
|
||||
{
|
||||
Settings = SettingsProvider.Load<TerrariaSettings>();
|
||||
DataModel = new TerrariaDataModel();
|
||||
ProcessNames.Add("Terraria");
|
||||
|
||||
// Generate a new offset when the game is updated
|
||||
//_pointer = new GamePointersCollection
|
||||
//{
|
||||
// Game = "Terraria",
|
||||
// GameVersion = "1.3.4.4",
|
||||
// GameAddresses = new List<GamePointer>
|
||||
// {
|
||||
// new GamePointer
|
||||
// {
|
||||
// Description = "PlayerBase",
|
||||
// BasePointer = new IntPtr(0x0039C078),
|
||||
// Offsets = new[] {0x280, 0x6C0, 0x674, 0x3C}
|
||||
// }
|
||||
// }
|
||||
//};
|
||||
//var res = JsonConvert.SerializeObject(_pointer, Formatting.Indented);
|
||||
}
|
||||
|
||||
public override string Name => "Terraria";
|
||||
public override bool IsOverlay => false;
|
||||
public override bool IsBoundToProcess => true;
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
_memory?.Dispose();
|
||||
_memory = null;
|
||||
}
|
||||
|
||||
public override void Enable()
|
||||
{
|
||||
Updater.GetPointers();
|
||||
_pointer = SettingsProvider.Load<OffsetSettings>().Terraria;
|
||||
|
||||
base.Enable();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (_memory == null)
|
||||
{
|
||||
var tempProcess = MemoryHelpers.GetProcessIfRunning(ProcessNames[0]);
|
||||
if (tempProcess == null)
|
||||
return;
|
||||
|
||||
_memory = new Memory(tempProcess);
|
||||
}
|
||||
|
||||
if (ProfileModel == null || DataModel == null || _memory == null)
|
||||
return;
|
||||
|
||||
var offsets = _pointer.GameAddresses.First(ga => ga.Description == "PlayerBase").ToString();
|
||||
var baseAddress = _memory.GetAddress("\"Terraria.exe\"" + offsets);
|
||||
var basePointer = new IntPtr(_memory.ReadInt32(baseAddress));
|
||||
var playerPointer = new IntPtr(_memory.ReadInt32(basePointer + 0x18));
|
||||
|
||||
var dataModel = (TerrariaDataModel) DataModel;
|
||||
dataModel.Hp = _memory.ReadInt32(playerPointer + 0x340);
|
||||
dataModel.MaxHp = _memory.ReadInt32(playerPointer + 0x338);
|
||||
dataModel.Mana = _memory.ReadInt32(playerPointer + 0x344);
|
||||
dataModel.MaxMana = _memory.ReadInt32(playerPointer + 0x348);
|
||||
dataModel.Breath = _memory.ReadInt32(playerPointer + 0x2B4);
|
||||
dataModel.MaxBreath = _memory.ReadInt32(playerPointer + 0x2B0);
|
||||
dataModel.InWater = Convert.ToBoolean(_memory.ReadInt32(playerPointer + 0x1D));
|
||||
dataModel.InLava = Convert.ToBoolean(_memory.ReadInt32(playerPointer + 0x20));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
using Artemis.Modules.Abstract;
|
||||
|
||||
namespace Artemis.Modules.Games.Terraria
|
||||
{
|
||||
public class TerrariaSettings : ModuleSettings
|
||||
{
|
||||
}
|
||||
}
|
||||
48
Artemis/Artemis/Modules/Games/Terraria/TerrariaView.xaml
Normal file
48
Artemis/Artemis/Modules/Games/Terraria/TerrariaView.xaml
Normal file
@ -0,0 +1,48 @@
|
||||
<UserControl x:Class="Artemis.Modules.Games.Terraria.TerrariaView"
|
||||
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.Terraria"
|
||||
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
|
||||
xmlns:cal="http://www.caliburnproject.org"
|
||||
mc:Ignorable="d" d:DesignWidth="714.667" d:DesignHeight="384.667" >
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="30" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Header -->
|
||||
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontSize="20" HorizontalAlignment="Left">
|
||||
<Label.Content>
|
||||
<AccessText TextWrapping="Wrap" Text="By default does nothing! (default profiles coming soon)" />
|
||||
</Label.Content>
|
||||
</Label>
|
||||
|
||||
<!-- Sub header -->
|
||||
<TextBlock x:Name="VersionText" Grid.Row="1" Grid.Column="0" VerticalAlignment="Bottom" TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold" TextAlignment="Justify" Margin="5,0,0,10" />
|
||||
|
||||
<!-- Enable -->
|
||||
<StackPanel Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<Label Content="Enable module" HorizontalAlignment="Right" Margin="0,0,0,3" />
|
||||
<controls:ToggleSwitchButton IsChecked="{Binding Path=IsModuleEnabled, Mode=OneWay}" cal:Message.Attach="[Event Click] = [Action ToggleModule]"
|
||||
Style="{StaticResource MahApps.Metro.Styles.ToggleSwitchButton.Win10}" ToolTip="Note: You can't enable an module when Artemis is disabled" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Profile editor -->
|
||||
<ContentControl Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ProfileEditor" />
|
||||
|
||||
<!-- Buttons -->
|
||||
<StackPanel Grid.Column="0" Grid.Row="3" Orientation="Horizontal" VerticalAlignment="Bottom">
|
||||
<Button x:Name="ResetSettings" Content="Reset effect" VerticalAlignment="Top" Width="100" Style="{DynamicResource SquareButtonStyle}" />
|
||||
<Button x:Name="SaveSettings" Content="Save changes" VerticalAlignment="Top" Width="100" Margin="10,0,0,0" Style="{DynamicResource SquareButtonStyle}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
28
Artemis/Artemis/Modules/Games/Terraria/TerrariaView.xaml.cs
Normal file
28
Artemis/Artemis/Modules/Games/Terraria/TerrariaView.xaml.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Artemis.Modules.Games.Terraria
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for TerrariaView.xaml
|
||||
/// </summary>
|
||||
public partial class TerrariaView : UserControl
|
||||
{
|
||||
public TerrariaView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
47
Artemis/Artemis/Modules/Games/Terraria/TerrariaViewModel.cs
Normal file
47
Artemis/Artemis/Modules/Games/Terraria/TerrariaViewModel.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using Artemis.DAL;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Modules.Abstract;
|
||||
using Artemis.Settings;
|
||||
using Artemis.Utilities;
|
||||
using Ninject;
|
||||
|
||||
namespace Artemis.Modules.Games.Terraria
|
||||
{
|
||||
public sealed class TerrariaViewModel : ModuleViewModel
|
||||
{
|
||||
private string _versionText;
|
||||
|
||||
|
||||
public TerrariaViewModel(MainManager mainManager, [Named(nameof(TerrariaModel))] ModuleModel moduleModel, IKernel kernel) : base(mainManager, moduleModel, kernel)
|
||||
{
|
||||
DisplayName = "Terraria";
|
||||
SetVersionText();
|
||||
}
|
||||
|
||||
public override bool UsesProfileEditor => true;
|
||||
|
||||
public string VersionText
|
||||
{
|
||||
get { return _versionText; }
|
||||
set
|
||||
{
|
||||
if (value == _versionText) return;
|
||||
_versionText = value;
|
||||
NotifyOfPropertyChange(() => VersionText);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetVersionText()
|
||||
{
|
||||
if (!SettingsProvider.Load<GeneralSettings>().EnablePointersUpdate)
|
||||
{
|
||||
VersionText = "You disabled pointer updates, this could result in the Terraria module not working after a game update.";
|
||||
return;
|
||||
}
|
||||
|
||||
Updater.GetPointers();
|
||||
var version = SettingsProvider.Load<OffsetSettings>().Terraria?.GameVersion;
|
||||
VersionText = $"Requires patch {version}. When a new patch is released Artemis downloads new pointers for the latest version (unless disabled in settings).";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,7 @@ using Artemis.Events;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Modules.Abstract;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.ActiveWindowDetection;
|
||||
using CSCore.CoreAudioAPI;
|
||||
using Newtonsoft.Json;
|
||||
using SpotifyAPI.Local;
|
||||
|
||||
@ -1,12 +1,6 @@
|
||||
<UserControl x:Class="Artemis.Modules.General.GeneralProfile.GeneralProfileView"
|
||||
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">
|
||||
<UserControl x:Class="Artemis.Modules.General.GeneralProfile.GeneralProfileView" 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">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
|
||||
@ -63,9 +63,15 @@ namespace Artemis.Profiles.Layers.Models
|
||||
switch (ToggleType)
|
||||
{
|
||||
case ToggleType.Enable:
|
||||
// Apply RenderAllowed only if this is the first keybind
|
||||
if (index == 0)
|
||||
layerModel.RenderAllowed = false;
|
||||
action = () => layerModel.RenderAllowed = true;
|
||||
break;
|
||||
case ToggleType.Disable:
|
||||
// Apply RenderAllowed only if this is the first keybind
|
||||
if (index == 0)
|
||||
layerModel.RenderAllowed = false;
|
||||
action = () => layerModel.RenderAllowed = false;
|
||||
break;
|
||||
case ToggleType.Toggle:
|
||||
|
||||
@ -1,261 +1,261 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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;
|
||||
using Artemis.Profiles.Layers.Types.Keyboard;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.ParentChild;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Models
|
||||
{
|
||||
public class LayerModel : IChildItem<LayerModel>, IChildItem<ProfileModel>
|
||||
{
|
||||
public LayerModel()
|
||||
{
|
||||
Children = new ChildItemCollection<LayerModel, LayerModel>(this);
|
||||
TweenModel = new TweenModel(this);
|
||||
RenderAllowed = true;
|
||||
|
||||
var model = Properties as KeyboardPropertiesModel;
|
||||
if (model != null)
|
||||
GifImage = new GifImage(model.GifFile, Properties.AnimationSpeed);
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public ImageSource LayerImage => LayerType.DrawThumbnail(this);
|
||||
|
||||
[JsonIgnore]
|
||||
public TweenModel TweenModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether this layers conditions are met.
|
||||
/// If they are met and this layer is an event, this also triggers that event.
|
||||
/// </summary>
|
||||
/// <param name="dataModel"></param>
|
||||
/// <returns></returns>
|
||||
public bool AreConditionsMet(ModuleDataModel dataModel)
|
||||
{
|
||||
// Conditions are not even checked if the layer isn't enabled
|
||||
return Enabled && LayerCondition.ConditionsMet(this, dataModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the layer
|
||||
/// </summary>
|
||||
/// <param name="dataModel"></param>
|
||||
/// <param name="preview"></param>
|
||||
/// <param name="updateAnimations"></param>
|
||||
public void Update(ModuleDataModel dataModel, bool preview, bool updateAnimations)
|
||||
{
|
||||
if (LayerType == null)
|
||||
return;
|
||||
|
||||
LayerType.Update(this, dataModel, preview);
|
||||
LayerAnimation?.Update(this, updateAnimations);
|
||||
|
||||
if (!preview)
|
||||
TweenModel.Update();
|
||||
|
||||
LastRender = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the saved properties to the current properties
|
||||
/// </summary>
|
||||
/// <param name="advanced">Include advanced properties (opacity, brush)</param>
|
||||
public void ApplyProperties(bool advanced)
|
||||
{
|
||||
X = Properties.X;
|
||||
Y = Properties.Y;
|
||||
Width = Properties.Width;
|
||||
Height = Properties.Height;
|
||||
|
||||
if (!advanced)
|
||||
return;
|
||||
|
||||
Opacity = Properties.Opacity;
|
||||
Brush = Properties.Brush;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw the layer using the provided context
|
||||
/// </summary>
|
||||
/// <param name="dataModel"></param>
|
||||
/// <param name="c"></param>
|
||||
/// <param name="preview"></param>
|
||||
/// <param name="updateAnimations"></param>
|
||||
public void Draw(ModuleDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations)
|
||||
{
|
||||
if (Brush == null || !preview && !RenderAllowed)
|
||||
return;
|
||||
|
||||
LayerType.Draw(this, c);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tells the current layer type to setup the layer's LayerProperties
|
||||
/// </summary>
|
||||
public void SetupProperties()
|
||||
{
|
||||
LayerType.SetupProperties(this);
|
||||
|
||||
// If the type is an event, set it up
|
||||
if (IsEvent && EventProperties == null)
|
||||
EventProperties = new KeyboardEventPropertiesModel
|
||||
{
|
||||
ExpirationType = ExpirationType.Time,
|
||||
Length = new TimeSpan(0, 0, 1),
|
||||
TriggerDelay = new TimeSpan(0)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures all child layers have a unique order
|
||||
/// </summary>
|
||||
public void FixOrder()
|
||||
{
|
||||
Children.Sort(l => l.Order);
|
||||
for (var i = 0; i < Children.Count; i++)
|
||||
Children[i].Order = i;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the layer meets the requirements to be drawn in the profile editor
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool MustDraw()
|
||||
{
|
||||
// If any of the parents are disabled, this layer must not be drawn
|
||||
var parent = Parent;
|
||||
while (parent != null)
|
||||
{
|
||||
if (!parent.Enabled)
|
||||
return false;
|
||||
parent = parent.Parent;
|
||||
}
|
||||
return Enabled && LayerType.ShowInEdtor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns every descendant of this layer
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<LayerModel> GetLayers()
|
||||
{
|
||||
var layers = new List<LayerModel>();
|
||||
foreach (var layerModel in Children.OrderBy(c => c.Order))
|
||||
{
|
||||
layers.Add(layerModel);
|
||||
layers.AddRange(layerModel.GetLayers());
|
||||
}
|
||||
|
||||
return layers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Keyboard layer with default settings
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static LayerModel CreateLayer()
|
||||
{
|
||||
return new LayerModel
|
||||
{
|
||||
Name = "New layer",
|
||||
Enabled = true,
|
||||
Order = -1,
|
||||
LayerType = new KeyboardType(),
|
||||
LayerCondition = new DataModelCondition(),
|
||||
LayerAnimation = new NoneAnimation(),
|
||||
Properties = new KeyboardPropertiesModel
|
||||
{
|
||||
Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()),
|
||||
Height = 1,
|
||||
Width = 1,
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Opacity = 1,
|
||||
HeightEaseTime = 0,
|
||||
HeightEase = "Linear",
|
||||
WidthEaseTime = 0,
|
||||
WidthEase = "Linear",
|
||||
OpacityEaseTime = 0,
|
||||
OpacityEase = "Linear"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert this layer before the given layer
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
public void InsertBefore(LayerModel source)
|
||||
{
|
||||
source.Order = Order;
|
||||
Insert(source);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert this layer after the given layer
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
public void InsertAfter(LayerModel source)
|
||||
{
|
||||
source.Order = Order + 1;
|
||||
Insert(source);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert the layer as a sibling
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
private void Insert(LayerModel source)
|
||||
{
|
||||
if (Parent != null)
|
||||
{
|
||||
foreach (var child in Parent.Children.OrderBy(c => c.Order))
|
||||
if (child.Order >= source.Order)
|
||||
child.Order++;
|
||||
Parent.Children.Add(source);
|
||||
}
|
||||
else if (Profile != null)
|
||||
{
|
||||
foreach (var layer in Profile.Layers.OrderBy(l => l.Order))
|
||||
if (layer.Order >= source.Order)
|
||||
layer.Order++;
|
||||
Profile.Layers.Add(source);
|
||||
}
|
||||
}
|
||||
|
||||
public Rect LayerRect(int scale = 4)
|
||||
{
|
||||
var width = Width;
|
||||
var height = Height;
|
||||
if (width < 0)
|
||||
width = 0;
|
||||
if (height < 0)
|
||||
height = 0;
|
||||
|
||||
return new Rect(X * scale, Y * scale, width * scale, height * scale);
|
||||
}
|
||||
|
||||
// TODO: Make this and ProfileModel's GetRenderLayers the same through inheritance
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
/// <param name="dataModel">Instance of said game data model</param>
|
||||
/// <param name="keyboardOnly">Whether or not to ignore anything but keyboards</param>
|
||||
/// <param name="ignoreConditions"></param>
|
||||
/// <returns>A flat list containing all layers that must be rendered</returns>
|
||||
public List<LayerModel> GetRenderLayers(ModuleDataModel dataModel, bool keyboardOnly, bool ignoreConditions = false)
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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;
|
||||
using Artemis.Profiles.Layers.Types.Keyboard;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.ParentChild;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Models
|
||||
{
|
||||
public class LayerModel : IChildItem<LayerModel>, IChildItem<ProfileModel>
|
||||
{
|
||||
public LayerModel()
|
||||
{
|
||||
Children = new ChildItemCollection<LayerModel, LayerModel>(this);
|
||||
TweenModel = new TweenModel(this);
|
||||
RenderAllowed = true;
|
||||
|
||||
var model = Properties as KeyboardPropertiesModel;
|
||||
if (model != null)
|
||||
GifImage = new GifImage(model.GifFile, Properties.AnimationSpeed);
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public ImageSource LayerImage => LayerType.DrawThumbnail(this);
|
||||
|
||||
[JsonIgnore]
|
||||
public TweenModel TweenModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether this layers conditions are met.
|
||||
/// If they are met and this layer is an event, this also triggers that event.
|
||||
/// </summary>
|
||||
/// <param name="dataModel"></param>
|
||||
/// <returns></returns>
|
||||
public bool AreConditionsMet(ModuleDataModel dataModel)
|
||||
{
|
||||
// Conditions are not even checked if the layer isn't enabled
|
||||
return Enabled && LayerCondition.ConditionsMet(this, dataModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the layer
|
||||
/// </summary>
|
||||
/// <param name="dataModel"></param>
|
||||
/// <param name="preview"></param>
|
||||
/// <param name="updateAnimations"></param>
|
||||
public void Update(ModuleDataModel dataModel, bool preview, bool updateAnimations)
|
||||
{
|
||||
if (LayerType == null)
|
||||
return;
|
||||
|
||||
LayerType.Update(this, dataModel, preview);
|
||||
LayerAnimation?.Update(this, updateAnimations);
|
||||
|
||||
if (!preview)
|
||||
TweenModel.Update();
|
||||
|
||||
LastRender = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the saved properties to the current properties
|
||||
/// </summary>
|
||||
/// <param name="advanced">Include advanced properties (opacity, brush)</param>
|
||||
public void ApplyProperties(bool advanced)
|
||||
{
|
||||
X = Properties.X;
|
||||
Y = Properties.Y;
|
||||
Width = Properties.Width;
|
||||
Height = Properties.Height;
|
||||
|
||||
if (!advanced)
|
||||
return;
|
||||
|
||||
Opacity = Properties.Opacity;
|
||||
Brush = Properties.Brush;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw the layer using the provided context
|
||||
/// </summary>
|
||||
/// <param name="dataModel"></param>
|
||||
/// <param name="c"></param>
|
||||
/// <param name="preview"></param>
|
||||
/// <param name="updateAnimations"></param>
|
||||
public void Draw(ModuleDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations)
|
||||
{
|
||||
if (Brush == null || !preview && !RenderAllowed)
|
||||
return;
|
||||
|
||||
LayerType.Draw(this, c);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tells the current layer type to setup the layer's LayerProperties
|
||||
/// </summary>
|
||||
public void SetupProperties()
|
||||
{
|
||||
LayerType.SetupProperties(this);
|
||||
|
||||
// If the type is an event, set it up
|
||||
if (IsEvent && EventProperties == null)
|
||||
EventProperties = new KeyboardEventPropertiesModel
|
||||
{
|
||||
ExpirationType = ExpirationType.Time,
|
||||
Length = new TimeSpan(0, 0, 1),
|
||||
TriggerDelay = new TimeSpan(0)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures all child layers have a unique order
|
||||
/// </summary>
|
||||
public void FixOrder()
|
||||
{
|
||||
Children.Sort(l => l.Order);
|
||||
for (var i = 0; i < Children.Count; i++)
|
||||
Children[i].Order = i;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the layer meets the requirements to be drawn in the profile editor
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool MustDraw()
|
||||
{
|
||||
// If any of the parents are disabled, this layer must not be drawn
|
||||
var parent = Parent;
|
||||
while (parent != null)
|
||||
{
|
||||
if (!parent.Enabled)
|
||||
return false;
|
||||
parent = parent.Parent;
|
||||
}
|
||||
return Enabled && LayerType.ShowInEdtor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns every descendant of this layer
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<LayerModel> GetLayers()
|
||||
{
|
||||
var layers = new List<LayerModel>();
|
||||
foreach (var layerModel in Children.OrderBy(c => c.Order))
|
||||
{
|
||||
layers.Add(layerModel);
|
||||
layers.AddRange(layerModel.GetLayers());
|
||||
}
|
||||
|
||||
return layers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Keyboard layer with default settings
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static LayerModel CreateLayer()
|
||||
{
|
||||
return new LayerModel
|
||||
{
|
||||
Name = "New layer",
|
||||
Enabled = true,
|
||||
Order = -1,
|
||||
LayerType = new KeyboardType(),
|
||||
LayerCondition = new DataModelCondition(),
|
||||
LayerAnimation = new NoneAnimation(),
|
||||
Properties = new KeyboardPropertiesModel
|
||||
{
|
||||
Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()),
|
||||
Height = 1,
|
||||
Width = 1,
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Opacity = 1,
|
||||
HeightEaseTime = 0,
|
||||
HeightEase = "Linear",
|
||||
WidthEaseTime = 0,
|
||||
WidthEase = "Linear",
|
||||
OpacityEaseTime = 0,
|
||||
OpacityEase = "Linear"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert this layer before the given layer
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
public void InsertBefore(LayerModel source)
|
||||
{
|
||||
source.Order = Order;
|
||||
Insert(source);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert this layer after the given layer
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
public void InsertAfter(LayerModel source)
|
||||
{
|
||||
source.Order = Order + 1;
|
||||
Insert(source);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert the layer as a sibling
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
private void Insert(LayerModel source)
|
||||
{
|
||||
if (Parent != null)
|
||||
{
|
||||
foreach (var child in Parent.Children.OrderBy(c => c.Order))
|
||||
if (child.Order >= source.Order)
|
||||
child.Order++;
|
||||
Parent.Children.Add(source);
|
||||
}
|
||||
else if (Profile != null)
|
||||
{
|
||||
foreach (var layer in Profile.Layers.OrderBy(l => l.Order))
|
||||
if (layer.Order >= source.Order)
|
||||
layer.Order++;
|
||||
Profile.Layers.Add(source);
|
||||
}
|
||||
}
|
||||
|
||||
public Rect LayerRect(int scale = 4)
|
||||
{
|
||||
var width = Width;
|
||||
var height = Height;
|
||||
if (width < 0)
|
||||
width = 0;
|
||||
if (height < 0)
|
||||
height = 0;
|
||||
|
||||
return new Rect(X * scale, Y * scale, width * scale, height * scale);
|
||||
}
|
||||
|
||||
// TODO: Make this and ProfileModel's GetRenderLayers the same through inheritance
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
/// <param name="dataModel">Instance of said game data model</param>
|
||||
/// <param name="keyboardOnly">Whether or not to ignore anything but keyboards</param>
|
||||
/// <param name="ignoreConditions"></param>
|
||||
/// <returns>A flat list containing all layers that must be rendered</returns>
|
||||
public List<LayerModel> GetRenderLayers(ModuleDataModel dataModel, bool keyboardOnly, bool ignoreConditions = false)
|
||||
{
|
||||
var layers = new List<LayerModel>();
|
||||
foreach (var layerModel in Children.OrderByDescending(l => l.Order))
|
||||
{
|
||||
@ -272,149 +272,149 @@ namespace Artemis.Profiles.Layers.Models
|
||||
layers.AddRange(layerModel.GetRenderLayers(dataModel, keyboardOnly, ignoreConditions));
|
||||
}
|
||||
|
||||
return layers;
|
||||
}
|
||||
|
||||
public void SetupCondition()
|
||||
{
|
||||
if (IsEvent && !(LayerCondition is EventCondition))
|
||||
LayerCondition = new EventCondition();
|
||||
else if (!IsEvent && !(LayerCondition is DataModelCondition))
|
||||
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
|
||||
|
||||
public ILayerType LayerType { get; set; }
|
||||
public ILayerCondition LayerCondition { get; set; }
|
||||
public ILayerAnimation LayerAnimation { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Generic properties
|
||||
|
||||
public string Name { get; set; }
|
||||
public int Order { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public bool RenderAllowed { get; set; }
|
||||
public bool Expanded { get; set; }
|
||||
public bool IsEvent { get; set; }
|
||||
public LayerPropertiesModel Properties { get; set; }
|
||||
public EventPropertiesModel EventProperties { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Relational properties
|
||||
|
||||
public ChildItemCollection<LayerModel, LayerModel> Children { get; }
|
||||
|
||||
[JsonIgnore]
|
||||
public LayerModel Parent { get; internal set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public ProfileModel Profile { get; internal set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Render properties
|
||||
|
||||
[JsonIgnore] private Brush _brush;
|
||||
|
||||
[JsonIgnore]
|
||||
public double X { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public double Y { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public double Width { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public double Height { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public double Opacity { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Brush Brush
|
||||
{
|
||||
get { return _brush; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
_brush = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.IsFrozen)
|
||||
{
|
||||
_brush = value;
|
||||
return;
|
||||
}
|
||||
|
||||
// Clone the brush off of the UI thread and freeze it
|
||||
var cloned = value.Dispatcher.Invoke(value.CloneCurrentValue);
|
||||
cloned.Freeze();
|
||||
_brush = cloned;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public double AnimationProgress { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public GifImage GifImage { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public DateTime LastRender { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region IChildItem<Parent> Members
|
||||
|
||||
LayerModel IChildItem<LayerModel>.Parent
|
||||
{
|
||||
get { return Parent; }
|
||||
set { Parent = value; }
|
||||
}
|
||||
|
||||
ProfileModel IChildItem<ProfileModel>.Parent
|
||||
{
|
||||
get { return Profile; }
|
||||
set { Profile = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{nameof(Name)}: {Name}, {nameof(Order)}: {Order}, {nameof(X)}: {X}, {nameof(Y)}: {Y}, {nameof(Width)}: {Width}, {nameof(Height)}: {Height}";
|
||||
}
|
||||
}
|
||||
}
|
||||
return layers;
|
||||
}
|
||||
|
||||
public void SetupCondition()
|
||||
{
|
||||
if (IsEvent && !(LayerCondition is EventCondition))
|
||||
LayerCondition = new EventCondition();
|
||||
else if (!IsEvent && !(LayerCondition is DataModelCondition))
|
||||
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
|
||||
|
||||
public ILayerType LayerType { get; set; }
|
||||
public ILayerCondition LayerCondition { get; set; }
|
||||
public ILayerAnimation LayerAnimation { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Generic properties
|
||||
|
||||
public string Name { get; set; }
|
||||
public int Order { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public bool RenderAllowed { get; set; }
|
||||
public bool Expanded { get; set; }
|
||||
public bool IsEvent { get; set; }
|
||||
public LayerPropertiesModel Properties { get; set; }
|
||||
public EventPropertiesModel EventProperties { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Relational properties
|
||||
|
||||
public ChildItemCollection<LayerModel, LayerModel> Children { get; }
|
||||
|
||||
[JsonIgnore]
|
||||
public LayerModel Parent { get; internal set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public ProfileModel Profile { get; internal set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Render properties
|
||||
|
||||
[JsonIgnore] private Brush _brush;
|
||||
|
||||
[JsonIgnore]
|
||||
public double X { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public double Y { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public double Width { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public double Height { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public double Opacity { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Brush Brush
|
||||
{
|
||||
get { return _brush; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
_brush = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.IsFrozen)
|
||||
{
|
||||
_brush = value;
|
||||
return;
|
||||
}
|
||||
|
||||
// Clone the brush off of the UI thread and freeze it
|
||||
var cloned = value.Dispatcher.Invoke(value.CloneCurrentValue);
|
||||
cloned.Freeze();
|
||||
_brush = cloned;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public double AnimationProgress { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public GifImage GifImage { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public DateTime LastRender { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region IChildItem<Parent> Members
|
||||
|
||||
LayerModel IChildItem<LayerModel>.Parent
|
||||
{
|
||||
get { return Parent; }
|
||||
set { Parent = value; }
|
||||
}
|
||||
|
||||
ProfileModel IChildItem<ProfileModel>.Parent
|
||||
{
|
||||
get { return Profile; }
|
||||
set { Profile = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{nameof(Name)}: {Name}, {nameof(Order)}: {Order}, {nameof(X)}: {X}, {nameof(Y)}: {Y}, {nameof(Width)}: {Width}, {nameof(Height)}: {Height}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,95 +1,95 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Utilities.Converters;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Models
|
||||
{
|
||||
public abstract class LayerPropertiesModel
|
||||
{
|
||||
private Brush _brush;
|
||||
|
||||
public LayerPropertiesModel(LayerPropertiesModel source = null)
|
||||
{
|
||||
if (source == null)
|
||||
return;
|
||||
|
||||
// Clone the source's properties onto the new properties model (useful when changing property type)
|
||||
X = source.X;
|
||||
Y = source.Y;
|
||||
Width = source.Width;
|
||||
Height = source.Height;
|
||||
Contain = source.Contain;
|
||||
Opacity = source.Opacity;
|
||||
AnimationSpeed = source.AnimationSpeed;
|
||||
Conditions = source.Conditions;
|
||||
LayerKeybindModels = source.LayerKeybindModels;
|
||||
ConditionType = source.ConditionType;
|
||||
DynamicProperties = source.DynamicProperties;
|
||||
Brush = source.Brush;
|
||||
HeightEase = source.HeightEase;
|
||||
WidthEase = source.WidthEase;
|
||||
OpacityEase = source.OpacityEase;
|
||||
HeightEaseTime = source.HeightEaseTime;
|
||||
WidthEaseTime = source.WidthEaseTime;
|
||||
OpacityEaseTime = source.OpacityEaseTime;
|
||||
}
|
||||
|
||||
public double X { get; set; }
|
||||
public double Y { get; set; }
|
||||
public double Width { get; set; }
|
||||
public double Height { get; set; }
|
||||
public bool Contain { get; set; }
|
||||
public double Opacity { get; set; }
|
||||
public double AnimationSpeed { get; set; }
|
||||
public double OpacityEaseTime { get; set; }
|
||||
public double HeightEaseTime { get; set; }
|
||||
public double WidthEaseTime { get; set; }
|
||||
public string WidthEase { set; get; }
|
||||
public string HeightEase { get; set; }
|
||||
public string OpacityEase { get; set; }
|
||||
public ConditionType ConditionType { get; set; }
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Utilities.Converters;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Models
|
||||
{
|
||||
public abstract class LayerPropertiesModel
|
||||
{
|
||||
private Brush _brush;
|
||||
|
||||
public LayerPropertiesModel(LayerPropertiesModel source = null)
|
||||
{
|
||||
if (source == null)
|
||||
return;
|
||||
|
||||
// Clone the source's properties onto the new properties model (useful when changing property type)
|
||||
X = source.X;
|
||||
Y = source.Y;
|
||||
Width = source.Width;
|
||||
Height = source.Height;
|
||||
Contain = source.Contain;
|
||||
Opacity = source.Opacity;
|
||||
AnimationSpeed = source.AnimationSpeed;
|
||||
Conditions = source.Conditions;
|
||||
LayerKeybindModels = source.LayerKeybindModels;
|
||||
ConditionType = source.ConditionType;
|
||||
DynamicProperties = source.DynamicProperties;
|
||||
Brush = source.Brush;
|
||||
HeightEase = source.HeightEase;
|
||||
WidthEase = source.WidthEase;
|
||||
OpacityEase = source.OpacityEase;
|
||||
HeightEaseTime = source.HeightEaseTime;
|
||||
WidthEaseTime = source.WidthEaseTime;
|
||||
OpacityEaseTime = source.OpacityEaseTime;
|
||||
}
|
||||
|
||||
public double X { get; set; }
|
||||
public double Y { get; set; }
|
||||
public double Width { get; set; }
|
||||
public double Height { get; set; }
|
||||
public bool Contain { get; set; }
|
||||
public double Opacity { get; set; }
|
||||
public double AnimationSpeed { get; set; }
|
||||
public double OpacityEaseTime { get; set; }
|
||||
public double HeightEaseTime { get; set; }
|
||||
public double WidthEaseTime { get; set; }
|
||||
public string WidthEase { set; get; }
|
||||
public string HeightEase { get; set; }
|
||||
public string OpacityEase { get; set; }
|
||||
public ConditionType ConditionType { get; set; }
|
||||
public List<LayerConditionModel> Conditions { get; set; } = new List<LayerConditionModel>();
|
||||
public List<LayerKeybindModel> LayerKeybindModels { get; set; } = new List<LayerKeybindModel>();
|
||||
public List<DynamicPropertiesModel> DynamicProperties { get; set; } = new List<DynamicPropertiesModel>();
|
||||
|
||||
[JsonConverter(typeof(BrushJsonConverter))]
|
||||
public Brush Brush
|
||||
{
|
||||
get { return _brush; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
_brush = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.IsFrozen)
|
||||
{
|
||||
_brush = value;
|
||||
return;
|
||||
}
|
||||
|
||||
// Clone the brush off of the UI thread and freeze it
|
||||
var cloned = value.Dispatcher.Invoke(value.CloneCurrentValue);
|
||||
cloned.Freeze();
|
||||
_brush = cloned;
|
||||
}
|
||||
}
|
||||
|
||||
public Rect PropertiesRect(int scale = 4)
|
||||
{
|
||||
return new Rect(X*scale, Y*scale, Width*scale, Height*scale);
|
||||
}
|
||||
}
|
||||
|
||||
public enum ConditionType
|
||||
{
|
||||
[Description("All met")] AllMet,
|
||||
[Description("Any met")] AnyMet,
|
||||
[Description("None met")] NoneMet
|
||||
}
|
||||
public List<LayerKeybindModel> LayerKeybindModels { get; set; } = new List<LayerKeybindModel>();
|
||||
public List<DynamicPropertiesModel> DynamicProperties { get; set; } = new List<DynamicPropertiesModel>();
|
||||
|
||||
[JsonConverter(typeof(BrushJsonConverter))]
|
||||
public Brush Brush
|
||||
{
|
||||
get { return _brush; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
_brush = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.IsFrozen)
|
||||
{
|
||||
_brush = value;
|
||||
return;
|
||||
}
|
||||
|
||||
// Clone the brush off of the UI thread and freeze it
|
||||
var cloned = value.Dispatcher.Invoke(value.CloneCurrentValue);
|
||||
cloned.Freeze();
|
||||
_brush = cloned;
|
||||
}
|
||||
}
|
||||
|
||||
public Rect PropertiesRect(int scale = 4)
|
||||
{
|
||||
return new Rect(X*scale, Y*scale, Width*scale, Height*scale);
|
||||
}
|
||||
}
|
||||
|
||||
public enum ConditionType
|
||||
{
|
||||
[Description("All met")] AllMet,
|
||||
[Description("Any met")] AnyMet,
|
||||
[Description("None met")] NoneMet
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Media;
|
||||
using Microsoft.Win32;
|
||||
using SharpDX.Direct3D9;
|
||||
|
||||
namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing
|
||||
@ -15,6 +16,14 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing
|
||||
Width = Screen.PrimaryScreen.Bounds.Width;
|
||||
Height = Screen.PrimaryScreen.Bounds.Height;
|
||||
|
||||
//DarthAffe 08.04.2017: Fix for systems using windows-scaling. The primary screen size is reported 'wrong'.
|
||||
double scaling = GetScaling();
|
||||
if (Math.Abs(scaling - 1.0) > 0.01)
|
||||
{
|
||||
Width = (int)(Width / scaling);
|
||||
Height = (int)(Height / scaling);
|
||||
}
|
||||
|
||||
var presentParams = new PresentParameters(Width, Height)
|
||||
{
|
||||
Windowed = true,
|
||||
@ -24,7 +33,7 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing
|
||||
_device = new Device(new Direct3D(), 0, DeviceType.Hardware, IntPtr.Zero,
|
||||
CreateFlags.SoftwareVertexProcessing, presentParams);
|
||||
_surface = Surface.CreateOffscreenPlain(_device, Width, Height, Format.A8R8G8B8, Pool.Scratch);
|
||||
_buffer = new byte[Width*Height*4];
|
||||
_buffer = new byte[Width * Height * 4];
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -43,6 +52,19 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing
|
||||
|
||||
#region Methods
|
||||
|
||||
private double GetScaling()
|
||||
{
|
||||
try
|
||||
{
|
||||
int currentDpi = (int)Registry.GetValue("HKEY_CURRENT_USER\\Control Panel\\Desktop", "LogPixels", 96);
|
||||
return 96.0 / currentDpi;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] CaptureScreen()
|
||||
{
|
||||
_device.GetFrontBufferData(0, _surface);
|
||||
|
||||
@ -97,18 +97,23 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
|
||||
}
|
||||
}
|
||||
|
||||
private LineSpectrum _lineSpectrum;
|
||||
public LineSpectrum GetLineSpectrum(int barCount, ScalingStrategy scalingStrategy)
|
||||
{
|
||||
if (_spectrumProvider == null)
|
||||
if (_spectrumProvider == null || barCount <= 0)
|
||||
return null;
|
||||
return new LineSpectrum(FftSize)
|
||||
{
|
||||
SpectrumProvider = _spectrumProvider,
|
||||
UseAverage = true,
|
||||
BarCount = barCount,
|
||||
IsXLogScale = true,
|
||||
ScalingStrategy = scalingStrategy
|
||||
};
|
||||
|
||||
if (_lineSpectrum == null)
|
||||
_lineSpectrum = new LineSpectrum(FftSize)
|
||||
{
|
||||
SpectrumProvider = _spectrumProvider,
|
||||
UseAverage = true,
|
||||
BarCount = barCount,
|
||||
IsXLogScale = true,
|
||||
ScalingStrategy = scalingStrategy
|
||||
};
|
||||
|
||||
return _lineSpectrum;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -148,13 +153,13 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
|
||||
if (Type == MmDeviceType.Input)
|
||||
{
|
||||
_soundIn = Device != null
|
||||
? new WasapiCapture {Device = Device}
|
||||
? new WasapiCapture { Device = Device }
|
||||
: new WasapiCapture();
|
||||
}
|
||||
else
|
||||
{
|
||||
_soundIn = Device != null
|
||||
? new WasapiLoopbackCapture {Device = Device}
|
||||
? new WasapiLoopbackCapture { Device = Device }
|
||||
: new WasapiLoopbackCapture();
|
||||
}
|
||||
|
||||
@ -182,6 +187,7 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
|
||||
}
|
||||
};
|
||||
|
||||
_lineSpectrum = null;
|
||||
_singleSpectrum = new SingleSpectrum(FftSize, _spectrumProvider);
|
||||
_mayStop = false;
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
@ -26,6 +27,7 @@ namespace Artemis.Profiles.Layers.Types.Audio
|
||||
private List<double> _lineValues;
|
||||
private AudioPropertiesModel _properties;
|
||||
private bool _subscribed;
|
||||
private DateTime _lastRender;
|
||||
|
||||
public AudioType(AudioCaptureManager audioCaptureManager)
|
||||
{
|
||||
@ -123,8 +125,7 @@ namespace Artemis.Profiles.Layers.Types.Audio
|
||||
|
||||
SubscribeToAudioChange();
|
||||
|
||||
if (_audioCapture == null || newProperties.Device != _properties.Device ||
|
||||
newProperties.DeviceType != _properties.DeviceType)
|
||||
if (_audioCapture == null || newProperties.Device != _properties.Device || newProperties.DeviceType != _properties.DeviceType)
|
||||
{
|
||||
var device = GetMmDevice();
|
||||
if (device != null)
|
||||
@ -153,17 +154,19 @@ namespace Artemis.Profiles.Layers.Types.Audio
|
||||
currentHeight = layerModel.Width;
|
||||
}
|
||||
|
||||
if (_lines != currentLines || _lineSpectrum == null)
|
||||
// Get a new line spectrum if the lines changed, it is null or the layer hasn't rendered for a few frames
|
||||
if (_lines != currentLines || _lineSpectrum == null || DateTime.Now - _lastRender > TimeSpan.FromMilliseconds(100))
|
||||
{
|
||||
_lines = currentLines;
|
||||
_lineSpectrum = _audioCapture.GetLineSpectrum(_lines, ScalingStrategy.Decibel);
|
||||
if (_lineSpectrum == null)
|
||||
return;
|
||||
}
|
||||
|
||||
var newLineValues = _lineSpectrum?.GetLineValues(currentHeight);
|
||||
|
||||
var newLineValues = _audioCapture.GetLineSpectrum(_lines, ScalingStrategy.Decibel)?.GetLineValues(currentHeight);
|
||||
if (newLineValues != null)
|
||||
{
|
||||
_lineValues = newLineValues;
|
||||
_lastRender = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetupProperties(LayerModel layerModel)
|
||||
|
||||
25
Artemis/Artemis/Profiles/Lua/Modules/Gui/EditorButton.cs
Normal file
25
Artemis/Artemis/Profiles/Lua/Modules/Gui/EditorButton.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using Artemis.Managers;
|
||||
using MoonSharp.Interpreter;
|
||||
|
||||
namespace Artemis.Profiles.Lua.Modules.Gui
|
||||
{
|
||||
public class EditorButton
|
||||
{
|
||||
private readonly LuaManager _luaManager;
|
||||
|
||||
public EditorButton(LuaManager luaManager, string text, DynValue action)
|
||||
{
|
||||
_luaManager = luaManager;
|
||||
Text = text;
|
||||
Action = action;
|
||||
}
|
||||
|
||||
public void Invoke()
|
||||
{
|
||||
_luaManager.Call(Action);
|
||||
}
|
||||
|
||||
public string Text { get; }
|
||||
public DynValue Action { get; }
|
||||
}
|
||||
}
|
||||
49
Artemis/Artemis/Profiles/Lua/Modules/Gui/LuaButton.cs
Normal file
49
Artemis/Artemis/Profiles/Lua/Modules/Gui/LuaButton.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Artemis.Managers;
|
||||
using MoonSharp.Interpreter;
|
||||
using MoonSharp.Interpreter.Interop;
|
||||
|
||||
namespace Artemis.Profiles.Lua.Modules.Gui
|
||||
{
|
||||
[MoonSharpUserData]
|
||||
public class LuaButton
|
||||
{
|
||||
private readonly LuaManager _luaManager;
|
||||
|
||||
public LuaButton(LuaManager luaManager, string text, double x, double y, double? width, double? height)
|
||||
{
|
||||
_luaManager = luaManager;
|
||||
|
||||
Button = new Button {Content = text};
|
||||
if (width != null)
|
||||
Button.Width = width.Value;
|
||||
if (height != null)
|
||||
Button.Height = height.Value;
|
||||
|
||||
Button.Click += ButtonOnClick;
|
||||
}
|
||||
|
||||
[MoonSharpVisible(false)]
|
||||
public Button Button { get; }
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => Button.Dispatcher.Invoke(() => (string) Button.Content);
|
||||
set => Button.Dispatcher.Invoke(() => Button.Content = value);
|
||||
}
|
||||
|
||||
private void ButtonOnClick(object sender, RoutedEventArgs routedEventArgs)
|
||||
{
|
||||
_luaManager.EventsModule.LuaInvoke(_luaManager.ProfileModel, () => OnClick(this));
|
||||
}
|
||||
|
||||
public event EventHandler<EventArgs> Click;
|
||||
|
||||
protected virtual void OnClick(LuaButton button)
|
||||
{
|
||||
Click?.Invoke(button, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
55
Artemis/Artemis/Profiles/Lua/Modules/Gui/LuaCheckBox.cs
Normal file
55
Artemis/Artemis/Profiles/Lua/Modules/Gui/LuaCheckBox.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Artemis.Managers;
|
||||
using MoonSharp.Interpreter;
|
||||
using MoonSharp.Interpreter.Interop;
|
||||
|
||||
namespace Artemis.Profiles.Lua.Modules.Gui
|
||||
{
|
||||
[MoonSharpUserData]
|
||||
public class LuaCheckBox
|
||||
{
|
||||
private readonly LuaManager _luaManager;
|
||||
|
||||
public LuaCheckBox(LuaManager luaManager, string text, bool isChecked, double x, double y, double? width, double? height)
|
||||
{
|
||||
_luaManager = luaManager;
|
||||
|
||||
CheckBox = new CheckBox {Content = text, IsChecked = isChecked};
|
||||
if (width != null)
|
||||
CheckBox.Width = width.Value;
|
||||
if (height != null)
|
||||
CheckBox.Height = height.Value;
|
||||
|
||||
CheckBox.Click += CheckBoxOnClick;
|
||||
}
|
||||
|
||||
[MoonSharpVisible(false)]
|
||||
public CheckBox CheckBox { get; }
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => CheckBox.Dispatcher.Invoke(() => (string) CheckBox.Content);
|
||||
set => CheckBox.Dispatcher.Invoke(() => CheckBox.Content = value);
|
||||
}
|
||||
|
||||
public bool IsChecked
|
||||
{
|
||||
get => CheckBox.Dispatcher.Invoke(() => CheckBox.IsChecked != null && (bool) CheckBox.IsChecked);
|
||||
set => CheckBox.Dispatcher.Invoke(() => CheckBox.IsChecked = value);
|
||||
}
|
||||
|
||||
private void CheckBoxOnClick(object sender, RoutedEventArgs routedEventArgs)
|
||||
{
|
||||
_luaManager.EventsModule.LuaInvoke(_luaManager.ProfileModel, () => OnClick(this));
|
||||
}
|
||||
|
||||
public event EventHandler<EventArgs> Click;
|
||||
|
||||
protected virtual void OnClick(LuaCheckBox checkBox)
|
||||
{
|
||||
Click?.Invoke(checkBox, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
70
Artemis/Artemis/Profiles/Lua/Modules/Gui/LuaComboBox.cs
Normal file
70
Artemis/Artemis/Profiles/Lua/Modules/Gui/LuaComboBox.cs
Normal file
@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows.Controls;
|
||||
using Artemis.Managers;
|
||||
using MoonSharp.Interpreter;
|
||||
using MoonSharp.Interpreter.Interop;
|
||||
|
||||
namespace Artemis.Profiles.Lua.Modules.Gui
|
||||
{
|
||||
[MoonSharpUserData]
|
||||
public class LuaComboBox
|
||||
{
|
||||
private readonly LuaManager _luaManager;
|
||||
|
||||
public LuaComboBox(LuaManager luaManager, string value, List<string> values, double x, double y, double? width, double? height)
|
||||
{
|
||||
_luaManager = luaManager;
|
||||
|
||||
ComboBox = new ComboBox {ItemsSource = new ObservableCollection<string>(values), SelectedItem = value};
|
||||
if (width != null)
|
||||
ComboBox.Width = (double) width;
|
||||
if (height != null)
|
||||
ComboBox.Height = (double) height;
|
||||
|
||||
ComboBox.SelectionChanged += ComboBoxOnSelectionChanged;
|
||||
}
|
||||
|
||||
[MoonSharpVisible(false)]
|
||||
public ComboBox ComboBox { get; }
|
||||
|
||||
public string Value
|
||||
{
|
||||
get => ComboBox.Dispatcher.Invoke(() => (string) ComboBox.SelectedItem);
|
||||
set => ComboBox.Dispatcher.Invoke(() => ComboBox.SelectedItem = value);
|
||||
}
|
||||
|
||||
public void SetValues(string[] values)
|
||||
{
|
||||
var collection = (ObservableCollection<string>) ComboBox.ItemsSource;
|
||||
collection.Clear();
|
||||
foreach (var value in values)
|
||||
collection.Add(value);
|
||||
}
|
||||
|
||||
public void AddValue(string value)
|
||||
{
|
||||
((ObservableCollection<string>) ComboBox.ItemsSource).Add(value);
|
||||
}
|
||||
|
||||
public void RemoveValue(string value)
|
||||
{
|
||||
var collection = (ObservableCollection<string>) ComboBox.ItemsSource;
|
||||
if (collection.Contains(value))
|
||||
collection.Remove(value);
|
||||
}
|
||||
|
||||
private void ComboBoxOnSelectionChanged(object sender, SelectionChangedEventArgs selectionChangedEventArgs)
|
||||
{
|
||||
_luaManager.EventsModule.LuaInvoke(_luaManager.ProfileModel, () => OnSelectionChanged(this));
|
||||
}
|
||||
|
||||
public event EventHandler<EventArgs> SelectionChanged;
|
||||
|
||||
protected virtual void OnSelectionChanged(LuaComboBox comboBox)
|
||||
{
|
||||
SelectionChanged?.Invoke(comboBox, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Artemis/Artemis/Profiles/Lua/Modules/Gui/LuaLabel.cs
Normal file
30
Artemis/Artemis/Profiles/Lua/Modules/Gui/LuaLabel.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using MoonSharp.Interpreter;
|
||||
using MoonSharp.Interpreter.Interop;
|
||||
|
||||
namespace Artemis.Profiles.Lua.Modules.Gui
|
||||
{
|
||||
[MoonSharpUserData]
|
||||
public class LuaLabel
|
||||
{
|
||||
public LuaLabel(string text, double x, double y, double fontSize = 12, int fontWeight = 400)
|
||||
{
|
||||
Label = new Label
|
||||
{
|
||||
Content = text,
|
||||
FontSize = fontSize,
|
||||
FontWeight = FontWeight.FromOpenTypeWeight(fontWeight)
|
||||
};
|
||||
}
|
||||
|
||||
[MoonSharpVisible(false)]
|
||||
public Label Label { get; }
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => Label.Dispatcher.Invoke(() => (string) Label.Content);
|
||||
set => Label.Dispatcher.Invoke(() => Label.Content = value);
|
||||
}
|
||||
}
|
||||
}
|
||||
48
Artemis/Artemis/Profiles/Lua/Modules/Gui/LuaTextBox.cs
Normal file
48
Artemis/Artemis/Profiles/Lua/Modules/Gui/LuaTextBox.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
using Artemis.Managers;
|
||||
using MoonSharp.Interpreter;
|
||||
using MoonSharp.Interpreter.Interop;
|
||||
|
||||
namespace Artemis.Profiles.Lua.Modules.Gui
|
||||
{
|
||||
[MoonSharpUserData]
|
||||
public class LuaTextBox
|
||||
{
|
||||
private readonly LuaManager _luaManager;
|
||||
|
||||
public LuaTextBox(LuaManager luaManager, string text, double x, double y, double? width, double? height)
|
||||
{
|
||||
_luaManager = luaManager;
|
||||
|
||||
TextBox = new TextBox {Text = text};
|
||||
if (width != null)
|
||||
TextBox.Width = width.Value;
|
||||
if (height != null)
|
||||
TextBox.Height = height.Value;
|
||||
|
||||
TextBox.TextChanged += TextBoxOnTextChanged;
|
||||
}
|
||||
|
||||
[MoonSharpVisible(false)]
|
||||
public TextBox TextBox { get; }
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => TextBox.Dispatcher.Invoke(() => TextBox.Text);
|
||||
set => TextBox.Dispatcher.Invoke(() => TextBox.Text = value);
|
||||
}
|
||||
|
||||
private void TextBoxOnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
|
||||
{
|
||||
_luaManager.EventsModule.LuaInvoke(_luaManager.ProfileModel, () => OnTextChanged(this));
|
||||
}
|
||||
|
||||
public event EventHandler<EventArgs> TextChanged;
|
||||
|
||||
protected virtual void OnTextChanged(LuaTextBox button)
|
||||
{
|
||||
TextChanged?.Invoke(button, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
<controls:MetroWindow x:Class="Artemis.Profiles.Lua.Modules.Gui.LuaWindowView" 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:local="clr-namespace:Artemis.Profiles.Lua.Modules.Gui"
|
||||
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls" mc:Ignorable="d" Title="LuaWindowView" Height="300" Width="300" WindowStartupLocation="CenterScreen"
|
||||
GlowBrush="{DynamicResource AccentColorBrush}">
|
||||
<Grid>
|
||||
<ItemsControl ItemsSource="{Binding Path=Content}" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" />
|
||||
</Grid>
|
||||
</controls:MetroWindow>
|
||||
@ -0,0 +1,15 @@
|
||||
using MahApps.Metro.Controls;
|
||||
|
||||
namespace Artemis.Profiles.Lua.Modules.Gui
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for LuaWindowView.xaml
|
||||
/// </summary>
|
||||
public partial class LuaWindowView : MetroWindow
|
||||
{
|
||||
public LuaWindowView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,93 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Artemis.Managers;
|
||||
using Caliburn.Micro;
|
||||
using MoonSharp.Interpreter;
|
||||
|
||||
namespace Artemis.Profiles.Lua.Modules.Gui
|
||||
{
|
||||
[MoonSharpUserData]
|
||||
public class LuaWindowViewModel : Screen
|
||||
{
|
||||
private readonly LuaManager _luaManager;
|
||||
|
||||
public LuaWindowViewModel(LuaManager luaManager)
|
||||
{
|
||||
_luaManager = luaManager;
|
||||
|
||||
Canvas = new Canvas();
|
||||
Content = new List<UIElement> {Canvas};
|
||||
}
|
||||
|
||||
public Canvas Canvas { get; set; }
|
||||
public List<UIElement> Content { get; set; }
|
||||
|
||||
public LuaLabel CreateLabel(string text, double x, double y, double fontSize = 12, int fontWeight = 400)
|
||||
{
|
||||
LuaLabel element = null;
|
||||
Execute.OnUIThread(() =>
|
||||
{
|
||||
element = new LuaLabel(text, x, y, fontSize, fontWeight);
|
||||
AddControl(element.Label, x, y);
|
||||
});
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public LuaButton CreateButton(string text, double x, double y, double? width, double? height)
|
||||
{
|
||||
LuaButton element = null;
|
||||
Execute.OnUIThread(() =>
|
||||
{
|
||||
element = new LuaButton(_luaManager, text, x, y, width, height);
|
||||
AddControl(element.Button, x, y);
|
||||
});
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public LuaTextBox CreateTextBox(string text, double x, double y, double? width, double? height)
|
||||
{
|
||||
LuaTextBox element = null;
|
||||
Execute.OnUIThread(() =>
|
||||
{
|
||||
element = new LuaTextBox(_luaManager, text, x, y, width, height);
|
||||
AddControl(element.TextBox, x, y);
|
||||
});
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public LuaComboBox CreateComboBox(string value, List<string> values, double x, double y, double? width, double? height)
|
||||
{
|
||||
LuaComboBox element = null;
|
||||
Execute.OnUIThread(() =>
|
||||
{
|
||||
element = new LuaComboBox(_luaManager, value, values, x, y, width, height);
|
||||
AddControl(element.ComboBox, x, y);
|
||||
});
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public LuaCheckBox CreateCheckBox(string text, bool isChecked, double x, double y, double? width, double? height)
|
||||
{
|
||||
LuaCheckBox element = null;
|
||||
Execute.OnUIThread(() =>
|
||||
{
|
||||
element = new LuaCheckBox(_luaManager, text, isChecked, x, y, width, height);
|
||||
AddControl(element.CheckBox, x, y);
|
||||
});
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
private void AddControl(UIElement uiElement, double x, double y)
|
||||
{
|
||||
Canvas.Children.Add(uiElement);
|
||||
Canvas.SetLeft(uiElement, x);
|
||||
Canvas.SetTop(uiElement, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -73,7 +73,7 @@ namespace Artemis.Profiles.Lua.Modules
|
||||
}
|
||||
}
|
||||
|
||||
private void LuaInvoke(ProfileModel profileModel, Action action)
|
||||
public void LuaInvoke(ProfileModel profileModel, Action action)
|
||||
{
|
||||
lock (InvokeLock)
|
||||
{
|
||||
|
||||
64
Artemis/Artemis/Profiles/Lua/Modules/LuaGuiModule.cs
Normal file
64
Artemis/Artemis/Profiles/Lua/Modules/LuaGuiModule.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Profiles.Lua.Modules.Gui;
|
||||
using Artemis.Services;
|
||||
using Caliburn.Micro;
|
||||
using MoonSharp.Interpreter;
|
||||
using Ninject.Parameters;
|
||||
|
||||
namespace Artemis.Profiles.Lua.Modules
|
||||
{
|
||||
[MoonSharpUserData]
|
||||
public class LuaGuiModule : LuaModule
|
||||
{
|
||||
private readonly WindowService _windowService;
|
||||
private readonly List<LuaWindowViewModel> _windows;
|
||||
|
||||
public LuaGuiModule(LuaManager luaManager, WindowService windowService) : base(luaManager)
|
||||
{
|
||||
_windowService = windowService;
|
||||
_windows = new List<LuaWindowViewModel>();
|
||||
}
|
||||
|
||||
public override string ModuleName => "Gui";
|
||||
|
||||
public LuaWindowViewModel CreateWindow(string title, double width, double height)
|
||||
{
|
||||
lock (_windows)
|
||||
{
|
||||
dynamic settings = new ExpandoObject();
|
||||
settings.Width = width;
|
||||
settings.Height = height;
|
||||
IParameter[] args =
|
||||
{
|
||||
new ConstructorArgument("luaManager", LuaManager)
|
||||
};
|
||||
|
||||
Execute.OnUIThread(() => _windows.Add(_windowService.ShowWindow<LuaWindowViewModel>("Artemis | " + title, settings, args)));
|
||||
return _windows.Last();
|
||||
}
|
||||
}
|
||||
|
||||
public void AddEditorButton(string name, DynValue action)
|
||||
{
|
||||
Execute.OnUIThread(() => LuaManager.EditorButtons.Add(new EditorButton(LuaManager, name, action)));
|
||||
}
|
||||
|
||||
public void RemoveEditorButton(string name)
|
||||
{
|
||||
var button = LuaManager.EditorButtons.FirstOrDefault(b => b.Text == name);
|
||||
if (button != null)
|
||||
Execute.OnUIThread(() => LuaManager.EditorButtons.Remove(button));
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
foreach (var window in _windows)
|
||||
window.TryClose();
|
||||
|
||||
Execute.OnUIThread(() => LuaManager.EditorButtons.Clear());
|
||||
}
|
||||
}
|
||||
}
|
||||
68
Artemis/Artemis/Profiles/Lua/Modules/LuaStorageModule.cs
Normal file
68
Artemis/Artemis/Profiles/Lua/Modules/LuaStorageModule.cs
Normal file
@ -0,0 +1,68 @@
|
||||
using Artemis.DAL;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Settings;
|
||||
using MoonSharp.Interpreter;
|
||||
using static MoonSharp.Interpreter.Serialization.Json.JsonTableConverter;
|
||||
|
||||
namespace Artemis.Profiles.Lua.Modules
|
||||
{
|
||||
[MoonSharpUserData]
|
||||
public class LuaStorageModule : LuaModule
|
||||
{
|
||||
private readonly Table _globalValues;
|
||||
private readonly Table _profileValues;
|
||||
private readonly LuaGlobalSettings _globalSettings;
|
||||
|
||||
public LuaStorageModule(LuaManager luaManager) : base(luaManager)
|
||||
{
|
||||
_globalSettings = SettingsProvider.Load<LuaGlobalSettings>();
|
||||
|
||||
// Load profile values
|
||||
if (LuaManager.ProfileModel.LuaStorage != null)
|
||||
_profileValues = JsonToTable(LuaManager.ProfileModel.LuaStorage, LuaManager.LuaScript);
|
||||
else
|
||||
_profileValues = new Table(LuaManager.LuaScript);
|
||||
|
||||
// Load global values
|
||||
if (_globalSettings.GlobalValues != null)
|
||||
_globalValues = JsonToTable(_globalSettings.GlobalValues, LuaManager.LuaScript);
|
||||
else
|
||||
_globalValues = new Table(LuaManager.LuaScript);
|
||||
|
||||
// Set the values onto the globals table so scripters can access them
|
||||
LuaManager.LuaScript.Globals["ProfileStorage"] = _profileValues;
|
||||
LuaManager.LuaScript.Globals["GlobalStorage"] = _globalValues;
|
||||
}
|
||||
|
||||
public override string ModuleName => null;
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
// Store profile values
|
||||
LuaManager.ProfileModel.LuaStorage = _profileValues.TableToJson();
|
||||
ProfileProvider.AddOrUpdate(LuaManager.ProfileModel);
|
||||
|
||||
// Store global values
|
||||
_globalSettings.GlobalValues = _globalValues.TableToJson();
|
||||
_globalSettings.Save();
|
||||
}
|
||||
}
|
||||
|
||||
public class LuaGlobalSettings : IArtemisSettings
|
||||
{
|
||||
public string GlobalValues { get; set; }
|
||||
|
||||
public void Save()
|
||||
{
|
||||
SettingsProvider.Save(this);
|
||||
}
|
||||
|
||||
public void Reset(bool save = false)
|
||||
{
|
||||
GlobalValues = null;
|
||||
|
||||
if (save)
|
||||
Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -38,6 +38,7 @@ namespace Artemis.Profiles
|
||||
public int Width { get; set; }
|
||||
public int Height { get; set; }
|
||||
public string LuaScript { get; set; }
|
||||
public string LuaStorage { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string Slug => new string(Name.Where(ch => !_invalidFileNameChars.Contains(ch)).ToArray());
|
||||
|
||||
@ -53,7 +53,7 @@ using System.Windows;
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyVersion("1.9.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.9.0.0")]
|
||||
[assembly: AssemblyVersion("1.10.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.10.0.0")]
|
||||
[assembly: InternalsVisibleTo("Artemis.Explorables")]
|
||||
|
||||
|
||||
Binary file not shown.
41
Artemis/Artemis/Services/CompatibilityService.cs
Normal file
41
Artemis/Artemis/Services/CompatibilityService.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Microsoft.Win32;
|
||||
using NLog;
|
||||
|
||||
namespace Artemis.Services
|
||||
{
|
||||
public static class CompatibilityService
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
// Checks to see if RivaTuner Statistics Server is installed and if so places a profile disabling it for Artemis
|
||||
public static void CheckRivaTuner()
|
||||
{
|
||||
// Find the installation path in the registry
|
||||
var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Unwinder\RTSS");
|
||||
var value = key?.GetValue("InstallPath");
|
||||
var installDir = Path.GetDirectoryName(value?.ToString());
|
||||
|
||||
if (installDir == null)
|
||||
return;
|
||||
var profilePath = Path.Combine(installDir, "ProfileTemplates\\Artemis.exe.cfg");
|
||||
if (File.Exists(profilePath))
|
||||
return;
|
||||
|
||||
File.WriteAllText(profilePath, "[Hooking]\r\nEnableHooking\t\t= 0");
|
||||
|
||||
// It's kill or be killed...
|
||||
var rtssProcess = System.Diagnostics.Process.GetProcessesByName("RTSS").FirstOrDefault();
|
||||
var rtssHookProcess = System.Diagnostics.Process.GetProcessesByName("RTSSHooksLoader64").FirstOrDefault();
|
||||
rtssProcess?.Kill();
|
||||
rtssHookProcess?.Kill();
|
||||
|
||||
// Funnily enough sleeping prevents the RTSS injection so that the process gets killed in time
|
||||
Thread.Sleep(1000);
|
||||
|
||||
Logger.Info("Detected that RivaTuner Statistics Server is installed, inserted a profile to prevent crashes.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,39 +1,41 @@
|
||||
using System.Dynamic;
|
||||
using Caliburn.Micro;
|
||||
using Ninject;
|
||||
using Ninject.Parameters;
|
||||
|
||||
namespace Artemis.Services
|
||||
{
|
||||
public class WindowService
|
||||
{
|
||||
private readonly IKernel _kernel;
|
||||
|
||||
public WindowService(IKernel kernel)
|
||||
{
|
||||
_kernel = kernel;
|
||||
}
|
||||
|
||||
public T ShowWindow<T>(string windowName, params IParameter[] param) where T : class
|
||||
{
|
||||
var windowManager = new WindowManager();
|
||||
using System.Dynamic;
|
||||
using Caliburn.Micro;
|
||||
using Ninject;
|
||||
using Ninject.Parameters;
|
||||
|
||||
namespace Artemis.Services
|
||||
{
|
||||
public class WindowService
|
||||
{
|
||||
private readonly IKernel _kernel;
|
||||
|
||||
public WindowService(IKernel kernel)
|
||||
{
|
||||
_kernel = kernel;
|
||||
}
|
||||
|
||||
public T ShowWindow<T>(string windowName, dynamic settings = null, params IParameter[] param) where T : class
|
||||
{
|
||||
var windowManager = new WindowManager();
|
||||
var viewModel = _kernel.Get<T>(param);
|
||||
|
||||
dynamic settings = new ExpandoObject();
|
||||
settings.Title = windowName;
|
||||
windowManager.ShowWindow(viewModel, null, settings);
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
public T ShowDialog<T>(string dialogName, params IParameter[] param) where T : class
|
||||
{
|
||||
var windowManager = new WindowManager();
|
||||
var viewModel = _kernel.Get<T>(param);
|
||||
|
||||
dynamic settings = new ExpandoObject();
|
||||
settings.Title = dialogName;
|
||||
windowManager.ShowDialog(viewModel, null, settings);
|
||||
return viewModel;
|
||||
}
|
||||
}
|
||||
if (settings == null)
|
||||
settings = new ExpandoObject();
|
||||
settings.Title = windowName;
|
||||
windowManager.ShowWindow(viewModel, null, settings);
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
public T ShowDialog<T>(string dialogName, dynamic settings = null, params IParameter[] param) where T : class
|
||||
{
|
||||
var windowManager = new WindowManager();
|
||||
var viewModel = _kernel.Get<T>(param);
|
||||
|
||||
if (settings == null)
|
||||
settings = new ExpandoObject();
|
||||
settings.Title = dialogName;
|
||||
windowManager.ShowDialog(viewModel, null, settings);
|
||||
return viewModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,9 +5,11 @@ using System.Windows;
|
||||
using Artemis.DAL;
|
||||
using Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.ActiveWindowDetection;
|
||||
using Caliburn.Micro;
|
||||
using MahApps.Metro;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Squirrel;
|
||||
|
||||
namespace Artemis.Settings
|
||||
@ -68,6 +70,11 @@ namespace Artemis.Settings
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||
public string LogLevel { get; set; }
|
||||
|
||||
[DefaultValue(ActiveWindowDetectionType.Events)]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||
public ActiveWindowDetectionType ActiveWindowDetection { get; set; }
|
||||
|
||||
public Version LastRanVersion { get; set; }
|
||||
|
||||
public void Save()
|
||||
@ -75,6 +82,7 @@ namespace Artemis.Settings
|
||||
SettingsProvider.Save(this);
|
||||
|
||||
Logging.SetupLogging(LogLevel);
|
||||
ActiveWindowHelper.SetActiveWindowDetectionType(ActiveWindowDetection);
|
||||
ApplyAutorun();
|
||||
ApplyTheme();
|
||||
ApplyGamestatePort();
|
||||
|
||||
@ -8,6 +8,7 @@ namespace Artemis.Settings
|
||||
{
|
||||
public GamePointersCollection RocketLeague { get; set; }
|
||||
public GamePointersCollection WorldOfWarcraft { get; set; }
|
||||
public GamePointersCollection Terraria { get; set; }
|
||||
|
||||
public void Save()
|
||||
{
|
||||
|
||||
@ -210,7 +210,7 @@
|
||||
ItemsSource="{Binding AvailableBrushTypes, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center">
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<UniformGrid Rows="1" Columns="4" />
|
||||
<UniformGrid Rows="1" />
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
<ListBox.ItemContainerStyle>
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
namespace Artemis.Utilities.ActiveWindowDetection
|
||||
{
|
||||
public enum ActiveWindowDetectionType
|
||||
{
|
||||
Disabled = -1,
|
||||
Events = 0,
|
||||
Timer = 1,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
namespace Artemis.Utilities.ActiveWindowDetection
|
||||
{
|
||||
public static class ActiveWindowHelper
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private static ActiveWindowDetectionType _currentDetectionType = ActiveWindowDetectionType.Disabled;
|
||||
private static IActiveWindowDetector _activeWindowDetector;
|
||||
|
||||
public static string ActiveWindowProcessName => _activeWindowDetector?.ActiveWindowProcessName ?? string.Empty;
|
||||
public static string ActiveWindowWindowTitle => _activeWindowDetector?.ActiveWindowWindowTitle ?? string.Empty;
|
||||
public static bool MainWindowActive => ActiveWindowProcessName.Contains("Artemis");
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public static void Dispose()
|
||||
{
|
||||
_activeWindowDetector?.Dispose();
|
||||
}
|
||||
|
||||
public static void SetActiveWindowDetectionType(ActiveWindowDetectionType detectionType)
|
||||
{
|
||||
if (detectionType == _currentDetectionType) return;
|
||||
|
||||
_activeWindowDetector?.Dispose();
|
||||
|
||||
switch (detectionType)
|
||||
{
|
||||
case ActiveWindowDetectionType.Events:
|
||||
_activeWindowDetector = new EventActiveWindowDetector();
|
||||
break;
|
||||
case ActiveWindowDetectionType.Timer:
|
||||
_activeWindowDetector = new TimerActiveWindowDetector();
|
||||
break;
|
||||
case ActiveWindowDetectionType.Disabled:
|
||||
_activeWindowDetector = null;
|
||||
break;
|
||||
}
|
||||
|
||||
_activeWindowDetector?.Initialize();
|
||||
_currentDetectionType = detectionType;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -2,9 +2,9 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Artemis.Utilities
|
||||
namespace Artemis.Utilities.ActiveWindowDetection
|
||||
{
|
||||
public static class ActiveWindowHelper
|
||||
public class EventActiveWindowDetector : IActiveWindowDetector
|
||||
{
|
||||
#region DLL-Imports
|
||||
|
||||
@ -14,7 +14,7 @@ namespace Artemis.Utilities
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc,
|
||||
WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
|
||||
WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool UnhookWinEvent(IntPtr hWinEventHook);
|
||||
@ -41,47 +41,46 @@ namespace Artemis.Utilities
|
||||
#region Properties & Fields
|
||||
|
||||
// DarthAffe 17.12.2016: We need to keep a reference to this or it might get collected by the garbage collector and cause some random crashes afterwards.
|
||||
private static WinEventDelegate _activeWindowChangedDelegate;
|
||||
private static IntPtr _activeWindowEventHook;
|
||||
private WinEventDelegate _activeWindowChangedDelegate;
|
||||
private IntPtr _activeWindowEventHook;
|
||||
|
||||
private static WinEventDelegate _windowTitleChangedDelegate;
|
||||
private static IntPtr _windowTitleEventHook;
|
||||
private WinEventDelegate _windowTitleChangedDelegate;
|
||||
private IntPtr _windowTitleEventHook;
|
||||
|
||||
private static WinEventDelegate _windowMinimizedChangedDelegate;
|
||||
private static IntPtr _windowMinimizedEventHook;
|
||||
private WinEventDelegate _windowMinimizedChangedDelegate;
|
||||
private IntPtr _windowMinimizedEventHook;
|
||||
|
||||
private static IntPtr _activeWindow;
|
||||
private IntPtr _activeWindow;
|
||||
|
||||
public static string ActiveWindowProcessName { get; private set; } = string.Empty;
|
||||
public static string ActiveWindowWindowTitle { get; private set; } = string.Empty;
|
||||
public static bool MainWindowActive => ActiveWindowProcessName.Contains("Artemis");
|
||||
public string ActiveWindowProcessName { get; private set; } = string.Empty;
|
||||
public string ActiveWindowWindowTitle { get; private set; } = string.Empty;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
private static void ActiveWindowChanged(IntPtr hWinEventHook, uint eventType,
|
||||
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
|
||||
private void ActiveWindowChanged(IntPtr hWinEventHook, uint eventType,
|
||||
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
|
||||
{
|
||||
UpdateForWindow(hwnd);
|
||||
}
|
||||
|
||||
private static void WindowTitleChanged(IntPtr hWinEventHook, uint eventType,
|
||||
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
|
||||
private void WindowTitleChanged(IntPtr hWinEventHook, uint eventType,
|
||||
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
|
||||
{
|
||||
if (_activeWindow == hwnd)
|
||||
UpdateForWindow(hwnd);
|
||||
}
|
||||
|
||||
private static void WindowMinimizedChanged(IntPtr hWinEventHook, uint eventType,
|
||||
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
|
||||
private void WindowMinimizedChanged(IntPtr hWinEventHook, uint eventType,
|
||||
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
|
||||
{
|
||||
// DarthAffe 19.12.2016: We expect currently un-minimized windows to be active.
|
||||
// DarthAffe 19.12.2016: The result of the API-function GetActiveWindow at this moment is 'idle' so we can't use this to validate this estimation.
|
||||
UpdateForWindow(hwnd);
|
||||
}
|
||||
|
||||
private static void UpdateForWindow(IntPtr hwnd)
|
||||
private void UpdateForWindow(IntPtr hwnd)
|
||||
{
|
||||
_activeWindow = hwnd;
|
||||
|
||||
@ -89,13 +88,13 @@ namespace Artemis.Utilities
|
||||
ActiveWindowWindowTitle = GetActiveWindowTitle(hwnd) ?? string.Empty;
|
||||
}
|
||||
|
||||
private static string GetActiveWindowProcessName(IntPtr hwnd)
|
||||
private string GetActiveWindowProcessName(IntPtr hwnd)
|
||||
{
|
||||
try
|
||||
{
|
||||
uint pid;
|
||||
GetWindowThreadProcessId(hwnd, out pid);
|
||||
return System.Diagnostics.Process.GetProcessById((int) pid).ProcessName;
|
||||
return System.Diagnostics.Process.GetProcessById((int)pid).ProcessName;
|
||||
}
|
||||
catch
|
||||
{
|
||||
@ -103,7 +102,7 @@ namespace Artemis.Utilities
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetActiveWindowTitle(IntPtr hwnd)
|
||||
private string GetActiveWindowTitle(IntPtr hwnd)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -116,7 +115,7 @@ namespace Artemis.Utilities
|
||||
}
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
public void Initialize()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -124,21 +123,21 @@ namespace Artemis.Utilities
|
||||
{
|
||||
_activeWindowChangedDelegate = ActiveWindowChanged;
|
||||
_activeWindowEventHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND,
|
||||
IntPtr.Zero, _activeWindowChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
|
||||
IntPtr.Zero, _activeWindowChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
|
||||
}
|
||||
|
||||
if (_windowTitleEventHook == IntPtr.Zero)
|
||||
{
|
||||
_windowTitleChangedDelegate = WindowTitleChanged;
|
||||
_windowTitleEventHook = SetWinEventHook(EVENT_OBJECT_NAMECHANGE, EVENT_OBJECT_NAMECHANGE,
|
||||
IntPtr.Zero, _windowTitleChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
|
||||
IntPtr.Zero, _windowTitleChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
|
||||
}
|
||||
|
||||
if (_windowMinimizedEventHook == IntPtr.Zero)
|
||||
{
|
||||
_windowMinimizedChangedDelegate = WindowMinimizedChanged;
|
||||
_windowMinimizedEventHook = SetWinEventHook(EVENT_SYSTEM_MINIMIZEEND, EVENT_SYSTEM_MINIMIZEEND,
|
||||
IntPtr.Zero, _windowMinimizedChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
|
||||
IntPtr.Zero, _windowMinimizedChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
|
||||
}
|
||||
}
|
||||
catch
|
||||
@ -147,7 +146,7 @@ namespace Artemis.Utilities
|
||||
}
|
||||
}
|
||||
|
||||
public static void Dispose()
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -180,4 +179,4 @@ namespace Artemis.Utilities
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace Artemis.Utilities.ActiveWindowDetection
|
||||
{
|
||||
public interface IActiveWindowDetector : IDisposable
|
||||
{
|
||||
string ActiveWindowProcessName { get; }
|
||||
string ActiveWindowWindowTitle { get; }
|
||||
|
||||
void Initialize();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Timers;
|
||||
|
||||
namespace Artemis.Utilities.ActiveWindowDetection
|
||||
{
|
||||
public class TimerActiveWindowDetector : IActiveWindowDetector
|
||||
{
|
||||
#region DLL-Imports
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern IntPtr GetForegroundWindow();
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constants
|
||||
|
||||
private const int TIMER_INTERVAL = 1000;
|
||||
private const int MAX_TITLE_LENGTH = 256;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties & Fields
|
||||
|
||||
private Timer _timer;
|
||||
|
||||
public string ActiveWindowProcessName { get; private set; }
|
||||
public string ActiveWindowWindowTitle { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
private void TimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
|
||||
{
|
||||
IntPtr activeWindow = GetForegroundWindow();
|
||||
ActiveWindowProcessName = GetActiveWindowProcessName(activeWindow);
|
||||
ActiveWindowWindowTitle = GetActiveWindowTitle(activeWindow);
|
||||
}
|
||||
|
||||
private string GetActiveWindowProcessName(IntPtr hwnd)
|
||||
{
|
||||
try
|
||||
{
|
||||
uint pid;
|
||||
GetWindowThreadProcessId(hwnd, out pid);
|
||||
return System.Diagnostics.Process.GetProcessById((int)pid).ProcessName;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetActiveWindowTitle(IntPtr hwnd)
|
||||
{
|
||||
try
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder(MAX_TITLE_LENGTH);
|
||||
return GetWindowText(hwnd, buffer, MAX_TITLE_LENGTH) > 0 ? buffer.ToString() : null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
_timer = new Timer(TIMER_INTERVAL) { AutoReset = true };
|
||||
_timer.Elapsed += TimerOnElapsed;
|
||||
_timer.Start();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_timer?.Stop();
|
||||
_timer?.Dispose();
|
||||
_timer = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -37,8 +37,11 @@ namespace Artemis.Utilities.DataReaders
|
||||
try
|
||||
{
|
||||
// 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");
|
||||
// Key doesn't exist yet on systems without LGS installed
|
||||
var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary", true) ??
|
||||
Registry.LocalMachine.CreateSubKey(@"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))
|
||||
|
||||
@ -148,6 +148,8 @@ namespace Artemis.Utilities
|
||||
offsetSettings.RocketLeague = pointers.FirstOrDefault(p => p.Game == "RocketLeague");
|
||||
if (pointers.FirstOrDefault(p => p.Game == "WorldOfWarcraft") != null)
|
||||
offsetSettings.WorldOfWarcraft = pointers.FirstOrDefault(p => p.Game == "WorldOfWarcraft");
|
||||
if (pointers.FirstOrDefault(p => p.Game == "Terraria") != null)
|
||||
offsetSettings.Terraria = pointers.FirstOrDefault(p => p.Game == "Terraria");
|
||||
|
||||
offsetSettings.Save();
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ using Artemis.Events;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Services;
|
||||
using Artemis.Settings;
|
||||
using Artemis.Utilities.ActiveWindowDetection;
|
||||
using Caliburn.Micro;
|
||||
using MahApps.Metro.Controls;
|
||||
using NLog;
|
||||
@ -37,6 +38,8 @@ namespace Artemis.ViewModels.Flyouts
|
||||
LogLevels = new BindableCollection<string>();
|
||||
LogLevels.AddRange(LogLevel.AllLoggingLevels.Select(l => l.Name));
|
||||
|
||||
ActiveWindowDetections = new BindableCollection<ActiveWindowDetectionType>(Enum.GetValues(typeof(ActiveWindowDetectionType)).Cast<ActiveWindowDetectionType>());
|
||||
|
||||
PropertyChanged += KeyboardUpdater;
|
||||
mainManager.EnabledChanged += MainManagerEnabledChanged;
|
||||
mainManager.ModuleManager.EffectChanged += EffectManagerEffectChanged;
|
||||
@ -96,6 +99,7 @@ namespace Artemis.ViewModels.Flyouts
|
||||
public string VersionText => "Artemis " + Assembly.GetExecutingAssembly().GetName().Version;
|
||||
|
||||
public BindableCollection<string> LogLevels { get; set; }
|
||||
public BindableCollection<ActiveWindowDetectionType> ActiveWindowDetections { get; set; }
|
||||
|
||||
public string SelectedTheme
|
||||
{
|
||||
@ -130,6 +134,17 @@ namespace Artemis.ViewModels.Flyouts
|
||||
}
|
||||
}
|
||||
|
||||
public ActiveWindowDetectionType SelectedActiveWindowDetection
|
||||
{
|
||||
get { return GeneralSettings.ActiveWindowDetection; }
|
||||
set
|
||||
{
|
||||
if (value == GeneralSettings.ActiveWindowDetection) return;
|
||||
GeneralSettings.ActiveWindowDetection = value;
|
||||
NotifyOfPropertyChange(() => SelectedActiveWindowDetection);
|
||||
}
|
||||
}
|
||||
|
||||
public string SelectedKeyboardProvider
|
||||
{
|
||||
get { return _selectedKeyboardProvider; }
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@ -12,7 +11,6 @@ using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Artemis.DAL;
|
||||
using Artemis.DeviceProviders;
|
||||
using Artemis.Events;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
@ -21,10 +19,12 @@ using Artemis.Profiles;
|
||||
using Artemis.Profiles.Layers.Interfaces;
|
||||
using Artemis.Profiles.Layers.Models;
|
||||
using Artemis.Profiles.Layers.Types.Folder;
|
||||
using Artemis.Profiles.Lua.Modules.Gui;
|
||||
using Artemis.Properties;
|
||||
using Artemis.Services;
|
||||
using Artemis.Styles.DropTargetAdorners;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.ActiveWindowDetection;
|
||||
using Caliburn.Micro;
|
||||
using Castle.Components.DictionaryAdapter;
|
||||
using GongSolutions.Wpf.DragDrop;
|
||||
@ -46,21 +46,20 @@ namespace Artemis.ViewModels
|
||||
{
|
||||
public sealed class ProfileEditorViewModel : Screen, IDropTarget
|
||||
{
|
||||
private readonly KeybindModel _copyKeybind;
|
||||
private readonly DeviceManager _deviceManager;
|
||||
private readonly MetroDialogService _dialogService;
|
||||
private readonly LoopManager _loopManager;
|
||||
private readonly ModuleModel _moduleModel;
|
||||
private readonly KeybindModel _copyKeybind;
|
||||
private readonly KeybindModel _pasteKeybind;
|
||||
private ImageSource _keyboardPreview;
|
||||
private ObservableCollection<LayerModel> _layers;
|
||||
private readonly KeybindModel _pasteKeybind;
|
||||
private ObservableCollection<string> _profileNames;
|
||||
private bool _saving;
|
||||
private LayerModel _selectedLayer;
|
||||
private bool _showAll;
|
||||
|
||||
public ProfileEditorViewModel(ProfileEditorModel profileEditorModel, DeviceManager deviceManager,
|
||||
LoopManager loopManager, ModuleModel moduleModel, MetroDialogService dialogService)
|
||||
public ProfileEditorViewModel(ProfileEditorModel profileEditorModel, DeviceManager deviceManager, LoopManager loopManager, LuaManager luaManager, ModuleModel moduleModel, MetroDialogService dialogService)
|
||||
{
|
||||
_deviceManager = deviceManager;
|
||||
_loopManager = loopManager;
|
||||
@ -72,6 +71,7 @@ namespace Artemis.ViewModels
|
||||
ProfileNames = new ObservableCollection<string>();
|
||||
Layers = new ObservableCollection<LayerModel>();
|
||||
ProfileEditorModel = profileEditorModel;
|
||||
LuaManager = luaManager;
|
||||
ShowAll = true;
|
||||
|
||||
PropertyChanged += EditorStateHandler;
|
||||
@ -102,6 +102,11 @@ namespace Artemis.ViewModels
|
||||
|
||||
#region LUA
|
||||
|
||||
public void ClickedLuaButton(EditorButton button)
|
||||
{
|
||||
button.Invoke();
|
||||
}
|
||||
|
||||
public void EditLua()
|
||||
{
|
||||
if (SelectedProfile == null)
|
||||
@ -123,6 +128,7 @@ namespace Artemis.ViewModels
|
||||
#region Properties
|
||||
|
||||
public ProfileEditorModel ProfileEditorModel { get; }
|
||||
public LuaManager LuaManager { get; }
|
||||
|
||||
public ObservableCollection<string> ProfileNames
|
||||
{
|
||||
@ -198,7 +204,7 @@ namespace Artemis.ViewModels
|
||||
NotifyOfPropertyChange(() => LayerSelected);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ProfileModel SelectedProfile => _moduleModel?.ProfileModel;
|
||||
public bool ProfileSelected => SelectedProfile != null;
|
||||
public bool LayerSelected => SelectedProfile != null && SelectedLayer != null;
|
||||
@ -325,7 +331,7 @@ namespace Artemis.ViewModels
|
||||
|
||||
public void LayerToClipboard()
|
||||
{
|
||||
if (SelectedLayer == null || !ActiveWindowHelper.MainWindowActive)
|
||||
if (SelectedLayer == null || !ActiveWindowHelper.MainWindowActive || !IsActive)
|
||||
return;
|
||||
|
||||
// Probably not how the cool kids do it but leveraging on JsonConvert gives flawless serialization
|
||||
@ -334,30 +340,35 @@ namespace Artemis.ViewModels
|
||||
|
||||
public void ClipboardToLayer()
|
||||
{
|
||||
if (!ActiveWindowHelper.MainWindowActive)
|
||||
if (!ActiveWindowHelper.MainWindowActive || !IsActive)
|
||||
return;
|
||||
|
||||
GeneralHelpers.ExecuteSta(() =>
|
||||
try
|
||||
{
|
||||
var data = (string) Clipboard.GetData("layer");
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
var layerModel = JsonConvert.DeserializeObject<LayerModel>(data);
|
||||
if (layerModel == null)
|
||||
return;
|
||||
|
||||
if (SelectedLayer != null)
|
||||
GeneralHelpers.ExecuteSta(() =>
|
||||
{
|
||||
SelectedLayer.InsertAfter(layerModel);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedProfile.Layers.Add(layerModel);
|
||||
SelectedProfile.FixOrder();
|
||||
}
|
||||
Execute.OnUIThread(() => UpdateLayerList(layerModel));
|
||||
});
|
||||
var data = (string) Clipboard.GetData("layer");
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
var layerModel = JsonConvert.DeserializeObject<LayerModel>(data);
|
||||
if (layerModel == null)
|
||||
return;
|
||||
|
||||
if (SelectedLayer != null)
|
||||
SelectedLayer.InsertAfter(layerModel);
|
||||
else
|
||||
{
|
||||
SelectedProfile.Layers.Add(layerModel);
|
||||
SelectedProfile.FixOrder();
|
||||
}
|
||||
Execute.OnUIThread(() => UpdateLayerList(layerModel));
|
||||
});
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateLayerList(LayerModel selectModel)
|
||||
@ -405,6 +416,9 @@ namespace Artemis.ViewModels
|
||||
if (_saving || SelectedProfile == null || _deviceManager.ChangingKeyboard)
|
||||
return;
|
||||
|
||||
SelectedProfile.Width = _deviceManager.ActiveKeyboard.Width;
|
||||
SelectedProfile.Height = _deviceManager.ActiveKeyboard.Height;
|
||||
|
||||
_saving = true;
|
||||
try
|
||||
{
|
||||
@ -421,8 +435,7 @@ namespace Artemis.ViewModels
|
||||
{
|
||||
if (_deviceManager.ActiveKeyboard == null)
|
||||
{
|
||||
_dialogService.ShowMessageBox("Cannot add profile.",
|
||||
"To add a profile, please select a keyboard in the options menu first.");
|
||||
_dialogService.ShowMessageBox("Cannot add profile.", "To add a profile, please select a keyboard in the options menu first.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -666,7 +679,7 @@ namespace Artemis.ViewModels
|
||||
return;
|
||||
|
||||
var pos = GetScaledPosition(e);
|
||||
var hoverLayer = GetLayers().Where(l => l.MustDraw()).FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(pos.X, pos.Y));
|
||||
var hoverLayer = GetHoverLayer(pos.X, pos.Y);
|
||||
|
||||
if (hoverLayer != null)
|
||||
SelectedLayer = hoverLayer;
|
||||
@ -682,7 +695,7 @@ namespace Artemis.ViewModels
|
||||
return;
|
||||
|
||||
var pos = GetScaledPosition(e);
|
||||
var hoverLayer = GetLayers().Where(l => l.MustDraw()).FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(pos.X, pos.Y));
|
||||
var hoverLayer = GetHoverLayer(pos.X, pos.Y);
|
||||
|
||||
HandleDragging(e, pos.X, pos.Y, hoverLayer);
|
||||
|
||||
@ -701,11 +714,10 @@ namespace Artemis.ViewModels
|
||||
: Cursors.SizeAll;
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyboardPreviewCursor = Cursors.Hand;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Point GetScaledPosition(MouseEventArgs e)
|
||||
{
|
||||
var previewSettings = _deviceManager.ActiveKeyboard.PreviewSettings;
|
||||
@ -716,16 +728,25 @@ namespace Artemis.ViewModels
|
||||
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);
|
||||
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.X = pos.X * (SelectedProfile.Width / (previewSettings.OverlayRectangle.Width * widthScale));
|
||||
pos.Y = pos.Y * (SelectedProfile.Height / (previewSettings.OverlayRectangle.Height * heightScale));
|
||||
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
private LayerModel GetHoverLayer(double x, double y)
|
||||
{
|
||||
// Prefer the selected layer as the hover layer even if it's underneath something else
|
||||
if (SelectedLayer != null && SelectedLayer.Properties.PropertiesRect(1).Contains(x, y))
|
||||
return SelectedLayer;
|
||||
|
||||
return GetLayers().Where(l => l.MustDraw()).FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(x, y));
|
||||
}
|
||||
|
||||
public Cursor KeyboardPreviewCursor
|
||||
{
|
||||
get { return _keyboardPreviewCursor; }
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
|
||||
xmlns:cal="http://www.caliburnproject.org"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="600" d:DesignWidth="300">
|
||||
d:DesignHeight="600" d:DesignWidth="310">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
@ -25,6 +25,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
@ -94,30 +95,36 @@
|
||||
<controls:NumericUpDown Grid.Row="8" Grid.Column="1" Margin="10" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right" Width="140" Minimum="1" Maximum="60"
|
||||
Value="{Binding Path=GeneralSettings.ScreenCaptureFPS, Mode=TwoWay}" />
|
||||
|
||||
<!-- Logging -->
|
||||
|
||||
<Label Grid.Row="9" Grid.Column="0" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Left"
|
||||
Content="Log level:" />
|
||||
<ComboBox Grid.Row="9" Grid.Column="1" x:Name="LogLevels" Margin="10" VerticalAlignment="Center"
|
||||
Content="Active window detection" />
|
||||
<ComboBox Grid.Row="9" Grid.Column="1" x:Name="ActiveWindowDetections" Margin="10" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Width="140" />
|
||||
<Button Grid.Row="10" Grid.Column="0" Margin="10" x:Name="ShowLogs" Content="Show logs"
|
||||
|
||||
<!-- Logging -->
|
||||
<Label Grid.Row="10" Grid.Column="0" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Left"
|
||||
Content="Log level:" />
|
||||
<ComboBox Grid.Row="10" Grid.Column="1" x:Name="LogLevels" Margin="10" VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Width="140" />
|
||||
<Button Grid.Row="11" Grid.Column="0" Margin="10" x:Name="ShowLogs" Content="Show logs"
|
||||
VerticalAlignment="Center" Width="100" HorizontalAlignment="Left"
|
||||
Style="{DynamicResource SquareButtonStyle}" />
|
||||
<Button Grid.Row="10" Grid.Column="1" Margin="10" x:Name="ShowDebug" Content="Show debugger"
|
||||
<Button Grid.Row="11" Grid.Column="1" Margin="10" x:Name="ShowDebug" Content="Show debugger"
|
||||
VerticalAlignment="Center" Width="100" HorizontalAlignment="Right"
|
||||
Style="{DynamicResource SquareButtonStyle}" />
|
||||
|
||||
<!-- Buttons -->
|
||||
<Button Grid.Row="11" Grid.Column="0" Margin="10" x:Name="ResetSettings" Content="Reset settings"
|
||||
<Button Grid.Row="12" Grid.Column="0" Margin="10" x:Name="ResetSettings" Content="Reset settings"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Left" Width="100"
|
||||
Style="{DynamicResource SquareButtonStyle}" />
|
||||
<Button Grid.Row="11" Grid.Column="1" Margin="11" x:Name="SaveSettings" Content="Save changes"
|
||||
<Button Grid.Row="12" Grid.Column="1" Margin="11" x:Name="SaveSettings" Content="Save changes"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Right" Width="100"
|
||||
Style="{DynamicResource SquareButtonStyle}" />
|
||||
|
||||
<!-- Version -->
|
||||
<Grid Grid.Row="12" Grid.Column="0" Grid.ColumnSpan="2" Margin="10" VerticalAlignment="Bottom">
|
||||
<Grid Grid.Row="13" Grid.Column="0" Grid.ColumnSpan="2" Margin="10" VerticalAlignment="Bottom">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
|
||||
@ -1,16 +1,8 @@
|
||||
<UserControl x:Class="Artemis.Views.ProfileEditorView"
|
||||
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">
|
||||
<UserControl x:Class="Artemis.Views.ProfileEditorView" 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">
|
||||
<UserControl.Resources>
|
||||
<converters:LayerOrderConverter x:Key="LayerOrderConverter" />
|
||||
</UserControl.Resources>
|
||||
@ -22,7 +14,8 @@
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="60" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Preview -->
|
||||
@ -32,7 +25,9 @@
|
||||
<Border.Effect>
|
||||
<DropShadowEffect x:Name="ShadowEffect" ShadowDepth="0" Color="{DynamicResource HighlightColor}" Opacity="1" BlurRadius="25" />
|
||||
</Border.Effect>
|
||||
<Image Source="{Binding Path=KeyboardPreview}" MinHeight="10" MinWidth="10" Stretch="Uniform" Cursor="{Binding Path=KeyboardPreviewCursor}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}" cal:Message.Attach="
|
||||
<Image Source="{Binding Path=KeyboardPreview}" MinHeight="10" MinWidth="10" Stretch="Uniform" Cursor="{Binding Path=KeyboardPreviewCursor}"
|
||||
IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"
|
||||
cal:Message.Attach="
|
||||
[Event MouseMove] = [Action MouseMoveKeyboardPreview($eventArgs)];
|
||||
[Event MouseDown] = [Action MouseDownKeyboardPreview($eventArgs)];
|
||||
[Event MouseUp] = [Action MouseUpKeyboardPreview($eventArgs)]" />
|
||||
@ -43,8 +38,8 @@
|
||||
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
|
||||
<Label Content="Active profile" />
|
||||
<ComboBox Width="220" VerticalAlignment="Top" x:Name="ProfileNames" Margin="5,0,0,0" />
|
||||
<Button x:Name="AddProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
|
||||
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Add profile">
|
||||
<Button x:Name="AddProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
|
||||
ToolTip="Add profile">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
|
||||
<Rectangle.OpacityMask>
|
||||
@ -53,9 +48,8 @@
|
||||
</Rectangle>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button x:Name="RenameProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
|
||||
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Rename profile"
|
||||
IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}">
|
||||
<Button x:Name="RenameProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
|
||||
ToolTip="Rename profile" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
|
||||
<Rectangle.OpacityMask>
|
||||
@ -74,7 +68,8 @@
|
||||
</Rectangle>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button x:Name="DeleteProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Delete profile" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}">
|
||||
<Button x:Name="DeleteProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
|
||||
ToolTip="Delete profile" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
|
||||
<Rectangle.OpacityMask>
|
||||
@ -84,17 +79,12 @@
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBlock VerticalAlignment="Top" Foreground="{DynamicResource HighlightBrush}" HorizontalAlignment="Left" Margin="5,5,0,0" Text="Note: To edit a default profile, duplicate it first." FontWeight="Bold" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="0" Grid.Row="2" Orientation="Horizontal" Margin="0,5,0,0" HorizontalAlignment="Right">
|
||||
<Button x:Name="ImportProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
|
||||
Height="26" HorizontalAlignment="Right">
|
||||
<Button x:Name="ImportProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Height="26" HorizontalAlignment="Right">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Rectangle
|
||||
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
|
||||
Width="12" Height="12" Margin="3,0">
|
||||
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12" Margin="3,0">
|
||||
<Rectangle.OpacityMask>
|
||||
<VisualBrush Visual="{StaticResource appbar_cabinet_in}" Stretch="Fill" />
|
||||
</Rectangle.OpacityMask>
|
||||
@ -103,13 +93,11 @@
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button x:Name="ExportProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
|
||||
Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" IsEnabled="{Binding ProfileSelected}">
|
||||
<Button x:Name="ExportProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
|
||||
IsEnabled="{Binding ProfileSelected}">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Rectangle
|
||||
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
|
||||
Width="12" Height="12" Margin="3,0">
|
||||
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12" Margin="3,0">
|
||||
<Rectangle.OpacityMask>
|
||||
<VisualBrush Visual="{StaticResource appbar_cabinet_out}" Stretch="Fill" />
|
||||
</Rectangle.OpacityMask>
|
||||
@ -118,14 +106,11 @@
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button x:Name="EditLua" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Height="26"
|
||||
HorizontalAlignment="Right" Margin="10,0,0,0" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"
|
||||
Visibility="{Binding Path=LuaButtonVisible, Converter={StaticResource BoolToVis} }">
|
||||
<Button x:Name="EditLua" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
|
||||
IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}" Visibility="{Binding Path=LuaButtonVisible, Converter={StaticResource BoolToVis} }">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Rectangle
|
||||
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
|
||||
Width="12" Height="12" Margin="3,0">
|
||||
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12" Margin="3,0">
|
||||
<Rectangle.OpacityMask>
|
||||
<VisualBrush Visual="{StaticResource appbar_code_xml}" Stretch="Fill" />
|
||||
</Rectangle.OpacityMask>
|
||||
@ -154,8 +139,7 @@
|
||||
ItemsSource="{Binding Path=Layers, Converter={StaticResource LayerOrderConverter}, ConverterParameter=Order}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"
|
||||
cal:Message.Attach="[Event MouseDoubleClick] = [Action EditLayerFromDoubleClick]">
|
||||
<i:Interaction.Behaviors>
|
||||
<itemBehaviours:BindableSelectedItemBehavior
|
||||
SelectedItem="{Binding SelectedLayer, Mode=TwoWay}" />
|
||||
<itemBehaviours:BindableSelectedItemBehavior SelectedItem="{Binding SelectedLayer, Mode=TwoWay}" />
|
||||
</i:Interaction.Behaviors>
|
||||
<TreeView.Resources>
|
||||
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
|
||||
@ -185,9 +169,8 @@
|
||||
</TreeView>
|
||||
</Border>
|
||||
<StackPanel Grid.Column="1" Grid.Row="2" Orientation="Horizontal" Margin="0,5,0,0" HorizontalAlignment="Right">
|
||||
<Button x:Name="AddLayer" VerticalAlignment="Top"
|
||||
Style="{DynamicResource SquareButtonStyle}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"
|
||||
Width="26" Height="26" ToolTip="Add layer" HorizontalAlignment="Left">
|
||||
<Button x:Name="AddLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}" Width="26" Height="26"
|
||||
ToolTip="Add layer" HorizontalAlignment="Left">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
|
||||
<Rectangle.OpacityMask>
|
||||
@ -196,9 +179,8 @@
|
||||
</Rectangle>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button x:Name="AddFolder" VerticalAlignment="Top"
|
||||
Style="{DynamicResource SquareButtonStyle}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"
|
||||
Width="26" Height="26" ToolTip="Add folder" HorizontalAlignment="Left" Margin="10,0,0,0">
|
||||
<Button x:Name="AddFolder" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}" Width="26" Height="26"
|
||||
ToolTip="Add folder" HorizontalAlignment="Left" Margin="10,0,0,0">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
|
||||
<Rectangle.OpacityMask>
|
||||
@ -207,8 +189,7 @@
|
||||
</Rectangle>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button x:Name="EditLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
|
||||
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Edit layer"
|
||||
<Button x:Name="EditLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Edit layer"
|
||||
IsEnabled="{Binding Path=LayerSelected}">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
|
||||
@ -218,9 +199,8 @@
|
||||
</Rectangle>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button x:Name="CloneLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
|
||||
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Duplicate layer"
|
||||
IsEnabled="{Binding Path=LayerSelected}">
|
||||
<Button x:Name="CloneLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
|
||||
ToolTip="Duplicate layer" IsEnabled="{Binding Path=LayerSelected}">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
|
||||
<Rectangle.OpacityMask>
|
||||
@ -229,9 +209,8 @@
|
||||
</Rectangle>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button x:Name="RemoveLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
|
||||
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Delete layer"
|
||||
IsEnabled="{Binding Path=LayerSelected}">
|
||||
<Button x:Name="RemoveLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
|
||||
ToolTip="Delete layer" IsEnabled="{Binding Path=LayerSelected}">
|
||||
<Button.Content>
|
||||
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
|
||||
<Rectangle.OpacityMask>
|
||||
@ -241,5 +220,21 @@
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock VerticalAlignment="Top" Grid.Column="0" Grid.Row="3" Foreground="{DynamicResource HighlightBrush}" Margin="0,5" HorizontalAlignment="Left"
|
||||
Text="Note: To edit a default profile, duplicate it first." FontWeight="Bold" />
|
||||
|
||||
<ItemsControl ItemsSource="{Binding Path=LuaManager.EditorButtons}" Grid.Column="1" Grid.Row="3" Margin="0,5" HorizontalAlignment="Right">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Button Content="{Binding Text}" cal:Message.Attach="ClickedLuaButton($dataContext)" Style="{DynamicResource SquareButtonStyle}" Height="26" Margin="5,0,0,0" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@ -22,7 +22,7 @@
|
||||
<ProjectGuid>{1A349CF5-2008-41E8-AC13-874CBBCDFA0A}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>LightFX2Artemis</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>LogiLed2Artemis</RootNamespace>
|
||||
<ProjectName>LogiLed2Artemis</ProjectName>
|
||||
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{39711909-C1D5-46CE-A9EA-2D561692EA47}</ProjectGuid>
|
||||
<RootNamespace>Razer2Artemis</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user