1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2026-01-01 02:03:32 +00:00

Merge pull request #355 from SpoinkyNL/development

1.10.0.0
This commit is contained in:
Robert Beekman 2017-05-06 23:48:48 +02:00 committed by GitHub
commit 2edbf093a7
65 changed files with 1872 additions and 774 deletions

View File

@ -384,6 +384,13 @@
<DependentUpon>AssettoCorsaView.xaml</DependentUpon> <DependentUpon>AssettoCorsaView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Modules\Games\AssettoCorsa\AssettoCorsaViewModel.cs" /> <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\General\GeneralProfile\PerformanceInfo.cs" />
<Compile Include="Modules\Games\EurotruckSimulator2\Data\Ets2TelemetryData.cs" /> <Compile Include="Modules\Games\EurotruckSimulator2\Data\Ets2TelemetryData.cs" />
<Compile Include="Modules\Games\EurotruckSimulator2\Data\Ets2TelemetryDataReader.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\LuaKeyPressEventArgs.cs" />
<Compile Include="Profiles\Lua\Modules\Events\LuaDeviceDrawingEventArgs.cs" /> <Compile Include="Profiles\Lua\Modules\Events\LuaDeviceDrawingEventArgs.cs" />
<Compile Include="Profiles\Lua\Modules\Events\LuaDeviceUpdatingEventArgs.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\LuaEventsModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaBrushesModule.cs" /> <Compile Include="Profiles\Lua\Modules\LuaBrushesModule.cs" />
<Compile Include="Profiles\Lua\LuaModule.cs" /> <Compile Include="Profiles\Lua\LuaModule.cs" />
<Compile Include="Profiles\Lua\Modules\Brushes\LuaSolidColorBrush.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\LuaKeybindModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaKeyboardModule.cs" /> <Compile Include="Profiles\Lua\Modules\LuaKeyboardModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaLayerModule.cs" /> <Compile Include="Profiles\Lua\Modules\LuaLayerModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaMouseModule.cs" /> <Compile Include="Profiles\Lua\Modules\LuaMouseModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaProfileModule.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\Timer\LuaTimer.cs" />
<Compile Include="Profiles\Lua\Modules\LuaTimerModule.cs" /> <Compile Include="Profiles\Lua\Modules\LuaTimerModule.cs" />
<Compile Include="Profiles\Lua\Wrappers\LuaDrawWrapper.cs" /> <Compile Include="Profiles\Lua\Wrappers\LuaDrawWrapper.cs" />
@ -645,6 +664,7 @@
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon> <DependentUpon>Resources.resx</DependentUpon>
</Compile> </Compile>
<Compile Include="Services\CompatibilityService.cs" />
<Compile Include="Services\DialogService.cs" /> <Compile Include="Services\DialogService.cs" />
<Compile Include="Services\MetroDialogService.cs" /> <Compile Include="Services\MetroDialogService.cs" />
<Compile Include="Services\WindowService.cs" /> <Compile Include="Services\WindowService.cs" />
@ -653,7 +673,11 @@
<Compile Include="Settings\OffsetSettings.cs" /> <Compile Include="Settings\OffsetSettings.cs" />
<Compile Include="Styles\DropTargetAdorners\DropTargetMetroHighlightAdorner.cs" /> <Compile Include="Styles\DropTargetAdorners\DropTargetMetroHighlightAdorner.cs" />
<Compile Include="Styles\DropTargetAdorners\DropTargetMetroInsertionAdorner.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\ColorHelpers.cs" />
<Compile Include="Utilities\Converters\JsonConverters.cs" /> <Compile Include="Utilities\Converters\JsonConverters.cs" />
<Compile Include="Utilities\Converters\NinjectCustomConverter.cs" /> <Compile Include="Utilities\Converters\NinjectCustomConverter.cs" />
@ -856,6 +880,10 @@
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</Page> </Page>
<Page Include="Modules\Games\Terraria\TerrariaView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Modules\General\Bubbles\BubblesView.xaml"> <Page Include="Modules\General\Bubbles\BubblesView.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
@ -924,6 +952,10 @@
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</Page> </Page>
<Page Include="Profiles\Lua\Modules\Gui\LuaWindowView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Resources\Icons.xaml"> <Page Include="Resources\Icons.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>

View File

@ -8,8 +8,10 @@ using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using Artemis.DAL; using Artemis.DAL;
using Artemis.InjectionModules; using Artemis.InjectionModules;
using Artemis.Services;
using Artemis.Settings; using Artemis.Settings;
using Artemis.Utilities; using Artemis.Utilities;
using Artemis.Utilities.ActiveWindowDetection;
using Artemis.Utilities.Converters; using Artemis.Utilities.Converters;
using Artemis.Utilities.DataReaders; using Artemis.Utilities.DataReaders;
using Artemis.ViewModels; using Artemis.ViewModels;
@ -31,10 +33,11 @@ namespace Artemis
Logging.SetupLogging(SettingsProvider.Load<GeneralSettings>().LogLevel); Logging.SetupLogging(SettingsProvider.Load<GeneralSettings>().LogLevel);
// Restore DDLs before interacting with any SDKs // Restore DDLs before interacting with any SDKs
DllManager.RestoreLogitechDll(); DllManager.RestoreLogitechDll();
// Check compatibility before trying to boot further
CompatibilityService.CheckRivaTuner();
Initialize(); Initialize();
BindSpecialValues(); BindSpecialValues();
InputHook.Start();
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException; 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 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 e.GetPosition(input).X;
// Return 0 if no processing could be done // 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."); logger.Info("Artemis was run using the autorun shortcut, sleeping for 15 sec.");
Thread.Sleep(15000); Thread.Sleep(15000);
} }
_kernel = new StandardKernel(new BaseModules(), new ManagerModules()); _kernel = new StandardKernel(new BaseModules(), new ManagerModules());
_kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope(); _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 DarthAffe 17.12.2016: Is this the right location for this?
//TODO Move to Mainmanager and make disposable //TODO Move to Mainmanager and make disposable
ActiveWindowHelper.Initialize(); ActiveWindowHelper.SetActiveWindowDetectionType(SettingsProvider.Load<GeneralSettings>().ActiveWindowDetection);
} }
protected override void OnExit(object sender, EventArgs e) protected override void OnExit(object sender, EventArgs e)
@ -144,6 +148,7 @@ namespace Artemis
protected override void OnStartup(object sender, StartupEventArgs e) protected override void OnStartup(object sender, StartupEventArgs e)
{ {
DisplayRootViewFor<ShellViewModel>(); DisplayRootViewFor<ShellViewModel>();
InputHook.Start();
} }
} }
} }

View File

@ -134,7 +134,7 @@ namespace Artemis.DAL
return null; return null;
return prof; return prof;
} }
catch (JsonSerializationException) catch (JsonException)
{ {
return null; return null;
} }

View File

@ -1,4 +1,5 @@
using System.Drawing; using System;
using System.Drawing;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Windows; using System.Windows;
@ -67,6 +68,8 @@ namespace Artemis.DeviceProviders.CoolerMaster
for (var y = 0; y < Height; y++) for (var y = 0; y < Height; y++)
{ {
var c = b.GetPixel(x, 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); matrix.KeyColor[y, x] = new KEY_COLOR(c.R, c.G, c.B);
} }
} }

View File

@ -42,9 +42,16 @@ namespace Artemis.DeviceProviders.CoolerMaster
CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MMouse_L); CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MMouse_L);
// Doesn't seem reliable but better than nothing I suppose // Doesn't seem reliable but better than nothing I suppose
CanUse = CmSdk.IsDevicePlug(); try
if (CanUse) {
CmSdk.EnableLedControl(true); CanUse = CmSdk.IsDevicePlug();
if (CanUse)
CmSdk.EnableLedControl(true);
}
catch (Exception)
{
CanUse = false;
}
Logger.Debug("Attempted to enable Mastermouse Pro L. CanUse: {0}", CanUse); Logger.Debug("Attempted to enable Mastermouse Pro L. CanUse: {0}", CanUse);
return CanUse; return CanUse;

View File

@ -38,9 +38,16 @@ namespace Artemis.DeviceProviders.CoolerMaster
CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MMouse_S); CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MMouse_S);
// Doesn't seem reliable but better than nothing I suppose // Doesn't seem reliable but better than nothing I suppose
CanUse = CmSdk.IsDevicePlug(); try
if (CanUse) {
CmSdk.EnableLedControl(true); CanUse = CmSdk.IsDevicePlug();
if (CanUse)
CmSdk.EnableLedControl(true);
}
catch (Exception)
{
CanUse = false;
}
Logger.Debug("Attempted to enable Mastermouse Pro S. CanUse: {0}", CanUse); Logger.Debug("Attempted to enable Mastermouse Pro S. CanUse: {0}", CanUse);
return CanUse; return CanUse;

View File

@ -81,10 +81,10 @@ namespace Artemis.DeviceProviders.Corsair
PreviewSettings = new PreviewSettings(new Rect(15, 30, 751, 284), Resources.k65); PreviewSettings = new PreviewSettings(new Rect(15, 30, 751, 284), Resources.k65);
break; break;
case "STRAFE RGB": case "STRAFE RGB":
Height = 7; Height = 8;
Width = 22; Width = 22;
Slug = "corsair-strafe-rgb"; 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; break;
} }
@ -114,29 +114,8 @@ namespace Artemis.DeviceProviders.Corsair
/// <param name="bitmap"></param> /// <param name="bitmap"></param>
public override void DrawBitmap(Bitmap bitmap) public override void DrawBitmap(Bitmap bitmap)
{ {
_keyboardBrush.Image = bitmap;
// For STRAFE, stretch the image on row 2. _keyboard.Update();
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();
}
} }
public override KeyMatch? GetKeyPosition(Keys keyCode) public override KeyMatch? GetKeyPosition(Keys keyCode)

View File

@ -14,8 +14,7 @@ namespace Artemis.DeviceProviders.Logitech
DllManager.RestoreLogitechDll(); DllManager.RestoreLogitechDll();
// Check to see if VC++ 2012 x64 is installed. // Check to see if VC++ 2012 x64 is installed.
if (Registry.LocalMachine.OpenSubKey( if (Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\Installer\Dependencies\{ca67548a-5ebe-413a-b50c-4b9ceb6d66c6}") == null)
@"SOFTWARE\Classes\Installer\Dependencies\{ca67548a-5ebe-413a-b50c-4b9ceb6d66c6}") == null)
{ {
CantEnableText = "Couldn't connect to your Logitech keyboard.\n" + 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" + "The Visual C++ 2012 Redistributable v11.0.61030.0 could not be found, which is required.\n" +

View File

@ -37,8 +37,11 @@ namespace Artemis.DeviceProviders.Razer
return false; return false;
// Some people have Synapse installed, but not a Chroma keyboard, deal with this // 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 blackWidowFound = Chroma.Instance.Query(Devices.Blackwidow).Connected;
var blackWidowTeFound = Chroma.Instance.Query(Devices.BlackwidowTe).Connected; var blackWidowTeFound = Chroma.Instance.Query(Devices.BlackwidowTe).Connected;
Chroma.Instance.Uninitialize();
return blackWidowFound || blackWidowTeFound; return blackWidowFound || blackWidowTeFound;
} }

View File

@ -6,6 +6,7 @@ using Artemis.Profiles.Layers.Abstract;
using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Types.Audio.AudioCapturing; using Artemis.Profiles.Layers.Types.Audio.AudioCapturing;
using Artemis.Profiles.Lua; using Artemis.Profiles.Lua;
using Artemis.Profiles.Lua.Modules.Gui;
using Artemis.Services; using Artemis.Services;
using Artemis.Utilities.DataReaders; using Artemis.Utilities.DataReaders;
using Artemis.Utilities.GameState; using Artemis.Utilities.GameState;
@ -116,6 +117,8 @@ namespace Artemis.InjectionModules
.InheritedFrom<LuaModule>() .InheritedFrom<LuaModule>()
.BindAllBaseClasses()); .BindAllBaseClasses());
Bind<LuaWindowViewModel>().ToSelf();
#endregion #endregion
} }
} }

View File

@ -1,10 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using Artemis.DeviceProviders; using Artemis.DeviceProviders;
using Artemis.Profiles; using Artemis.Profiles;
using Artemis.Profiles.Lua; using Artemis.Profiles.Lua;
using Artemis.Profiles.Lua.Modules; using Artemis.Profiles.Lua.Modules;
using Artemis.Profiles.Lua.Modules.Gui;
using Castle.Core.Internal; using Castle.Core.Internal;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
using Ninject; using Ninject;
@ -17,7 +19,6 @@ namespace Artemis.Managers
private readonly DeviceManager _deviceManager; private readonly DeviceManager _deviceManager;
private readonly IKernel _kernel; private readonly IKernel _kernel;
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly Script _luaScript;
private List<LuaModule> _luaModules; private List<LuaModule> _luaModules;
public LuaManager(IKernel kernel, ILogger logger, DeviceManager deviceManager) public LuaManager(IKernel kernel, ILogger logger, DeviceManager deviceManager)
@ -25,13 +26,17 @@ namespace Artemis.Managers
_kernel = kernel; _kernel = kernel;
_logger = logger; _logger = logger;
_deviceManager = deviceManager; _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 ProfileModel ProfileModel { get; private set; }
public KeyboardProvider KeyboardProvider { get; private set; } public KeyboardProvider KeyboardProvider { get; private set; }
public LuaProfileModule ProfileModule { get; private set; } public LuaProfileModule ProfileModule { get; private set; }
public LuaEventsModule EventsModule { get; private set; } public LuaEventsModule EventsModule { get; private set; }
public Script LuaScript { get; }
public ObservableCollection<EditorButton> EditorButtons { get; set; }
public void SetupLua(ProfileModel profileModel) public void SetupLua(ProfileModel profileModel)
{ {
@ -52,11 +57,11 @@ namespace Artemis.Managers
EventsModule = (LuaEventsModule) _luaModules.First(m => m.ModuleName == "Events"); EventsModule = (LuaEventsModule) _luaModules.First(m => m.ModuleName == "Events");
// Setup new state // Setup new state
_luaScript.Options.DebugPrint = LuaPrint; LuaScript.Options.DebugPrint = LuaPrint;
// Insert each module into the script's globals // Insert each module with a ModuleName into the script's globals
foreach (var luaModule in _luaModules) foreach (var luaModule in _luaModules.Where(m => m.ModuleName != null))
_luaScript.Globals[luaModule.ModuleName] = luaModule; LuaScript.Globals[luaModule.ModuleName] = luaModule;
// If there is no LUA script, don't bother executing the string // If there is no LUA script, don't bother executing the string
if (ProfileModel.LuaScript.IsNullOrEmpty()) if (ProfileModel.LuaScript.IsNullOrEmpty())
@ -66,9 +71,9 @@ namespace Artemis.Managers
{ {
lock (EventsModule.InvokeLock) lock (EventsModule.InvokeLock)
{ {
lock (_luaScript) lock (LuaScript)
{ {
_luaScript.DoString(ProfileModel.LuaScript); LuaScript.DoString(ProfileModel.LuaScript);
} }
} }
} }
@ -97,12 +102,12 @@ namespace Artemis.Managers
try try
{ {
_luaScript.Globals.Clear(); LuaScript.Globals.Clear();
_luaScript.Registry.Clear(); LuaScript.Registry.Clear();
_luaScript.Registry.RegisterConstants(); LuaScript.Registry.RegisterConstants();
_luaScript.Registry.RegisterCoreModules(CoreModules.Preset_SoftSandbox); LuaScript.Registry.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
_luaScript.Globals.RegisterConstants(); LuaScript.Globals.RegisterConstants();
_luaScript.Globals.RegisterCoreModules(CoreModules.Preset_SoftSandbox); LuaScript.Globals.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
} }
catch (NullReferenceException) catch (NullReferenceException)
{ {
@ -112,15 +117,15 @@ namespace Artemis.Managers
if (EventsModule != null) if (EventsModule != null)
lock (EventsModule.InvokeLock) lock (EventsModule.InvokeLock)
{ {
lock (_luaScript) lock (LuaScript)
{ {
_luaScript.DoString(""); LuaScript.DoString("");
} }
} }
else else
lock (_luaScript) lock (LuaScript)
{ {
_luaScript.DoString(""); LuaScript.DoString("");
} }
} }
@ -138,12 +143,12 @@ namespace Artemis.Managers
{ {
lock (EventsModule.InvokeLock) lock (EventsModule.InvokeLock)
{ {
lock (_luaScript) lock (LuaScript)
{ {
if (args != null) if (args != null)
_luaScript.Call(function, args); LuaScript.Call(function, args);
else else
_luaScript.Call(function); LuaScript.Call(function);
} }
} }
} }

View File

@ -108,6 +108,7 @@ namespace Artemis.Managers
public async void EnableProgram() public async void EnableProgram()
{ {
Logger.Debug("Enabling program"); Logger.Debug("Enabling program");
ProgramEnabled = true; ProgramEnabled = true;
await LoopManager.StartAsync(); await LoopManager.StartAsync();
@ -121,9 +122,12 @@ namespace Artemis.Managers
public void DisableProgram() public void DisableProgram()
{ {
Logger.Debug("Disabling program"); Logger.Debug("Disabling program");
foreach (var overlayModule in ModuleManager.OverlayModules) foreach (var overlayModule in ModuleManager.OverlayModules)
{
if (overlayModule.Settings.IsEnabled) if (overlayModule.Settings.IsEnabled)
overlayModule.Dispose(); overlayModule.Dispose();
}
LoopManager.Stop(); LoopManager.Stop();
ProgramEnabled = false; ProgramEnabled = false;
RaiseEnabledChangedEvent(new EnabledChangedEventArgs(ProgramEnabled)); RaiseEnabledChangedEvent(new EnabledChangedEventArgs(ProgramEnabled));

View File

@ -5,6 +5,7 @@ using Artemis.DAL;
using Artemis.Modules.Abstract; using Artemis.Modules.Abstract;
using Artemis.Settings; using Artemis.Settings;
using Artemis.Utilities; using Artemis.Utilities;
using Artemis.Utilities.ActiveWindowDetection;
using Ninject.Extensions.Logging; using Ninject.Extensions.Logging;
namespace Artemis.Managers namespace Artemis.Managers

View File

@ -27,8 +27,7 @@ namespace Artemis.Models
private FileSystemWatcher _watcher; private FileSystemWatcher _watcher;
private ModuleModel _luaModule; private ModuleModel _luaModule;
public ProfileEditorModel(WindowService windowService, MetroDialogService dialogService, public ProfileEditorModel(WindowService windowService, MetroDialogService dialogService, DeviceManager deviceManager, LuaManager luaManager)
DeviceManager deviceManager, LuaManager luaManager)
{ {
_windowService = windowService; _windowService = windowService;
_dialogService = dialogService; _dialogService = dialogService;
@ -50,7 +49,7 @@ namespace Artemis.Models
new ConstructorArgument("dataModel", dataModel), new ConstructorArgument("dataModel", dataModel),
new ConstructorArgument("layer", layer) 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 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()) if (layer.LayerType is FolderType || !layer.Children.Any())
@ -345,7 +344,8 @@ namespace Artemis.Models
private void DisposeLuaWatcher() private void DisposeLuaWatcher()
{ {
if (_watcher == null) return; if (_watcher == null)
return;
_watcher.Changed -= LuaFileChanged; _watcher.Changed -= LuaFileChanged;
_watcher.Dispose(); _watcher.Dispose();
_watcher = null; _watcher = null;
@ -360,8 +360,6 @@ namespace Artemis.Models
#region Rendering #region Rendering
#endregion #endregion
} }
} }

View File

@ -22,7 +22,7 @@
<!-- Header --> <!-- Header -->
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontSize="20" HorizontalAlignment="Left"> <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontSize="20" HorizontalAlignment="Left">
<Label.Content> <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.Content>
</Label> </Label>

View File

@ -29,7 +29,6 @@ namespace Artemis.Modules.Games.GtaV
public override void Enable() public override void Enable()
{ {
var process = System.Diagnostics.Process.GetProcessesByName("GTA5").First();
DllManager.PlaceLogitechDll(); DllManager.PlaceLogitechDll();
_pipeServer.PipeMessage += PipeServerOnPipeMessage; _pipeServer.PipeMessage += PipeServerOnPipeMessage;
base.Enable(); base.Enable();

View File

@ -36,7 +36,7 @@ namespace Artemis.Modules.Games.RocketLeague
{ {
if (!SettingsProvider.Load<GeneralSettings>().EnablePointersUpdate) 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; return;
} }

View 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; }
}
}

View 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));
}
}
}

View File

@ -0,0 +1,8 @@
using Artemis.Modules.Abstract;
namespace Artemis.Modules.Games.Terraria
{
public class TerrariaSettings : ModuleSettings
{
}
}

View 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>

View 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();
}
}
}

View 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).";
}
}
}

View File

@ -11,6 +11,7 @@ using Artemis.Events;
using Artemis.Managers; using Artemis.Managers;
using Artemis.Modules.Abstract; using Artemis.Modules.Abstract;
using Artemis.Utilities; using Artemis.Utilities;
using Artemis.Utilities.ActiveWindowDetection;
using CSCore.CoreAudioAPI; using CSCore.CoreAudioAPI;
using Newtonsoft.Json; using Newtonsoft.Json;
using SpotifyAPI.Local; using SpotifyAPI.Local;

View File

@ -1,12 +1,6 @@
<UserControl x:Class="Artemis.Modules.General.GeneralProfile.GeneralProfileView" <UserControl x:Class="Artemis.Modules.General.GeneralProfile.GeneralProfileView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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:x="http://schemas.microsoft.com/winfx/2006/xaml" 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">
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>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />

View File

@ -63,9 +63,15 @@ namespace Artemis.Profiles.Layers.Models
switch (ToggleType) switch (ToggleType)
{ {
case ToggleType.Enable: case ToggleType.Enable:
// Apply RenderAllowed only if this is the first keybind
if (index == 0)
layerModel.RenderAllowed = false;
action = () => layerModel.RenderAllowed = true; action = () => layerModel.RenderAllowed = true;
break; break;
case ToggleType.Disable: case ToggleType.Disable:
// Apply RenderAllowed only if this is the first keybind
if (index == 0)
layerModel.RenderAllowed = false;
action = () => layerModel.RenderAllowed = false; action = () => layerModel.RenderAllowed = false;
break; break;
case ToggleType.Toggle: case ToggleType.Toggle:

View File

@ -2,6 +2,7 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Media; using System.Windows.Media;
using Microsoft.Win32;
using SharpDX.Direct3D9; using SharpDX.Direct3D9;
namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing
@ -15,6 +16,14 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing
Width = Screen.PrimaryScreen.Bounds.Width; Width = Screen.PrimaryScreen.Bounds.Width;
Height = Screen.PrimaryScreen.Bounds.Height; 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) var presentParams = new PresentParameters(Width, Height)
{ {
Windowed = true, Windowed = true,
@ -24,7 +33,7 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing
_device = new Device(new Direct3D(), 0, DeviceType.Hardware, IntPtr.Zero, _device = new Device(new Direct3D(), 0, DeviceType.Hardware, IntPtr.Zero,
CreateFlags.SoftwareVertexProcessing, presentParams); CreateFlags.SoftwareVertexProcessing, presentParams);
_surface = Surface.CreateOffscreenPlain(_device, Width, Height, Format.A8R8G8B8, Pool.Scratch); _surface = Surface.CreateOffscreenPlain(_device, Width, Height, Format.A8R8G8B8, Pool.Scratch);
_buffer = new byte[Width*Height*4]; _buffer = new byte[Width * Height * 4];
} }
#endregion #endregion
@ -43,6 +52,19 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing
#region Methods #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() public byte[] CaptureScreen()
{ {
_device.GetFrontBufferData(0, _surface); _device.GetFrontBufferData(0, _surface);

View File

@ -97,18 +97,23 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
} }
} }
private LineSpectrum _lineSpectrum;
public LineSpectrum GetLineSpectrum(int barCount, ScalingStrategy scalingStrategy) public LineSpectrum GetLineSpectrum(int barCount, ScalingStrategy scalingStrategy)
{ {
if (_spectrumProvider == null) if (_spectrumProvider == null || barCount <= 0)
return null; return null;
return new LineSpectrum(FftSize)
{ if (_lineSpectrum == null)
SpectrumProvider = _spectrumProvider, _lineSpectrum = new LineSpectrum(FftSize)
UseAverage = true, {
BarCount = barCount, SpectrumProvider = _spectrumProvider,
IsXLogScale = true, UseAverage = true,
ScalingStrategy = scalingStrategy BarCount = barCount,
}; IsXLogScale = true,
ScalingStrategy = scalingStrategy
};
return _lineSpectrum;
} }
/// <summary> /// <summary>
@ -148,13 +153,13 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
if (Type == MmDeviceType.Input) if (Type == MmDeviceType.Input)
{ {
_soundIn = Device != null _soundIn = Device != null
? new WasapiCapture {Device = Device} ? new WasapiCapture { Device = Device }
: new WasapiCapture(); : new WasapiCapture();
} }
else else
{ {
_soundIn = Device != null _soundIn = Device != null
? new WasapiLoopbackCapture {Device = Device} ? new WasapiLoopbackCapture { Device = Device }
: new WasapiLoopbackCapture(); : new WasapiLoopbackCapture();
} }
@ -182,6 +187,7 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
} }
}; };
_lineSpectrum = null;
_singleSpectrum = new SingleSpectrum(FftSize, _spectrumProvider); _singleSpectrum = new SingleSpectrum(FftSize, _spectrumProvider);
_mayStop = false; _mayStop = false;

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
@ -26,6 +27,7 @@ namespace Artemis.Profiles.Layers.Types.Audio
private List<double> _lineValues; private List<double> _lineValues;
private AudioPropertiesModel _properties; private AudioPropertiesModel _properties;
private bool _subscribed; private bool _subscribed;
private DateTime _lastRender;
public AudioType(AudioCaptureManager audioCaptureManager) public AudioType(AudioCaptureManager audioCaptureManager)
{ {
@ -123,8 +125,7 @@ namespace Artemis.Profiles.Layers.Types.Audio
SubscribeToAudioChange(); SubscribeToAudioChange();
if (_audioCapture == null || newProperties.Device != _properties.Device || if (_audioCapture == null || newProperties.Device != _properties.Device || newProperties.DeviceType != _properties.DeviceType)
newProperties.DeviceType != _properties.DeviceType)
{ {
var device = GetMmDevice(); var device = GetMmDevice();
if (device != null) if (device != null)
@ -153,17 +154,19 @@ namespace Artemis.Profiles.Layers.Types.Audio
currentHeight = layerModel.Width; 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; _lines = currentLines;
_lineSpectrum = _audioCapture.GetLineSpectrum(_lines, ScalingStrategy.Decibel); _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) if (newLineValues != null)
{
_lineValues = newLineValues; _lineValues = newLineValues;
_lastRender = DateTime.Now;
}
} }
public void SetupProperties(LayerModel layerModel) public void SetupProperties(LayerModel layerModel)

View 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; }
}
}

View 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);
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View File

@ -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>

View File

@ -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();
}
}
}

View File

@ -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);
}
}
}

View File

@ -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) lock (InvokeLock)
{ {

View 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());
}
}
}

View 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();
}
}
}

View File

@ -38,6 +38,7 @@ namespace Artemis.Profiles
public int Width { get; set; } public int Width { get; set; }
public int Height { get; set; } public int Height { get; set; }
public string LuaScript { get; set; } public string LuaScript { get; set; }
public string LuaStorage { get; set; }
[JsonIgnore] [JsonIgnore]
public string Slug => new string(Name.Where(ch => !_invalidFileNameChars.Contains(ch)).ToArray()); public string Slug => new string(Name.Where(ch => !_invalidFileNameChars.Contains(ch)).ToArray());

View File

@ -53,7 +53,7 @@ using System.Windows;
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.9.0.0")] [assembly: AssemblyVersion("1.10.0.0")]
[assembly: AssemblyFileVersion("1.9.0.0")] [assembly: AssemblyFileVersion("1.10.0.0")]
[assembly: InternalsVisibleTo("Artemis.Explorables")] [assembly: InternalsVisibleTo("Artemis.Explorables")]

View 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.");
}
}
}

View File

@ -14,23 +14,25 @@ namespace Artemis.Services
_kernel = kernel; _kernel = kernel;
} }
public T ShowWindow<T>(string windowName, params IParameter[] param) where T : class public T ShowWindow<T>(string windowName, dynamic settings = null, params IParameter[] param) where T : class
{ {
var windowManager = new WindowManager(); var windowManager = new WindowManager();
var viewModel = _kernel.Get<T>(param); var viewModel = _kernel.Get<T>(param);
dynamic settings = new ExpandoObject(); if (settings == null)
settings = new ExpandoObject();
settings.Title = windowName; settings.Title = windowName;
windowManager.ShowWindow(viewModel, null, settings); windowManager.ShowWindow(viewModel, null, settings);
return viewModel; return viewModel;
} }
public T ShowDialog<T>(string dialogName, params IParameter[] param) where T : class public T ShowDialog<T>(string dialogName, dynamic settings = null, params IParameter[] param) where T : class
{ {
var windowManager = new WindowManager(); var windowManager = new WindowManager();
var viewModel = _kernel.Get<T>(param); var viewModel = _kernel.Get<T>(param);
dynamic settings = new ExpandoObject(); if (settings == null)
settings = new ExpandoObject();
settings.Title = dialogName; settings.Title = dialogName;
windowManager.ShowDialog(viewModel, null, settings); windowManager.ShowDialog(viewModel, null, settings);
return viewModel; return viewModel;

View File

@ -5,9 +5,11 @@ using System.Windows;
using Artemis.DAL; using Artemis.DAL;
using Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing; using Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing;
using Artemis.Utilities; using Artemis.Utilities;
using Artemis.Utilities.ActiveWindowDetection;
using Caliburn.Micro; using Caliburn.Micro;
using MahApps.Metro; using MahApps.Metro;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Squirrel; using Squirrel;
namespace Artemis.Settings namespace Artemis.Settings
@ -68,6 +70,11 @@ namespace Artemis.Settings
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public string LogLevel { get; set; } 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 Version LastRanVersion { get; set; }
public void Save() public void Save()
@ -75,6 +82,7 @@ namespace Artemis.Settings
SettingsProvider.Save(this); SettingsProvider.Save(this);
Logging.SetupLogging(LogLevel); Logging.SetupLogging(LogLevel);
ActiveWindowHelper.SetActiveWindowDetectionType(ActiveWindowDetection);
ApplyAutorun(); ApplyAutorun();
ApplyTheme(); ApplyTheme();
ApplyGamestatePort(); ApplyGamestatePort();

View File

@ -8,6 +8,7 @@ namespace Artemis.Settings
{ {
public GamePointersCollection RocketLeague { get; set; } public GamePointersCollection RocketLeague { get; set; }
public GamePointersCollection WorldOfWarcraft { get; set; } public GamePointersCollection WorldOfWarcraft { get; set; }
public GamePointersCollection Terraria { get; set; }
public void Save() public void Save()
{ {

View File

@ -210,7 +210,7 @@
ItemsSource="{Binding AvailableBrushTypes, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center"> ItemsSource="{Binding AvailableBrushTypes, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center">
<ListBox.ItemsPanel> <ListBox.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
<UniformGrid Rows="1" Columns="4" /> <UniformGrid Rows="1" />
</ItemsPanelTemplate> </ItemsPanelTemplate>
</ListBox.ItemsPanel> </ListBox.ItemsPanel>
<ListBox.ItemContainerStyle> <ListBox.ItemContainerStyle>

View File

@ -0,0 +1,9 @@
namespace Artemis.Utilities.ActiveWindowDetection
{
public enum ActiveWindowDetectionType
{
Disabled = -1,
Events = 0,
Timer = 1,
}
}

View File

@ -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
}
}

View File

@ -2,9 +2,9 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
namespace Artemis.Utilities namespace Artemis.Utilities.ActiveWindowDetection
{ {
public static class ActiveWindowHelper public class EventActiveWindowDetector : IActiveWindowDetector
{ {
#region DLL-Imports #region DLL-Imports
@ -14,7 +14,7 @@ namespace Artemis.Utilities
[DllImport("user32.dll")] [DllImport("user32.dll")]
private static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, 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")] [DllImport("user32.dll")]
private static extern bool UnhookWinEvent(IntPtr hWinEventHook); private static extern bool UnhookWinEvent(IntPtr hWinEventHook);
@ -41,47 +41,46 @@ namespace Artemis.Utilities
#region Properties & Fields #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. // 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 WinEventDelegate _activeWindowChangedDelegate;
private static IntPtr _activeWindowEventHook; private IntPtr _activeWindowEventHook;
private static WinEventDelegate _windowTitleChangedDelegate; private WinEventDelegate _windowTitleChangedDelegate;
private static IntPtr _windowTitleEventHook; private IntPtr _windowTitleEventHook;
private static WinEventDelegate _windowMinimizedChangedDelegate; private WinEventDelegate _windowMinimizedChangedDelegate;
private static IntPtr _windowMinimizedEventHook; private IntPtr _windowMinimizedEventHook;
private static IntPtr _activeWindow; private IntPtr _activeWindow;
public static string ActiveWindowProcessName { get; private set; } = string.Empty; public string ActiveWindowProcessName { get; private set; } = string.Empty;
public static string ActiveWindowWindowTitle { get; private set; } = string.Empty; public string ActiveWindowWindowTitle { get; private set; } = string.Empty;
public static bool MainWindowActive => ActiveWindowProcessName.Contains("Artemis");
#endregion #endregion
#region Methods #region Methods
private static void ActiveWindowChanged(IntPtr hWinEventHook, uint eventType, private void ActiveWindowChanged(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{ {
UpdateForWindow(hwnd); UpdateForWindow(hwnd);
} }
private static void WindowTitleChanged(IntPtr hWinEventHook, uint eventType, private void WindowTitleChanged(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{ {
if (_activeWindow == hwnd) if (_activeWindow == hwnd)
UpdateForWindow(hwnd); UpdateForWindow(hwnd);
} }
private static void WindowMinimizedChanged(IntPtr hWinEventHook, uint eventType, private void WindowMinimizedChanged(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) 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: 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. // 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); UpdateForWindow(hwnd);
} }
private static void UpdateForWindow(IntPtr hwnd) private void UpdateForWindow(IntPtr hwnd)
{ {
_activeWindow = hwnd; _activeWindow = hwnd;
@ -89,13 +88,13 @@ namespace Artemis.Utilities
ActiveWindowWindowTitle = GetActiveWindowTitle(hwnd) ?? string.Empty; ActiveWindowWindowTitle = GetActiveWindowTitle(hwnd) ?? string.Empty;
} }
private static string GetActiveWindowProcessName(IntPtr hwnd) private string GetActiveWindowProcessName(IntPtr hwnd)
{ {
try try
{ {
uint pid; uint pid;
GetWindowThreadProcessId(hwnd, out pid); GetWindowThreadProcessId(hwnd, out pid);
return System.Diagnostics.Process.GetProcessById((int) pid).ProcessName; return System.Diagnostics.Process.GetProcessById((int)pid).ProcessName;
} }
catch catch
{ {
@ -103,7 +102,7 @@ namespace Artemis.Utilities
} }
} }
private static string GetActiveWindowTitle(IntPtr hwnd) private string GetActiveWindowTitle(IntPtr hwnd)
{ {
try try
{ {
@ -116,7 +115,7 @@ namespace Artemis.Utilities
} }
} }
public static void Initialize() public void Initialize()
{ {
try try
{ {
@ -124,21 +123,21 @@ namespace Artemis.Utilities
{ {
_activeWindowChangedDelegate = ActiveWindowChanged; _activeWindowChangedDelegate = ActiveWindowChanged;
_activeWindowEventHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, _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) if (_windowTitleEventHook == IntPtr.Zero)
{ {
_windowTitleChangedDelegate = WindowTitleChanged; _windowTitleChangedDelegate = WindowTitleChanged;
_windowTitleEventHook = SetWinEventHook(EVENT_OBJECT_NAMECHANGE, EVENT_OBJECT_NAMECHANGE, _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) if (_windowMinimizedEventHook == IntPtr.Zero)
{ {
_windowMinimizedChangedDelegate = WindowMinimizedChanged; _windowMinimizedChangedDelegate = WindowMinimizedChanged;
_windowMinimizedEventHook = SetWinEventHook(EVENT_SYSTEM_MINIMIZEEND, EVENT_SYSTEM_MINIMIZEEND, _windowMinimizedEventHook = SetWinEventHook(EVENT_SYSTEM_MINIMIZEEND, EVENT_SYSTEM_MINIMIZEEND,
IntPtr.Zero, _windowMinimizedChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT); IntPtr.Zero, _windowMinimizedChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
} }
} }
catch catch
@ -147,7 +146,7 @@ namespace Artemis.Utilities
} }
} }
public static void Dispose() public void Dispose()
{ {
try try
{ {

View File

@ -0,0 +1,12 @@
using System;
namespace Artemis.Utilities.ActiveWindowDetection
{
public interface IActiveWindowDetector : IDisposable
{
string ActiveWindowProcessName { get; }
string ActiveWindowWindowTitle { get; }
void Initialize();
}
}

View File

@ -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
}
}

View File

@ -37,8 +37,11 @@ namespace Artemis.Utilities.DataReaders
try try
{ {
// Change the registry key to point to the fake DLL // 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 doesn't exist yet on systems without LGS installed
key?.SetValue(null, DllPath + @"\LogitechLed.dll"); 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 // Make sure the fake DLL is in place
if (!Directory.Exists(DllPath)) if (!Directory.Exists(DllPath))

View File

@ -148,6 +148,8 @@ namespace Artemis.Utilities
offsetSettings.RocketLeague = pointers.FirstOrDefault(p => p.Game == "RocketLeague"); offsetSettings.RocketLeague = pointers.FirstOrDefault(p => p.Game == "RocketLeague");
if (pointers.FirstOrDefault(p => p.Game == "WorldOfWarcraft") != null) if (pointers.FirstOrDefault(p => p.Game == "WorldOfWarcraft") != null)
offsetSettings.WorldOfWarcraft = pointers.FirstOrDefault(p => p.Game == "WorldOfWarcraft"); 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(); offsetSettings.Save();
} }

View File

@ -8,6 +8,7 @@ using Artemis.Events;
using Artemis.Managers; using Artemis.Managers;
using Artemis.Services; using Artemis.Services;
using Artemis.Settings; using Artemis.Settings;
using Artemis.Utilities.ActiveWindowDetection;
using Caliburn.Micro; using Caliburn.Micro;
using MahApps.Metro.Controls; using MahApps.Metro.Controls;
using NLog; using NLog;
@ -37,6 +38,8 @@ namespace Artemis.ViewModels.Flyouts
LogLevels = new BindableCollection<string>(); LogLevels = new BindableCollection<string>();
LogLevels.AddRange(LogLevel.AllLoggingLevels.Select(l => l.Name)); LogLevels.AddRange(LogLevel.AllLoggingLevels.Select(l => l.Name));
ActiveWindowDetections = new BindableCollection<ActiveWindowDetectionType>(Enum.GetValues(typeof(ActiveWindowDetectionType)).Cast<ActiveWindowDetectionType>());
PropertyChanged += KeyboardUpdater; PropertyChanged += KeyboardUpdater;
mainManager.EnabledChanged += MainManagerEnabledChanged; mainManager.EnabledChanged += MainManagerEnabledChanged;
mainManager.ModuleManager.EffectChanged += EffectManagerEffectChanged; mainManager.ModuleManager.EffectChanged += EffectManagerEffectChanged;
@ -96,6 +99,7 @@ namespace Artemis.ViewModels.Flyouts
public string VersionText => "Artemis " + Assembly.GetExecutingAssembly().GetName().Version; public string VersionText => "Artemis " + Assembly.GetExecutingAssembly().GetName().Version;
public BindableCollection<string> LogLevels { get; set; } public BindableCollection<string> LogLevels { get; set; }
public BindableCollection<ActiveWindowDetectionType> ActiveWindowDetections { get; set; }
public string SelectedTheme 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 public string SelectedKeyboardProvider
{ {
get { return _selectedKeyboardProvider; } get { return _selectedKeyboardProvider; }

View File

@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -12,7 +11,6 @@ using System.Windows.Forms;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using Artemis.DAL; using Artemis.DAL;
using Artemis.DeviceProviders;
using Artemis.Events; using Artemis.Events;
using Artemis.Managers; using Artemis.Managers;
using Artemis.Models; using Artemis.Models;
@ -21,10 +19,12 @@ using Artemis.Profiles;
using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Layers.Models;
using Artemis.Profiles.Layers.Types.Folder; using Artemis.Profiles.Layers.Types.Folder;
using Artemis.Profiles.Lua.Modules.Gui;
using Artemis.Properties; using Artemis.Properties;
using Artemis.Services; using Artemis.Services;
using Artemis.Styles.DropTargetAdorners; using Artemis.Styles.DropTargetAdorners;
using Artemis.Utilities; using Artemis.Utilities;
using Artemis.Utilities.ActiveWindowDetection;
using Caliburn.Micro; using Caliburn.Micro;
using Castle.Components.DictionaryAdapter; using Castle.Components.DictionaryAdapter;
using GongSolutions.Wpf.DragDrop; using GongSolutions.Wpf.DragDrop;
@ -46,21 +46,20 @@ namespace Artemis.ViewModels
{ {
public sealed class ProfileEditorViewModel : Screen, IDropTarget public sealed class ProfileEditorViewModel : Screen, IDropTarget
{ {
private readonly KeybindModel _copyKeybind;
private readonly DeviceManager _deviceManager; private readonly DeviceManager _deviceManager;
private readonly MetroDialogService _dialogService; private readonly MetroDialogService _dialogService;
private readonly LoopManager _loopManager; private readonly LoopManager _loopManager;
private readonly ModuleModel _moduleModel; private readonly ModuleModel _moduleModel;
private readonly KeybindModel _copyKeybind; private readonly KeybindModel _pasteKeybind;
private ImageSource _keyboardPreview; private ImageSource _keyboardPreview;
private ObservableCollection<LayerModel> _layers; private ObservableCollection<LayerModel> _layers;
private readonly KeybindModel _pasteKeybind;
private ObservableCollection<string> _profileNames; private ObservableCollection<string> _profileNames;
private bool _saving; private bool _saving;
private LayerModel _selectedLayer; private LayerModel _selectedLayer;
private bool _showAll; private bool _showAll;
public ProfileEditorViewModel(ProfileEditorModel profileEditorModel, DeviceManager deviceManager, public ProfileEditorViewModel(ProfileEditorModel profileEditorModel, DeviceManager deviceManager, LoopManager loopManager, LuaManager luaManager, ModuleModel moduleModel, MetroDialogService dialogService)
LoopManager loopManager, ModuleModel moduleModel, MetroDialogService dialogService)
{ {
_deviceManager = deviceManager; _deviceManager = deviceManager;
_loopManager = loopManager; _loopManager = loopManager;
@ -72,6 +71,7 @@ namespace Artemis.ViewModels
ProfileNames = new ObservableCollection<string>(); ProfileNames = new ObservableCollection<string>();
Layers = new ObservableCollection<LayerModel>(); Layers = new ObservableCollection<LayerModel>();
ProfileEditorModel = profileEditorModel; ProfileEditorModel = profileEditorModel;
LuaManager = luaManager;
ShowAll = true; ShowAll = true;
PropertyChanged += EditorStateHandler; PropertyChanged += EditorStateHandler;
@ -102,6 +102,11 @@ namespace Artemis.ViewModels
#region LUA #region LUA
public void ClickedLuaButton(EditorButton button)
{
button.Invoke();
}
public void EditLua() public void EditLua()
{ {
if (SelectedProfile == null) if (SelectedProfile == null)
@ -123,6 +128,7 @@ namespace Artemis.ViewModels
#region Properties #region Properties
public ProfileEditorModel ProfileEditorModel { get; } public ProfileEditorModel ProfileEditorModel { get; }
public LuaManager LuaManager { get; }
public ObservableCollection<string> ProfileNames public ObservableCollection<string> ProfileNames
{ {
@ -325,7 +331,7 @@ namespace Artemis.ViewModels
public void LayerToClipboard() public void LayerToClipboard()
{ {
if (SelectedLayer == null || !ActiveWindowHelper.MainWindowActive) if (SelectedLayer == null || !ActiveWindowHelper.MainWindowActive || !IsActive)
return; return;
// Probably not how the cool kids do it but leveraging on JsonConvert gives flawless serialization // 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() public void ClipboardToLayer()
{ {
if (!ActiveWindowHelper.MainWindowActive) if (!ActiveWindowHelper.MainWindowActive || !IsActive)
return; return;
GeneralHelpers.ExecuteSta(() => try
{ {
var data = (string) Clipboard.GetData("layer"); GeneralHelpers.ExecuteSta(() =>
if (data == null)
return;
var layerModel = JsonConvert.DeserializeObject<LayerModel>(data);
if (layerModel == null)
return;
if (SelectedLayer != null)
{ {
SelectedLayer.InsertAfter(layerModel); var data = (string) Clipboard.GetData("layer");
} if (data == null)
else return;
{
SelectedProfile.Layers.Add(layerModel); var layerModel = JsonConvert.DeserializeObject<LayerModel>(data);
SelectedProfile.FixOrder(); if (layerModel == null)
} return;
Execute.OnUIThread(() => UpdateLayerList(layerModel));
}); 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) private void UpdateLayerList(LayerModel selectModel)
@ -405,6 +416,9 @@ namespace Artemis.ViewModels
if (_saving || SelectedProfile == null || _deviceManager.ChangingKeyboard) if (_saving || SelectedProfile == null || _deviceManager.ChangingKeyboard)
return; return;
SelectedProfile.Width = _deviceManager.ActiveKeyboard.Width;
SelectedProfile.Height = _deviceManager.ActiveKeyboard.Height;
_saving = true; _saving = true;
try try
{ {
@ -421,8 +435,7 @@ namespace Artemis.ViewModels
{ {
if (_deviceManager.ActiveKeyboard == null) if (_deviceManager.ActiveKeyboard == null)
{ {
_dialogService.ShowMessageBox("Cannot add profile.", _dialogService.ShowMessageBox("Cannot add profile.", "To add a profile, please select a keyboard in the options menu first.");
"To add a profile, please select a keyboard in the options menu first.");
return; return;
} }
@ -666,7 +679,7 @@ namespace Artemis.ViewModels
return; return;
var pos = GetScaledPosition(e); 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) if (hoverLayer != null)
SelectedLayer = hoverLayer; SelectedLayer = hoverLayer;
@ -682,7 +695,7 @@ namespace Artemis.ViewModels
return; return;
var pos = GetScaledPosition(e); 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); HandleDragging(e, pos.X, pos.Y, hoverLayer);
@ -701,11 +714,10 @@ namespace Artemis.ViewModels
: Cursors.SizeAll; : Cursors.SizeAll;
} }
else else
{
KeyboardPreviewCursor = Cursors.Hand; KeyboardPreviewCursor = Cursors.Hand;
}
} }
private Point GetScaledPosition(MouseEventArgs e) private Point GetScaledPosition(MouseEventArgs e)
{ {
var previewSettings = _deviceManager.ActiveKeyboard.PreviewSettings; var previewSettings = _deviceManager.ActiveKeyboard.PreviewSettings;
@ -716,16 +728,25 @@ namespace Artemis.ViewModels
var heightScale = sourceImage.ActualHeight / _deviceManager.ActiveKeyboard.PreviewSettings.BackgroundRectangle.Height; var heightScale = sourceImage.ActualHeight / _deviceManager.ActiveKeyboard.PreviewSettings.BackgroundRectangle.Height;
// Remove the preview settings' offset from the cursor postion // Remove the preview settings' offset from the cursor postion
pos.X = pos.X - (previewSettings.OverlayRectangle.X * widthScale); pos.X = pos.X - previewSettings.OverlayRectangle.X * widthScale;
pos.Y = pos.Y - (previewSettings.OverlayRectangle.Y * heightScale); 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 // 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)); pos.Y = pos.Y * (SelectedProfile.Height / (previewSettings.OverlayRectangle.Height * heightScale));
return pos; 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 public Cursor KeyboardPreviewCursor
{ {
get { return _keyboardPreviewCursor; } get { return _keyboardPreviewCursor; }

View File

@ -6,7 +6,7 @@
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls" xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:cal="http://www.caliburnproject.org" xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="300"> d:DesignHeight="600" d:DesignWidth="310">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
@ -25,6 +25,7 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
@ -95,29 +96,35 @@
HorizontalAlignment="Right" Width="140" Minimum="1" Maximum="60" HorizontalAlignment="Right" Width="140" Minimum="1" Maximum="60"
Value="{Binding Path=GeneralSettings.ScreenCaptureFPS, Mode=TwoWay}" /> Value="{Binding Path=GeneralSettings.ScreenCaptureFPS, Mode=TwoWay}" />
<!-- Logging -->
<Label Grid.Row="9" Grid.Column="0" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Left" <Label Grid.Row="9" Grid.Column="0" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Left"
Content="Log level:" /> Content="Active window detection" />
<ComboBox Grid.Row="9" Grid.Column="1" x:Name="LogLevels" Margin="10" VerticalAlignment="Center" <ComboBox Grid.Row="9" Grid.Column="1" x:Name="ActiveWindowDetections" Margin="10" VerticalAlignment="Center"
HorizontalAlignment="Right" HorizontalAlignment="Right"
Width="140" /> 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" VerticalAlignment="Center" Width="100" HorizontalAlignment="Left"
Style="{DynamicResource SquareButtonStyle}" /> 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" VerticalAlignment="Center" Width="100" HorizontalAlignment="Right"
Style="{DynamicResource SquareButtonStyle}" /> Style="{DynamicResource SquareButtonStyle}" />
<!-- Buttons --> <!-- 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" VerticalAlignment="Center" HorizontalAlignment="Left" Width="100"
Style="{DynamicResource SquareButtonStyle}" /> 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" VerticalAlignment="Center" HorizontalAlignment="Right" Width="100"
Style="{DynamicResource SquareButtonStyle}" /> Style="{DynamicResource SquareButtonStyle}" />
<!-- Version --> <!-- 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> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />

View File

@ -1,16 +1,8 @@
<UserControl x:Class="Artemis.Views.ProfileEditorView" <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="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 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:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:itemBehaviours="clr-namespace:Artemis.ItemBehaviours"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:dragDrop="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop" xmlns:converters="clr-namespace:Artemis.Utilities.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls" mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="1060">
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> <UserControl.Resources>
<converters:LayerOrderConverter x:Key="LayerOrderConverter" /> <converters:LayerOrderConverter x:Key="LayerOrderConverter" />
</UserControl.Resources> </UserControl.Resources>
@ -22,7 +14,8 @@
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="40" /> <RowDefinition Height="40" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="60" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Preview --> <!-- Preview -->
@ -32,7 +25,9 @@
<Border.Effect> <Border.Effect>
<DropShadowEffect x:Name="ShadowEffect" ShadowDepth="0" Color="{DynamicResource HighlightColor}" Opacity="1" BlurRadius="25" /> <DropShadowEffect x:Name="ShadowEffect" ShadowDepth="0" Color="{DynamicResource HighlightColor}" Opacity="1" BlurRadius="25" />
</Border.Effect> </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 MouseMove] = [Action MouseMoveKeyboardPreview($eventArgs)];
[Event MouseDown] = [Action MouseDownKeyboardPreview($eventArgs)]; [Event MouseDown] = [Action MouseDownKeyboardPreview($eventArgs)];
[Event MouseUp] = [Action MouseUpKeyboardPreview($eventArgs)]" /> [Event MouseUp] = [Action MouseUpKeyboardPreview($eventArgs)]" />
@ -43,8 +38,8 @@
<StackPanel Orientation="Horizontal" Margin="0,5,0,0"> <StackPanel Orientation="Horizontal" Margin="0,5,0,0">
<Label Content="Active profile" /> <Label Content="Active profile" />
<ComboBox Width="220" VerticalAlignment="Top" x:Name="ProfileNames" Margin="5,0,0,0" /> <ComboBox Width="220" VerticalAlignment="Top" x:Name="ProfileNames" Margin="5,0,0,0" />
<Button x:Name="AddProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" <Button x:Name="AddProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Add profile"> ToolTip="Add profile">
<Button.Content> <Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12"> <Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
<Rectangle.OpacityMask> <Rectangle.OpacityMask>
@ -53,9 +48,8 @@
</Rectangle> </Rectangle>
</Button.Content> </Button.Content>
</Button> </Button>
<Button x:Name="RenameProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" <Button x:Name="RenameProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Rename profile" ToolTip="Rename profile" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}">
IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}">
<Button.Content> <Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12"> <Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
<Rectangle.OpacityMask> <Rectangle.OpacityMask>
@ -74,7 +68,8 @@
</Rectangle> </Rectangle>
</Button.Content> </Button.Content>
</Button> </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> <Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12"> <Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
<Rectangle.OpacityMask> <Rectangle.OpacityMask>
@ -84,17 +79,12 @@
</Button.Content> </Button.Content>
</Button> </Button>
</StackPanel> </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>
<StackPanel Grid.Column="0" Grid.Row="2" Orientation="Horizontal" Margin="0,5,0,0" HorizontalAlignment="Right"> <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}" <Button x:Name="ImportProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Height="26" HorizontalAlignment="Right">
Height="26" HorizontalAlignment="Right">
<Button.Content> <Button.Content>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Rectangle <Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12" Margin="3,0">
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
Width="12" Height="12" Margin="3,0">
<Rectangle.OpacityMask> <Rectangle.OpacityMask>
<VisualBrush Visual="{StaticResource appbar_cabinet_in}" Stretch="Fill" /> <VisualBrush Visual="{StaticResource appbar_cabinet_in}" Stretch="Fill" />
</Rectangle.OpacityMask> </Rectangle.OpacityMask>
@ -103,13 +93,11 @@
</StackPanel> </StackPanel>
</Button.Content> </Button.Content>
</Button> </Button>
<Button x:Name="ExportProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" <Button x:Name="ExportProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" IsEnabled="{Binding ProfileSelected}"> IsEnabled="{Binding ProfileSelected}">
<Button.Content> <Button.Content>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Rectangle <Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12" Margin="3,0">
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
Width="12" Height="12" Margin="3,0">
<Rectangle.OpacityMask> <Rectangle.OpacityMask>
<VisualBrush Visual="{StaticResource appbar_cabinet_out}" Stretch="Fill" /> <VisualBrush Visual="{StaticResource appbar_cabinet_out}" Stretch="Fill" />
</Rectangle.OpacityMask> </Rectangle.OpacityMask>
@ -118,14 +106,11 @@
</StackPanel> </StackPanel>
</Button.Content> </Button.Content>
</Button> </Button>
<Button x:Name="EditLua" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Height="26" <Button x:Name="EditLua" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
HorizontalAlignment="Right" Margin="10,0,0,0" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}" Visibility="{Binding Path=LuaButtonVisible, Converter={StaticResource BoolToVis} }">
Visibility="{Binding Path=LuaButtonVisible, Converter={StaticResource BoolToVis} }">
<Button.Content> <Button.Content>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Rectangle <Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12" Margin="3,0">
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
Width="12" Height="12" Margin="3,0">
<Rectangle.OpacityMask> <Rectangle.OpacityMask>
<VisualBrush Visual="{StaticResource appbar_code_xml}" Stretch="Fill" /> <VisualBrush Visual="{StaticResource appbar_code_xml}" Stretch="Fill" />
</Rectangle.OpacityMask> </Rectangle.OpacityMask>
@ -154,8 +139,7 @@
ItemsSource="{Binding Path=Layers, Converter={StaticResource LayerOrderConverter}, ConverterParameter=Order}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}" ItemsSource="{Binding Path=Layers, Converter={StaticResource LayerOrderConverter}, ConverterParameter=Order}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"
cal:Message.Attach="[Event MouseDoubleClick] = [Action EditLayerFromDoubleClick]"> cal:Message.Attach="[Event MouseDoubleClick] = [Action EditLayerFromDoubleClick]">
<i:Interaction.Behaviors> <i:Interaction.Behaviors>
<itemBehaviours:BindableSelectedItemBehavior <itemBehaviours:BindableSelectedItemBehavior SelectedItem="{Binding SelectedLayer, Mode=TwoWay}" />
SelectedItem="{Binding SelectedLayer, Mode=TwoWay}" />
</i:Interaction.Behaviors> </i:Interaction.Behaviors>
<TreeView.Resources> <TreeView.Resources>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" /> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
@ -185,9 +169,8 @@
</TreeView> </TreeView>
</Border> </Border>
<StackPanel Grid.Column="1" Grid.Row="2" Orientation="Horizontal" Margin="0,5,0,0" HorizontalAlignment="Right"> <StackPanel Grid.Column="1" Grid.Row="2" Orientation="Horizontal" Margin="0,5,0,0" HorizontalAlignment="Right">
<Button x:Name="AddLayer" VerticalAlignment="Top" <Button x:Name="AddLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}" Width="26" Height="26"
Style="{DynamicResource SquareButtonStyle}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}" ToolTip="Add layer" HorizontalAlignment="Left">
Width="26" Height="26" ToolTip="Add layer" HorizontalAlignment="Left">
<Button.Content> <Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12"> <Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
<Rectangle.OpacityMask> <Rectangle.OpacityMask>
@ -196,9 +179,8 @@
</Rectangle> </Rectangle>
</Button.Content> </Button.Content>
</Button> </Button>
<Button x:Name="AddFolder" VerticalAlignment="Top" <Button x:Name="AddFolder" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}" Width="26" Height="26"
Style="{DynamicResource SquareButtonStyle}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}" ToolTip="Add folder" HorizontalAlignment="Left" Margin="10,0,0,0">
Width="26" Height="26" ToolTip="Add folder" HorizontalAlignment="Left" Margin="10,0,0,0">
<Button.Content> <Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12"> <Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
<Rectangle.OpacityMask> <Rectangle.OpacityMask>
@ -207,8 +189,7 @@
</Rectangle> </Rectangle>
</Button.Content> </Button.Content>
</Button> </Button>
<Button x:Name="EditLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" <Button x:Name="EditLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Edit layer"
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Edit layer"
IsEnabled="{Binding Path=LayerSelected}"> IsEnabled="{Binding Path=LayerSelected}">
<Button.Content> <Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12"> <Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
@ -218,9 +199,8 @@
</Rectangle> </Rectangle>
</Button.Content> </Button.Content>
</Button> </Button>
<Button x:Name="CloneLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" <Button x:Name="CloneLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Duplicate layer" ToolTip="Duplicate layer" IsEnabled="{Binding Path=LayerSelected}">
IsEnabled="{Binding Path=LayerSelected}">
<Button.Content> <Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12"> <Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
<Rectangle.OpacityMask> <Rectangle.OpacityMask>
@ -229,9 +209,8 @@
</Rectangle> </Rectangle>
</Button.Content> </Button.Content>
</Button> </Button>
<Button x:Name="RemoveLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" <Button x:Name="RemoveLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Delete layer" ToolTip="Delete layer" IsEnabled="{Binding Path=LayerSelected}">
IsEnabled="{Binding Path=LayerSelected}">
<Button.Content> <Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12"> <Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
<Rectangle.OpacityMask> <Rectangle.OpacityMask>
@ -241,5 +220,21 @@
</Button.Content> </Button.Content>
</Button> </Button>
</StackPanel> </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> </Grid>
</UserControl> </UserControl>

View File

@ -22,7 +22,7 @@
<ProjectGuid>{1A349CF5-2008-41E8-AC13-874CBBCDFA0A}</ProjectGuid> <ProjectGuid>{1A349CF5-2008-41E8-AC13-874CBBCDFA0A}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>LightFX2Artemis</RootNamespace> <RootNamespace>LightFX2Artemis</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

View File

@ -23,6 +23,7 @@
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>LogiLed2Artemis</RootNamespace> <RootNamespace>LogiLed2Artemis</RootNamespace>
<ProjectName>LogiLed2Artemis</ProjectName> <ProjectName>LogiLed2Artemis</ProjectName>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

View File

@ -21,7 +21,7 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{39711909-C1D5-46CE-A9EA-2D561692EA47}</ProjectGuid> <ProjectGuid>{39711909-C1D5-46CE-A9EA-2D561692EA47}</ProjectGuid>
<RootNamespace>Razer2Artemis</RootNamespace> <RootNamespace>Razer2Artemis</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">