1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2026-01-01 10:13:30 +00:00

Finished CM support

Reimplemented task bar icon
This commit is contained in:
SpoinkyNL 2016-11-12 00:00:38 +01:00
parent 6f7e24611a
commit c172ec4c6a
17 changed files with 281 additions and 292 deletions

View File

@ -318,7 +318,7 @@
<Compile Include="DAL\ProfileProvider.cs" /> <Compile Include="DAL\ProfileProvider.cs" />
<Compile Include="DAL\SettingsProvider.cs" /> <Compile Include="DAL\SettingsProvider.cs" />
<Compile Include="DeviceProviders\CoolerMaster\MasterkeysProL.cs" /> <Compile Include="DeviceProviders\CoolerMaster\MasterkeysProL.cs" />
<Compile Include="DeviceProviders\CoolerMaster\Utilities\CMSDK.cs" /> <Compile Include="DeviceProviders\CoolerMaster\Utilities\CmSdk.cs" />
<Compile Include="DeviceProviders\Corsair\CorsairMice.cs" /> <Compile Include="DeviceProviders\Corsair\CorsairMice.cs" />
<Compile Include="DeviceProviders\Corsair\CorsairHeadsets.cs" /> <Compile Include="DeviceProviders\Corsair\CorsairHeadsets.cs" />
<Compile Include="DeviceProviders\Corsair\CorsairMousemats.cs" /> <Compile Include="DeviceProviders\Corsair\CorsairMousemats.cs" />
@ -611,7 +611,6 @@
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplayViewModel.cs" /> <Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplayViewModel.cs" />
<Compile Include="ViewModels\Profiles\ProfileEditorViewModel.cs" /> <Compile Include="ViewModels\Profiles\ProfileEditorViewModel.cs" />
<Compile Include="ViewModels\ShellViewModel.cs" /> <Compile Include="ViewModels\ShellViewModel.cs" />
<Compile Include="ViewModels\SystemTrayViewModel.cs" />
<Compile Include="ViewModels\WelcomeViewModel.cs" /> <Compile Include="ViewModels\WelcomeViewModel.cs" />
<Compile Include="Views\DebugView.xaml.cs"> <Compile Include="Views\DebugView.xaml.cs">
<DependentUpon>DebugView.xaml</DependentUpon> <DependentUpon>DebugView.xaml</DependentUpon>
@ -687,6 +686,7 @@
<Compile Include="Properties\AssemblyInfo.cs"> <Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<None Include="Resources\Keyboards\masterkeys-pro-l.png" />
<Resource Include="Resources\Kottke Silkscreen License.txt" /> <Resource Include="Resources\Kottke Silkscreen License.txt" />
<None Include="Resources\lua-placeholder.lua" /> <None Include="Resources\lua-placeholder.lua" />
<None Include="NLog.xsd"> <None Include="NLog.xsd">

View File

@ -1,9 +1,10 @@
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Linq;
using System.Runtime.InteropServices; using System.Threading;
using System.Windows; using System.Windows;
using System.Windows.Forms; using System.Windows.Forms;
using Artemis.DeviceProviders.CoolerMaster.Utilities; using Artemis.DeviceProviders.CoolerMaster.Utilities;
using Artemis.DeviceProviders.Logitech.Utilities;
using Artemis.Properties; using Artemis.Properties;
using Artemis.Utilities; using Artemis.Utilities;
@ -11,6 +12,8 @@ namespace Artemis.DeviceProviders.CoolerMaster
{ {
public class MasterkeysProL : KeyboardProvider public class MasterkeysProL : KeyboardProvider
{ {
private bool _hasControl;
public MasterkeysProL() public MasterkeysProL()
{ {
Name = "CM Masterkeys Pro L"; Name = "CM Masterkeys Pro L";
@ -22,76 +25,62 @@ namespace Artemis.DeviceProviders.CoolerMaster
Height = 6; Height = 6;
Width = 22; 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() public override void Disable()
{
if (_hasControl)
{ {
CmSdk.EnableLedControl(false); CmSdk.EnableLedControl(false);
Thread.Sleep(500);
}
_hasControl = false;
} }
public override bool CanEnable() 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() public override void Enable()
{ {
CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MKeys_L); CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MKeys_L);
_hasControl = true;
CmSdk.EnableLedControl(true); CmSdk.EnableLedControl(true);
} }
public override void DrawBitmap(Bitmap bitmap) public override void DrawBitmap(Bitmap bitmap)
{ {
// Resize the bitmap
using (var b = ImageUtilities.ResizeImage(bitmap, Width, Height)) using (var b = ImageUtilities.ResizeImage(bitmap, Width, Height))
{ {
// Create an empty matrix
var matrix = new COLOR_MATRIX {KeyColor = new KEY_COLOR[Height, Width]}; 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 x = 0; x < Width; x++)
{ {
for (var y = 0; y < Height; y++) for (var y = 0; y < Height; y++)
{ {
var color = b.GetPixel(x, y); var c = b.GetPixel(x, y);
matrix.KeyColor[y, x] = new KEY_COLOR(color.R, color.G, color.B); matrix.KeyColor[y, x] = new KEY_COLOR(c.R, c.G, c.B);
} }
} }
// Send the matrix to the keyboard
CmSdk.SetAllLedColor(matrix); CmSdk.SetAllLedColor(matrix);
} }
} }
public override KeyMatch? GetKeyPosition(Keys keyCode) public override KeyMatch? GetKeyPosition(Keys keyCode)
{ {
return null; return KeyMap.QwertyLayout.FirstOrDefault(k => k.KeyCode == keyCode);
}
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;
} }
} }
} }

View File

@ -2,7 +2,6 @@
namespace Artemis.DeviceProviders.CoolerMaster.Utilities namespace Artemis.DeviceProviders.CoolerMaster.Utilities
{ {
public struct KEY_COLOR public struct KEY_COLOR
{ {
public byte r; public byte r;
@ -17,12 +16,9 @@ namespace Artemis.DeviceProviders.CoolerMaster.Utilities
} }
} }
// set up/save the whole LED color structure
public struct COLOR_MATRIX public struct COLOR_MATRIX
{ {
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 132)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 132)] public KEY_COLOR[,] KeyColor;
public KEY_COLOR[,] KeyColor;
} }
//Enumeration of device list //Enumeration of device list
@ -45,15 +41,52 @@ namespace Artemis.DeviceProviders.CoolerMaster.Utilities
public static class CmSdk public static class CmSdk
{ {
/// <summary>
/// Sets the control device which all following actions are targetted to
/// </summary>
/// <param name="devIndex"></param>
[DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)] [DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)]
public static extern void SetControlDevice(DEVICE_INDEX devIndex); public static extern void SetControlDevice(DEVICE_INDEX devIndex);
/// <summary>
/// Obtain current device layout
/// </summary>
/// <returns></returns>
[DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)]
public static extern LAYOUT_KEYBOARD GetDeviceLayout();
/// <summary>
/// Verify if the currently conrolled device is plugged in
/// </summary>
/// <returns></returns>
[DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool IsDevicePlug();
/// <summary>
/// Enables led control on the currently controlled device
/// </summary>
/// <param name="bEnable"></param>
/// <returns></returns>
[DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)] [DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool EnableLedControl(bool bEnable); public static extern bool EnableLedControl(bool bEnable);
/// <summary>
/// Sets the LED of the currently controlled device
/// </summary>
/// <param name="iRow"></param>
/// <param name="iColumn"></param>
/// <param name="r"></param>
/// <param name="g"></param>
/// <param name="b"></param>
/// <returns></returns>
[DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)] [DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool SetLedColor(int iRow, int iColumn, byte r, byte g, byte b); public static extern bool SetLedColor(int iRow, int iColumn, byte r, byte g, byte b);
/// <summary>
/// Sets all LEDS using the given color matrix
/// </summary>
/// <param name="colorMatrix"></param>
/// <returns></returns>
[DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)] [DllImport("lib\\SDKDLL ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool SetAllLedColor(COLOR_MATRIX colorMatrix); public static extern bool SetAllLedColor(COLOR_MATRIX colorMatrix);
} }

View File

@ -2,6 +2,7 @@
using System.Threading; using System.Threading;
using System.Windows; using System.Windows;
using Artemis.DeviceProviders.Logitech.Utilities; using Artemis.DeviceProviders.Logitech.Utilities;
using Artemis.Utilities;
using Artemis.Utilities.DataReaders; using Artemis.Utilities.DataReaders;
using Microsoft.Win32; using Microsoft.Win32;

View File

@ -202,10 +202,16 @@ namespace Artemis.DeviceProviders.Logitech.Utilities
{ {
graphics.CompositingMode = CompositingMode.SourceCopy; graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
graphics.SmoothingMode = SmoothingMode.AntiAlias; graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; 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()) using (var wrapMode = new ImageAttributes())
{ {
wrapMode.SetWrapMode(WrapMode.TileFlipXY); wrapMode.SetWrapMode(WrapMode.TileFlipXY);

View File

@ -10,19 +10,21 @@ namespace Artemis.DeviceProviders.Razer.Utilities
public static Custom BitmapColorArray(Bitmap b, int height, int width) public static Custom BitmapColorArray(Bitmap b, int height, int width)
{ {
var keyboardGrid = Custom.Create(); var keyboardGrid = Custom.Create();
if (b.Width > width || b.Height > height) // Resize the bitmap
b = ImageUtilities.ResizeImage(b, width, height); using (b = ImageUtilities.ResizeImage(b, width, height))
for (var y = 0; y < b.Height; y++)
{ {
// Map the bytes to the grid
for (var x = 0; x < b.Width; x++) for (var x = 0; x < b.Width; x++)
{ {
var pixel = b.GetPixel(x, y); for (var y = 0; y < b.Height; y++)
keyboardGrid[y, x] = new Color(pixel.R, pixel.G, pixel.B); {
var c = b.GetPixel(x, y);
keyboardGrid[y, x] = new Color(c.R, c.G, c.B);
} }
} }
return keyboardGrid; return keyboardGrid;
} }
} }
}
} }

View File

@ -15,7 +15,6 @@ namespace Artemis.InjectionModules
{ {
// ViewModels // ViewModels
Bind<ShellViewModel>().ToSelf().InSingletonScope(); Bind<ShellViewModel>().ToSelf().InSingletonScope();
Bind<SystemTrayViewModel>().ToSelf().InSingletonScope();
Bind<ProfileViewModel>().ToSelf(); Bind<ProfileViewModel>().ToSelf();
Bind<ProfileEditorViewModel>().ToSelf(); Bind<ProfileEditorViewModel>().ToSelf();
Bind<DebugViewModel>().ToSelf().InSingletonScope(); Bind<DebugViewModel>().ToSelf().InSingletonScope();

View File

@ -73,7 +73,7 @@ namespace Artemis.Managers
public async void EnableKeyboard(KeyboardProvider keyboardProvider) public async void EnableKeyboard(KeyboardProvider keyboardProvider)
{ {
if (keyboardProvider == null) if (keyboardProvider == null)
throw new ArgumentNullException(nameof(keyboardProvider)); return;
if (ChangingKeyboard || (ActiveKeyboard?.Name == keyboardProvider.Name)) if (ChangingKeyboard || (ActiveKeyboard?.Name == keyboardProvider.Name))
return; return;

View File

@ -177,6 +177,9 @@ namespace Artemis.Managers
{ {
public RenderFrame(KeyboardProvider keyboard) public RenderFrame(KeyboardProvider keyboard)
{ {
if (keyboard == null)
return;
KeyboardBitmap = keyboard.KeyboardBitmap(4); KeyboardBitmap = keyboard.KeyboardBitmap(4);
KeyboardBitmap.SetResolution(96, 96); KeyboardBitmap.SetResolution(96, 96);
@ -222,10 +225,10 @@ namespace Artemis.Managers
public void Dispose() public void Dispose()
{ {
KeyboardBitmap.Dispose(); KeyboardBitmap?.Dispose();
MouseBitmap.Dispose(); MouseBitmap?.Dispose();
HeadsetBitmap.Dispose(); HeadsetBitmap?.Dispose();
GenericBitmap.Dispose(); GenericBitmap?.Dispose();
} }
} }
} }

View File

@ -328,6 +328,16 @@ namespace Artemis.Properties {
} }
} }
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap masterkeys_pro_l {
get {
object obj = ResourceManager.GetObject("masterkeys_pro_l", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary> /// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap. /// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary> /// </summary>

View File

@ -214,4 +214,7 @@
<data name="ambilight" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="ambilight" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\ambilight.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Resources\ambilight.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="masterkeys_pro_l" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Keyboards\masterkeys-pro-l.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root> </root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

View File

@ -40,8 +40,8 @@ namespace Artemis.Services
Execute.OnUIThread(() => Execute.OnUIThread(() =>
{ {
window = Application.Current.Windows.OfType<MetroWindow>().FirstOrDefault(w => w.IsActive) ?? window = Application.Current.Windows.OfType<MetroWindow>()
Application.Current.Windows.OfType<MetroWindow>().FirstOrDefault(); .FirstOrDefault(w => w.IsActive && w.IsVisible);
}); });
return window; return window;

View File

@ -1,9 +1,12 @@
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Runtime.InteropServices;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using PixelFormat = System.Drawing.Imaging.PixelFormat;
using Point = System.Drawing.Point;
namespace Artemis.Utilities namespace Artemis.Utilities
{ {

View File

@ -56,7 +56,7 @@ namespace Artemis.Utilities
/// </summary> /// </summary>
/// <param name="dialogService">The dialog service to use for progress and result dialogs</param> /// <param name="dialogService">The dialog service to use for progress and result dialogs</param>
/// <returns></returns> /// <returns></returns>
public static async Task CheckChangelog(MetroDialogService dialogService) public static async void CheckChangelog(MetroDialogService dialogService)
{ {
var settings = SettingsProvider.Load<GeneralSettings>(); var settings = SettingsProvider.Load<GeneralSettings>();
var currentVersion = Assembly.GetExecutingAssembly().GetName().Version; var currentVersion = Assembly.GetExecutingAssembly().GetName().Version;

View File

@ -1,11 +1,18 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using Artemis.DAL;
using Artemis.Events;
using Artemis.Managers; using Artemis.Managers;
using Artemis.Services; using Artemis.Services;
using Artemis.Settings;
using Artemis.Utilities;
using Artemis.ViewModels.Abstract; using Artemis.ViewModels.Abstract;
using Artemis.ViewModels.Flyouts; using Artemis.ViewModels.Flyouts;
using Caliburn.Micro; using Caliburn.Micro;
using Hardcodet.Wpf.TaskbarNotification;
using MahApps.Metro.Controls; using MahApps.Metro.Controls;
using Ninject; using Ninject;
@ -14,52 +21,130 @@ namespace Artemis.ViewModels
public sealed class ShellViewModel : Conductor<IScreen>.Collection.OneActive public sealed class ShellViewModel : Conductor<IScreen>.Collection.OneActive
{ {
private readonly IKernel _kernel; 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, public ShellViewModel(IKernel kernel, MainManager mainManager, MetroDialogService metroDialogService,
FlyoutSettingsViewModel flyoutSettings) FlyoutSettingsViewModel flyoutSettings)
{ {
_kernel = kernel; _kernel = kernel;
MainManager = mainManager;
MetroDialogService = metroDialogService;
// Setup UI
DisplayName = "Artemis"; DisplayName = "Artemis";
GeneralSettings = SettingsProvider.Load<GeneralSettings>();
Flyouts = new BindableCollection<FlyoutBaseViewModel> Flyouts = new BindableCollection<FlyoutBaseViewModel>
{ {
flyoutSettings flyoutSettings
}; };
MainManager.OnEnabledChangedEvent += (sender, args) => Enabled = args.Enabled;
MainManager = mainManager; // This gets updated automatically but during startup lets quickly preset it
MetroDialogService = metroDialogService; Enabled = GeneralSettings.Suspended;
}
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(); MainManager.EnableProgram();
} }
public SystemTrayViewModel SystemTrayViewModel { get; set; } public Mutex Mutex { get; set; }
public MainManager MainManager { get; set; } public MainManager MainManager { get; set; }
public MetroDialogService MetroDialogService { get; set; } public MetroDialogService MetroDialogService { get; set; }
public IObservableCollection<FlyoutBaseViewModel> Flyouts { get; set; } public IObservableCollection<FlyoutBaseViewModel> Flyouts { get; set; }
public GeneralSettings GeneralSettings { get; set; }
private MetroWindow Window => (MetroWindow) GetView(); 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<bool> callback) public override void CanClose(Action<bool> callback)
{ {
if (Window.IsVisible) if (CanHideWindow)
HideWindow(); HideWindow();
else else if (!_exiting)
ShowWindow(); ShowWindow();
// ShellView is a strong and independent view who won't let herself get closed by the likes of anyone! // Only close if ExitApplication was called
callback(false); callback(_exiting);
} }
public bool CanShowWindow => !Window.IsVisible;
public bool CanHideWindow => Window.IsVisible;
public void ShowWindow() public void ShowWindow()
{ {
if (!Window.IsVisible) if (CanShowWindow)
Window?.Dispatcher.Invoke(() =>
{
Window.Show(); Window.Show();
Window.Activate();
});
GeneralSettings.ApplyTheme();
// Show certain dialogs if needed
CheckKeyboardState();
CheckDuplicateInstances();
Updater.CheckChangelog(MetroDialogService);
var vms = _kernel.GetAll<BaseViewModel>().ToList();
Items.Clear();
Items.AddRange(vms);
ActivateItem(vms.FirstOrDefault());
NotifyOfPropertyChange(() => CanShowWindow); NotifyOfPropertyChange(() => CanShowWindow);
NotifyOfPropertyChange(() => CanHideWindow); NotifyOfPropertyChange(() => CanHideWindow);
@ -67,26 +152,44 @@ namespace Artemis.ViewModels
public void HideWindow() public void HideWindow()
{ {
if (Window.IsVisible) if (CanHideWindow)
Window.Hide(); Window?.Dispatcher.Invoke(() => { Window.Hide(); });
Items.Clear();
NotifyOfPropertyChange(() => CanShowWindow); NotifyOfPropertyChange(() => CanShowWindow);
NotifyOfPropertyChange(() => CanHideWindow); NotifyOfPropertyChange(() => CanHideWindow);
// Force a GC since the UI releases a lot of resources
GC.Collect();
} }
protected override void OnActivate() public void ToggleEnabled()
{ {
base.OnActivate(); if (Enabled)
Items.Clear(); MainManager.DisableProgram();
else
var vms = _kernel.GetAll<BaseViewModel>(); MainManager.EnableProgram();
Items.AddRange(vms);
} }
protected override void OnDeactivate(bool close) public void ExitApplication()
{ {
base.OnDeactivate(close); MainManager.Dispose();
Items.Clear();
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() public void Settings()
@ -98,5 +201,42 @@ namespace Artemis.ViewModels
{ {
Flyouts.First().IsOpen = false; 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");
}
} }
} }

View File

@ -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<GeneralSettings>();
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<ShellViewModel>();
NotifyOfPropertyChange(() => CanShowWindow);
NotifyOfPropertyChange(() => CanHideWindow);
SettingsProvider.Load<GeneralSettings>().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();
}
}
}