diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj
index ae8690d13..198390572 100644
--- a/Artemis/Artemis/Artemis.csproj
+++ b/Artemis/Artemis/Artemis.csproj
@@ -318,7 +318,7 @@
-
+
@@ -611,7 +611,6 @@
-
DebugView.xaml
@@ -687,6 +686,7 @@
Code
+
diff --git a/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProL.cs b/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProL.cs
index a5cd4bb66..dc9873fdf 100644
--- a/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProL.cs
+++ b/Artemis/Artemis/DeviceProviders/CoolerMaster/MasterkeysProL.cs
@@ -1,9 +1,10 @@
using System.Drawing;
-using System.Drawing.Imaging;
-using System.Runtime.InteropServices;
+using System.Linq;
+using System.Threading;
using System.Windows;
using System.Windows.Forms;
using Artemis.DeviceProviders.CoolerMaster.Utilities;
+using Artemis.DeviceProviders.Logitech.Utilities;
using Artemis.Properties;
using Artemis.Utilities;
@@ -11,6 +12,8 @@ namespace Artemis.DeviceProviders.CoolerMaster
{
public class MasterkeysProL : KeyboardProvider
{
+ private bool _hasControl;
+
public MasterkeysProL()
{
Name = "CM Masterkeys Pro L";
@@ -22,76 +25,62 @@ namespace Artemis.DeviceProviders.CoolerMaster
Height = 6;
Width = 22;
- // TODO
- PreviewSettings = new PreviewSettings(665, 175, new Thickness(0, -15, 0, 0), Resources.blackwidow);
+
+ PreviewSettings = new PreviewSettings(670, 189, new Thickness(-2, -5, 0, 0), Resources.masterkeys_pro_l);
}
public override void Disable()
{
- CmSdk.EnableLedControl(false);
+ if (_hasControl)
+ {
+ CmSdk.EnableLedControl(false);
+ Thread.Sleep(500);
+ }
+ _hasControl = false;
}
public override bool CanEnable()
{
- return true;
+ CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MKeys_L);
+
+ // Doesn't seem reliable but better than nothing I suppose
+ return CmSdk.IsDevicePlug();
}
public override void Enable()
{
CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MKeys_L);
+
+ _hasControl = true;
CmSdk.EnableLedControl(true);
}
public override void DrawBitmap(Bitmap bitmap)
{
+ // Resize the bitmap
using (var b = ImageUtilities.ResizeImage(bitmap, Width, Height))
{
+ // Create an empty matrix
var matrix = new COLOR_MATRIX {KeyColor = new KEY_COLOR[Height, Width]};
+
+ // Map the bytes to the matix
for (var x = 0; x < Width; x++)
{
for (var y = 0; y < Height; y++)
{
- var color = b.GetPixel(x, y);
- matrix.KeyColor[y, x] = new KEY_COLOR(color.R, color.G, color.B);
+ var c = b.GetPixel(x, y);
+ matrix.KeyColor[y, x] = new KEY_COLOR(c.R, c.G, c.B);
}
}
+
+ // Send the matrix to the keyboard
CmSdk.SetAllLedColor(matrix);
}
}
public override KeyMatch? GetKeyPosition(Keys keyCode)
{
- return null;
- }
-
- private static byte[,,] BitmapToBytes(Bitmap bitmap)
- {
- BitmapData bitmapData =
- bitmap.LockBits(new Rectangle(new System.Drawing.Point(), bitmap.Size), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
- byte[] bitmapBytes;
- var stride = bitmapData.Stride;
- try
- {
- int byteCount = bitmapData.Stride * bitmap.Height;
- bitmapBytes = new byte[byteCount];
- Marshal.Copy(bitmapData.Scan0, bitmapBytes, 0, byteCount);
- }
- finally
- {
- bitmap.UnlockBits(bitmapData);
- }
- byte[,,] result = new byte[3, bitmap.Width, bitmap.Height];
- for (int k = 0; k < 3; k++)
- {
- for (int i = 0; i < bitmap.Width; i++)
- {
- for (int j = 0; j < bitmap.Height; j++)
- {
- result[k, i, j] = bitmapBytes[j * stride + i * 3 + k];
- }
- }
- }
- return result;
+ return KeyMap.QwertyLayout.FirstOrDefault(k => k.KeyCode == keyCode);
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/DeviceProviders/CoolerMaster/Utilities/CMSDK.cs b/Artemis/Artemis/DeviceProviders/CoolerMaster/Utilities/CMSDK.cs
index a8621a27f..4283e412f 100644
--- a/Artemis/Artemis/DeviceProviders/CoolerMaster/Utilities/CMSDK.cs
+++ b/Artemis/Artemis/DeviceProviders/CoolerMaster/Utilities/CMSDK.cs
@@ -2,7 +2,6 @@
namespace Artemis.DeviceProviders.CoolerMaster.Utilities
{
-
public struct KEY_COLOR
{
public byte r;
@@ -17,12 +16,9 @@ namespace Artemis.DeviceProviders.CoolerMaster.Utilities
}
}
- // set up/save the whole LED color structure
-
public struct COLOR_MATRIX
{
- [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 132)]
- public KEY_COLOR[,] KeyColor;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 132)] public KEY_COLOR[,] KeyColor;
}
//Enumeration of device list
@@ -45,15 +41,52 @@ namespace Artemis.DeviceProviders.CoolerMaster.Utilities
public static class CmSdk
{
+ ///
+ /// Sets the control device which all following actions are targetted to
+ ///
+ ///
[DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)]
public static extern void SetControlDevice(DEVICE_INDEX devIndex);
+ ///
+ /// Obtain current device layout
+ ///
+ ///
+ [DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)]
+ public static extern LAYOUT_KEYBOARD GetDeviceLayout();
+
+ ///
+ /// Verify if the currently conrolled device is plugged in
+ ///
+ ///
+ [DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)]
+ public static extern bool IsDevicePlug();
+
+ ///
+ /// Enables led control on the currently controlled device
+ ///
+ ///
+ ///
[DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool EnableLedControl(bool bEnable);
+ ///
+ /// Sets the LED of the currently controlled device
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
[DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool SetLedColor(int iRow, int iColumn, byte r, byte g, byte b);
+ ///
+ /// Sets all LEDS using the given color matrix
+ ///
+ ///
+ ///
[DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool SetAllLedColor(COLOR_MATRIX colorMatrix);
}
diff --git a/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs b/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs
index a4f65af0b..3fb2bfd0f 100644
--- a/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs
+++ b/Artemis/Artemis/DeviceProviders/Logitech/LogitechKeyboard.cs
@@ -2,6 +2,7 @@
using System.Threading;
using System.Windows;
using Artemis.DeviceProviders.Logitech.Utilities;
+using Artemis.Utilities;
using Artemis.Utilities.DataReaders;
using Microsoft.Win32;
diff --git a/Artemis/Artemis/DeviceProviders/Logitech/Utilities/OrionUtilities.cs b/Artemis/Artemis/DeviceProviders/Logitech/Utilities/OrionUtilities.cs
index f39d7a27e..736794cca 100644
--- a/Artemis/Artemis/DeviceProviders/Logitech/Utilities/OrionUtilities.cs
+++ b/Artemis/Artemis/DeviceProviders/Logitech/Utilities/OrionUtilities.cs
@@ -153,7 +153,7 @@ namespace Artemis.DeviceProviders.Logitech.Utilities
{
if (b.Width > 21 || b.Height > 6)
b = ResizeImage(b, 21, 6);
-
+
var rect = new Rectangle(0, 0, b.Width, b.Height);
var bitmapData = b.LockBits(rect, ImageLockMode.ReadWrite, b.PixelFormat);
@@ -202,10 +202,16 @@ namespace Artemis.DeviceProviders.Logitech.Utilities
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
- graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
+
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
+ // TODO: Make configurable
+ // Prevents light bleed
+ graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
+ // Soft/semi-transparent keys
+ //graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
+
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
diff --git a/Artemis/Artemis/DeviceProviders/Razer/Utilities/RazerUtilities.cs b/Artemis/Artemis/DeviceProviders/Razer/Utilities/RazerUtilities.cs
index 2ec0ebd43..44c7ae96a 100644
--- a/Artemis/Artemis/DeviceProviders/Razer/Utilities/RazerUtilities.cs
+++ b/Artemis/Artemis/DeviceProviders/Razer/Utilities/RazerUtilities.cs
@@ -10,19 +10,21 @@ namespace Artemis.DeviceProviders.Razer.Utilities
public static Custom BitmapColorArray(Bitmap b, int height, int width)
{
var keyboardGrid = Custom.Create();
- if (b.Width > width || b.Height > height)
- b = ImageUtilities.ResizeImage(b, width, height);
-
- for (var y = 0; y < b.Height; y++)
+ // Resize the bitmap
+ using (b = ImageUtilities.ResizeImage(b, width, height))
{
+ // Map the bytes to the grid
for (var x = 0; x < b.Width; x++)
{
- var pixel = b.GetPixel(x, y);
- keyboardGrid[y, x] = new Color(pixel.R, pixel.G, pixel.B);
+ for (var y = 0; y < b.Height; y++)
+ {
+ var c = b.GetPixel(x, y);
+ keyboardGrid[y, x] = new Color(c.R, c.G, c.B);
+ }
}
- }
- return keyboardGrid;
+ return keyboardGrid;
+ }
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/InjectionModules/BaseModules.cs b/Artemis/Artemis/InjectionModules/BaseModules.cs
index cbe1f7980..cdd51407f 100644
--- a/Artemis/Artemis/InjectionModules/BaseModules.cs
+++ b/Artemis/Artemis/InjectionModules/BaseModules.cs
@@ -15,7 +15,6 @@ namespace Artemis.InjectionModules
{
// ViewModels
Bind().ToSelf().InSingletonScope();
- Bind().ToSelf().InSingletonScope();
Bind().ToSelf();
Bind().ToSelf();
Bind().ToSelf().InSingletonScope();
diff --git a/Artemis/Artemis/Managers/DeviceManager.cs b/Artemis/Artemis/Managers/DeviceManager.cs
index 362f5cc11..bc79efdb1 100644
--- a/Artemis/Artemis/Managers/DeviceManager.cs
+++ b/Artemis/Artemis/Managers/DeviceManager.cs
@@ -73,7 +73,7 @@ namespace Artemis.Managers
public async void EnableKeyboard(KeyboardProvider keyboardProvider)
{
if (keyboardProvider == null)
- throw new ArgumentNullException(nameof(keyboardProvider));
+ return;
if (ChangingKeyboard || (ActiveKeyboard?.Name == keyboardProvider.Name))
return;
diff --git a/Artemis/Artemis/Managers/LoopManager.cs b/Artemis/Artemis/Managers/LoopManager.cs
index df5c7b701..631017882 100644
--- a/Artemis/Artemis/Managers/LoopManager.cs
+++ b/Artemis/Artemis/Managers/LoopManager.cs
@@ -177,6 +177,9 @@ namespace Artemis.Managers
{
public RenderFrame(KeyboardProvider keyboard)
{
+ if (keyboard == null)
+ return;
+
KeyboardBitmap = keyboard.KeyboardBitmap(4);
KeyboardBitmap.SetResolution(96, 96);
@@ -222,10 +225,10 @@ namespace Artemis.Managers
public void Dispose()
{
- KeyboardBitmap.Dispose();
- MouseBitmap.Dispose();
- HeadsetBitmap.Dispose();
- GenericBitmap.Dispose();
+ KeyboardBitmap?.Dispose();
+ MouseBitmap?.Dispose();
+ HeadsetBitmap?.Dispose();
+ GenericBitmap?.Dispose();
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Properties/Resources.Designer.cs b/Artemis/Artemis/Properties/Resources.Designer.cs
index 207ddd094..318b52e6b 100644
--- a/Artemis/Artemis/Properties/Resources.Designer.cs
+++ b/Artemis/Artemis/Properties/Resources.Designer.cs
@@ -328,6 +328,16 @@ namespace Artemis.Properties {
}
}
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap masterkeys_pro_l {
+ get {
+ object obj = ResourceManager.GetObject("masterkeys_pro_l", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
diff --git a/Artemis/Artemis/Properties/Resources.resx b/Artemis/Artemis/Properties/Resources.resx
index 44eae2ca5..b2b934454 100644
--- a/Artemis/Artemis/Properties/Resources.resx
+++ b/Artemis/Artemis/Properties/Resources.resx
@@ -214,4 +214,7 @@
..\Resources\ambilight.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Resources\Keyboards\masterkeys-pro-l.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Resources/Keyboards/masterkeys-pro-l.png b/Artemis/Artemis/Resources/Keyboards/masterkeys-pro-l.png
new file mode 100644
index 000000000..4658fe7bd
Binary files /dev/null and b/Artemis/Artemis/Resources/Keyboards/masterkeys-pro-l.png differ
diff --git a/Artemis/Artemis/Services/MetroDialogService.cs b/Artemis/Artemis/Services/MetroDialogService.cs
index c40f76583..dc52e96dd 100644
--- a/Artemis/Artemis/Services/MetroDialogService.cs
+++ b/Artemis/Artemis/Services/MetroDialogService.cs
@@ -40,8 +40,8 @@ namespace Artemis.Services
Execute.OnUIThread(() =>
{
- window = Application.Current.Windows.OfType().FirstOrDefault(w => w.IsActive) ??
- Application.Current.Windows.OfType().FirstOrDefault();
+ window = Application.Current.Windows.OfType()
+ .FirstOrDefault(w => w.IsActive && w.IsVisible);
});
return window;
diff --git a/Artemis/Artemis/Utilities/ImageUtilities.cs b/Artemis/Artemis/Utilities/ImageUtilities.cs
index 3326e3253..2984b1a6c 100644
--- a/Artemis/Artemis/Utilities/ImageUtilities.cs
+++ b/Artemis/Artemis/Utilities/ImageUtilities.cs
@@ -1,9 +1,12 @@
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
+using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
+using PixelFormat = System.Drawing.Imaging.PixelFormat;
+using Point = System.Drawing.Point;
namespace Artemis.Utilities
{
diff --git a/Artemis/Artemis/Utilities/Updater.cs b/Artemis/Artemis/Utilities/Updater.cs
index 31555b81d..0c856cfd9 100644
--- a/Artemis/Artemis/Utilities/Updater.cs
+++ b/Artemis/Artemis/Utilities/Updater.cs
@@ -56,7 +56,7 @@ namespace Artemis.Utilities
///
/// The dialog service to use for progress and result dialogs
///
- public static async Task CheckChangelog(MetroDialogService dialogService)
+ public static async void CheckChangelog(MetroDialogService dialogService)
{
var settings = SettingsProvider.Load();
var currentVersion = Assembly.GetExecutingAssembly().GetName().Version;
diff --git a/Artemis/Artemis/ViewModels/ShellViewModel.cs b/Artemis/Artemis/ViewModels/ShellViewModel.cs
index fd56ee14c..de8d7c5de 100644
--- a/Artemis/Artemis/ViewModels/ShellViewModel.cs
+++ b/Artemis/Artemis/ViewModels/ShellViewModel.cs
@@ -1,11 +1,18 @@
using System;
using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
using System.Windows;
+using Artemis.DAL;
+using Artemis.Events;
using Artemis.Managers;
using Artemis.Services;
+using Artemis.Settings;
+using Artemis.Utilities;
using Artemis.ViewModels.Abstract;
using Artemis.ViewModels.Flyouts;
using Caliburn.Micro;
+using Hardcodet.Wpf.TaskbarNotification;
using MahApps.Metro.Controls;
using Ninject;
@@ -14,52 +21,130 @@ namespace Artemis.ViewModels
public sealed class ShellViewModel : Conductor.Collection.OneActive
{
private readonly IKernel _kernel;
+ private string _activeIcon;
+ private bool _checked;
+ private bool _enabled;
+ private string _toggleText;
+ private bool _exiting;
public ShellViewModel(IKernel kernel, MainManager mainManager, MetroDialogService metroDialogService,
FlyoutSettingsViewModel flyoutSettings)
{
_kernel = kernel;
+ MainManager = mainManager;
+ MetroDialogService = metroDialogService;
- // Setup UI
DisplayName = "Artemis";
-
+ GeneralSettings = SettingsProvider.Load();
Flyouts = new BindableCollection
{
flyoutSettings
};
+ MainManager.OnEnabledChangedEvent += (sender, args) => Enabled = args.Enabled;
- MainManager = mainManager;
- MetroDialogService = metroDialogService;
- MainManager.EnableProgram();
+ // This gets updated automatically but during startup lets quickly preset it
+ Enabled = GeneralSettings.Suspended;
}
- public SystemTrayViewModel SystemTrayViewModel { get; set; }
+ protected override void OnViewReady(object view)
+ {
+ base.OnViewReady(view);
+
+ Task.Run(() => StartupHide());
+ }
+
+ private void StartupHide()
+ {
+ // TODO: This is probably an awful idea. I can't reliably hook into the view being ready to be hidden
+ Thread.Sleep(500);
+
+ if (GeneralSettings.ShowOnStartup)
+ ShowWindow();
+ else
+ HideWindow();
+
+ if (!GeneralSettings.Suspended)
+ MainManager.EnableProgram();
+ }
+
+ public Mutex Mutex { get; set; }
public MainManager MainManager { get; set; }
public MetroDialogService MetroDialogService { get; set; }
public IObservableCollection Flyouts { get; set; }
-
+ public GeneralSettings GeneralSettings { get; set; }
private MetroWindow Window => (MetroWindow) GetView();
+ public bool CanShowWindow => Window != null && (Window != null || !Window.IsVisible);
+ public bool CanHideWindow => Window != null && Window.IsVisible;
+
+ public bool Enabled
+ {
+ get { return _enabled; }
+ set
+ {
+ if (value == _enabled) return;
+ _enabled = value;
+
+ ToggleText = _enabled ? "Disable Artemis" : "Enable Artemis";
+ ActiveIcon = _enabled ? "../Resources/logo.ico" : "../Resources/logo-disabled.ico";
+ NotifyOfPropertyChange(() => Enabled);
+ }
+ }
+
+ public string ActiveIcon
+ {
+ get { return _activeIcon; }
+ set
+ {
+ _activeIcon = value;
+ NotifyOfPropertyChange();
+ }
+ }
+
+ public string ToggleText
+ {
+ get { return _toggleText; }
+ set
+ {
+ if (value == _toggleText) return;
+ _toggleText = value;
+ NotifyOfPropertyChange(() => ToggleText);
+ }
+ }
+
public override void CanClose(Action callback)
{
- if (Window.IsVisible)
+ if (CanHideWindow)
HideWindow();
- else
+ else if (!_exiting)
ShowWindow();
- // ShellView is a strong and independent view who won't let herself get closed by the likes of anyone!
- callback(false);
+ // Only close if ExitApplication was called
+ callback(_exiting);
}
- public bool CanShowWindow => !Window.IsVisible;
- public bool CanHideWindow => Window.IsVisible;
-
public void ShowWindow()
{
- if (!Window.IsVisible)
- Window.Show();
+ if (CanShowWindow)
+ Window?.Dispatcher.Invoke(() =>
+ {
+ Window.Show();
+ Window.Activate();
+ });
+
+ GeneralSettings.ApplyTheme();
+
+ // Show certain dialogs if needed
+ CheckKeyboardState();
+ CheckDuplicateInstances();
+ Updater.CheckChangelog(MetroDialogService);
+
+ var vms = _kernel.GetAll().ToList();
+ Items.Clear();
+ Items.AddRange(vms);
+ ActivateItem(vms.FirstOrDefault());
NotifyOfPropertyChange(() => CanShowWindow);
NotifyOfPropertyChange(() => CanHideWindow);
@@ -67,26 +152,44 @@ namespace Artemis.ViewModels
public void HideWindow()
{
- if (Window.IsVisible)
- Window.Hide();
+ if (CanHideWindow)
+ Window?.Dispatcher.Invoke(() => { Window.Hide(); });
+ Items.Clear();
NotifyOfPropertyChange(() => CanShowWindow);
NotifyOfPropertyChange(() => CanHideWindow);
+
+ // Force a GC since the UI releases a lot of resources
+ GC.Collect();
}
- protected override void OnActivate()
+ public void ToggleEnabled()
{
- base.OnActivate();
- Items.Clear();
-
- var vms = _kernel.GetAll();
- Items.AddRange(vms);
+ if (Enabled)
+ MainManager.DisableProgram();
+ else
+ MainManager.EnableProgram();
}
- protected override void OnDeactivate(bool close)
+ public void ExitApplication()
{
- base.OnDeactivate(close);
- Items.Clear();
+ MainManager.Dispose();
+
+ try
+ {
+ var icon = (TaskbarIcon) Window.FindResource("SystemTrayIcon");
+ icon.Dispose();
+ }
+ catch (Exception)
+ {
+ //ignored
+ }
+
+ _exiting = true;
+
+ // TODO: CoolerMaster SDK is freezing Artemis on shutdown, dunno what to do about it yet
+ System.Diagnostics.Process.GetCurrentProcess().Kill();
+ // Application.Current.Shutdown();
}
public void Settings()
@@ -98,5 +201,42 @@ namespace Artemis.ViewModels
{
Flyouts.First().IsOpen = false;
}
+
+ private async void CheckKeyboardState()
+ {
+ var dialog = await MetroDialogService.ShowProgressDialog("Enabling keyboard",
+ "Artemis is still busy trying to enable your last used keyboard. " +
+ "Please wait while the process completes");
+ dialog.SetIndeterminate();
+
+ while (MainManager.DeviceManager.ChangingKeyboard)
+ await Task.Delay(10);
+
+ try
+ {
+ await dialog.CloseAsync();
+ }
+ catch (InvalidOperationException)
+ {
+ // Occurs when window is closed again, can't find a proper check for this
+ }
+ }
+
+ private void CheckDuplicateInstances()
+ {
+ if (_checked)
+ return;
+ _checked = true;
+
+ bool aIsNewInstance;
+ Mutex = new Mutex(true, "ArtemisMutex", out aIsNewInstance);
+ if (aIsNewInstance)
+ return;
+
+ MetroDialogService.ShowMessageBox("Multiple instances found",
+ "It looks like there are multiple running instances of Artemis. " +
+ "This can cause issues, especially with CS:GO and Dota2. " +
+ "If so, please make sure Artemis isn't already running");
+ }
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs b/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs
deleted file mode 100644
index b5adfcf72..000000000
--- a/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs
+++ /dev/null
@@ -1,200 +0,0 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Windows;
-using Artemis.DAL;
-using Artemis.Events;
-using Artemis.Managers;
-using Artemis.Services;
-using Artemis.Settings;
-using Artemis.Utilities;
-using Caliburn.Micro;
-
-namespace Artemis.ViewModels
-{
- public class SystemTrayViewModel : Screen
- {
- private readonly WindowService _windowService;
- private ShellViewModel _shellViewModel;
- private string _activeIcon;
- private bool _checked;
- private bool _enabled;
- private string _toggleText;
-
- public SystemTrayViewModel(WindowService windowService, MetroDialogService dialogService, MainManager mainManager)
- {
- _windowService = windowService;
-
- DialogService = dialogService;
- MainManager = mainManager;
-
- MainManager.EnableProgram();
- MainManager.OnEnabledChangedEvent += MainManagerOnOnEnabledChangedEvent;
-
- var generalSettings = SettingsProvider.Load();
- Enabled = !generalSettings.Suspended;
- if (generalSettings.ShowOnStartup)
- ShowWindow();
- }
-
- public MetroDialogService DialogService { get; set; }
-
- public MainManager MainManager { get; set; }
-
- public bool CanShowWindow
- {
- get
- {
- if (_shellViewModel == null)
- return true;
- return !_shellViewModel.IsActive;
- }
- }
-
- public bool CanHideWindow => (_shellViewModel?.IsActive == true) && !MainManager.DeviceManager.ChangingKeyboard;
- public bool CanToggleEnabled => !MainManager.DeviceManager.ChangingKeyboard;
-
- public bool Enabled
- {
- get { return _enabled; }
- set
- {
- if (value == _enabled) return;
- _enabled = value;
-
- ToggleText = _enabled ? "Disable Artemis" : "Enable Artemis";
- ActiveIcon = _enabled ? "../Resources/logo.ico" : "../Resources/logo-disabled.ico";
- NotifyOfPropertyChange(() => Enabled);
- }
- }
-
- public string ActiveIcon
- {
- get { return _activeIcon; }
- set
- {
- _activeIcon = value;
- NotifyOfPropertyChange();
- }
- }
-
- public string ToggleText
- {
- get { return _toggleText; }
- set
- {
- if (value == _toggleText) return;
- _toggleText = value;
- NotifyOfPropertyChange(() => ToggleText);
- }
- }
-
- public Mutex Mutex { get; set; }
-
- private void MainManagerOnOnEnabledChangedEvent(object sender, EnabledChangedEventArgs e)
- {
- Enabled = e.Enabled;
- }
-
- public void ToggleEnabled()
- {
- if (Enabled)
- MainManager.DisableProgram();
- else
- MainManager.EnableProgram();
- }
-
- protected override void OnActivate()
- {
- base.OnActivate();
-
- NotifyOfPropertyChange(() => CanShowWindow);
- NotifyOfPropertyChange(() => CanHideWindow);
- }
-
- public void ShowWindow()
- {
- if (!CanShowWindow)
- return;
-
- // manually show the next window view-model
- _shellViewModel = _windowService.ShowWindow();
-
- NotifyOfPropertyChange(() => CanShowWindow);
- NotifyOfPropertyChange(() => CanHideWindow);
-
- SettingsProvider.Load().ApplyTheme();
-
- // Show certain dialogs if needed
- CheckKeyboardState();
- CheckDuplicateInstances();
- Updater.CheckChangelog(DialogService);
- }
-
- private void CheckDuplicateInstances()
- {
- if (_checked)
- return;
- _checked = true;
-
- bool aIsNewInstance;
- Mutex = new Mutex(true, "ArtemisMutex", out aIsNewInstance);
- if (aIsNewInstance)
- return;
-
- DialogService.ShowMessageBox("Multiple instances found",
- "It looks like there are multiple running instances of Artemis. " +
- "This can cause issues, especially with CS:GO and Dota2. " +
- "If so, please make sure Artemis isn't already running");
- }
-
- private async void CheckKeyboardState()
- {
- while (!_shellViewModel.IsActive)
- await Task.Delay(200);
-
- NotifyOfPropertyChange(() => CanHideWindow);
- NotifyOfPropertyChange(() => CanToggleEnabled);
-
- var dialog = await DialogService.ShowProgressDialog("Enabling keyboard",
- "Artemis is still busy trying to enable your last used keyboard. " +
- "Please wait while the process completes");
- dialog.SetIndeterminate();
-
- while (MainManager.DeviceManager.ChangingKeyboard)
- await Task.Delay(10);
-
- NotifyOfPropertyChange(() => CanHideWindow);
- NotifyOfPropertyChange(() => CanToggleEnabled);
-
- try
- {
- await dialog.CloseAsync();
- }
- catch (InvalidOperationException)
- {
- // Occurs when window is closed again, can't find a proper check for this
- }
- }
-
- public void HideWindow()
- {
- if (!CanHideWindow)
- return;
-
- _shellViewModel.TryClose();
-
- NotifyOfPropertyChange(() => CanShowWindow);
- NotifyOfPropertyChange(() => CanHideWindow);
-
- // Force a GC since the UI releases a lot of resources
- GC.Collect();
- }
-
- public void ExitApplication()
- {
- MainManager.Dispose();
- Application.Current.Shutdown();
- }
- }
-}
\ No newline at end of file