1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Smoothed out the way changing keyboards works in combination with profiles.

This commit is contained in:
SpoinkyNL 2016-05-11 12:14:32 +02:00
parent b9a55b896a
commit aafd361a6b
13 changed files with 174 additions and 146 deletions

View File

@ -4,6 +4,7 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
using Artemis.KeyboardProviders;
using Artemis.Models;
using Artemis.Models.Profiles;
@ -27,10 +28,16 @@ namespace Artemis.DAL
/// Get all profiles matching the provided game
/// </summary>
/// <param name="game">The game to match</param>
/// <param name="keyboard">The keyboard to match</param>
/// <returns>All profiles matching the provided game</returns>
public static List<ProfileModel> GetAll(GameModel game)
public static List<ProfileModel> GetAll(GameModel game, KeyboardProvider keyboard)
{
return GetAll().Where(g => g.GameName.Equals(game.Name)).ToList();
if (game == null)
throw new ArgumentNullException(nameof(game));
if (keyboard == null)
throw new ArgumentNullException(nameof(keyboard));
return GetAll().Where(g => g.GameName.Equals(game.Name) && g.KeyboardName.Equals(keyboard.Name)).ToList();
}
/// <summary>
@ -40,6 +47,8 @@ namespace Artemis.DAL
/// <param name="prof">The profile to add or update</param>
public static void AddOrUpdate(ProfileModel prof)
{
if (prof == null)
throw new ArgumentNullException(nameof(prof));
if (!(prof.GameName?.Length > 1) || !(prof.KeyboardName?.Length > 1) || !(prof.Name?.Length > 1))
throw new ArgumentException("Profile is invalid. Name, GameName and KeyboardName are required");

View File

@ -1,12 +1,16 @@
namespace Artemis.Events
using Artemis.KeyboardProviders;
namespace Artemis.Events
{
public class ActiveKeyboardChanged
{
public ActiveKeyboardChanged(string activeKeyboard)
public ActiveKeyboardChanged(KeyboardProvider oldKeyboard, KeyboardProvider newKeyboard)
{
ActiveKeyboard = activeKeyboard;
OldKeyboard = oldKeyboard;
NewKeyboard = newKeyboard;
}
public string ActiveKeyboard { get; set; }
public KeyboardProvider OldKeyboard { get; set; }
public KeyboardProvider NewKeyboard { get; set; }
}
}

View File

@ -17,6 +17,7 @@ namespace Artemis.InjectionModules
Bind<IScreen>().To<ShellViewModel>().InSingletonScope();
Bind<IProfileEditorViewModelFactory>().ToFactory();
Bind<BaseViewModel>().To<WelcomeViewModel>().InSingletonScope();
Bind<BaseViewModel>().To<EffectsViewModel>().InSingletonScope();
Bind<BaseViewModel>().To<GamesViewModel>().InSingletonScope();
Bind<BaseViewModel>().To<OverlaysViewModel>().InSingletonScope();

View File

@ -123,17 +123,10 @@ namespace Artemis.KeyboardProviders.Corsair
/// <param name="bitmap"></param>
public override void DrawBitmap(Bitmap bitmap)
{
var fixedBmp = new Bitmap(bitmap.Width, bitmap.Height);
using (var g = Graphics.FromImage(fixedBmp))
{
g.Clear(Color.Black);
g.DrawImage(bitmap, 0, 0);
}
var fixedImage = ImageUtilities.ResizeImage(fixedBmp, Width, Height);
var image = ImageUtilities.ResizeImage(bitmap, Width, Height);
var brush = new ImageBrush
{
Image = fixedImage
Image = image
};
_keyboard.Brush = brush;

View File

@ -79,6 +79,9 @@ namespace Artemis.Managers
/// <param name="e"></param>
private void SetupProfilePreview(object sender, ElapsedEventArgs e)
{
if (_keyboardManager.ChangingKeyboard)
return;
// Make sure the preview model should still be active
if (ActiveEffect is ProfilePreviewModel)
{
@ -133,10 +136,6 @@ namespace Artemis.Managers
if (effectModel is OverlayModel)
throw new ArgumentException("Can't set an Overlay effect as the active effect");
lock (_keyboardManager)
{
lock (this)
{
if (_keyboardManager.ActiveKeyboard == null)
_keyboardManager.EnableLastKeyboard();
// If still null, no last keyboard, so stop.
@ -155,6 +154,9 @@ namespace Artemis.Managers
wasNull = true;
ActiveEffect = effectModel;
}
lock (ActiveEffect)
{
if (!wasNull)
ActiveEffect.Dispose();
@ -168,7 +170,6 @@ namespace Artemis.Managers
General.Default.LastEffect = ActiveEffect?.Name;
General.Default.Save();
}
}
if (loopManager != null && !loopManager.Running)
{
@ -185,9 +186,10 @@ namespace Artemis.Managers
/// </summary>
public void ClearEffect()
{
lock (_keyboardManager)
{
lock (this)
if (ActiveEffect == null)
return;
lock (ActiveEffect)
{
ActiveEffect.Dispose();
ActiveEffect = null;
@ -195,7 +197,7 @@ namespace Artemis.Managers
General.Default.LastEffect = null;
General.Default.Save();
}
}
_logger.Debug("Cleared active effect");
}

View File

@ -18,7 +18,6 @@ namespace Artemis.Managers
{
private readonly IEventAggregator _events;
private readonly ILogger _logger;
private KeyboardProvider _activeKeyboard;
public KeyboardManager(IEventAggregator events, ILogger logger, List<KeyboardProvider> keyboardProviders)
{
@ -36,16 +35,9 @@ namespace Artemis.Managers
public List<KeyboardProvider> KeyboardProviders { get; set; }
public KeyboardProvider ActiveKeyboard
{
get { return _activeKeyboard; }
set
{
_activeKeyboard = value;
// Let the ViewModels know
_events.PublishOnUIThread(new ActiveKeyboardChanged(value?.Name));
}
}
public KeyboardProvider ActiveKeyboard { get; set; }
public bool ChangingKeyboard { get; private set; }
/// <summary>
/// Enables the last keyboard according to the settings file
@ -68,11 +60,19 @@ namespace Artemis.Managers
{
lock (this)
{
ChangingKeyboard = true;
if (keyboardProvider == null)
throw new ArgumentNullException(nameof(keyboardProvider));
if (ActiveKeyboard?.Name == keyboardProvider.Name)
{
ChangingKeyboard = false;
return;
}
// Store the old keyboard so it can be used in the event we're raising later
var oldKeyboard = ActiveKeyboard;
var wasNull = false;
if (ActiveKeyboard == null)
@ -94,6 +94,7 @@ namespace Artemis.Managers
General.Default.LastKeyboard = null;
General.Default.Save();
_logger.Warn("Failed enabling keyboard: {0}", keyboardProvider.Name);
ChangingKeyboard = false;
return;
}
@ -102,6 +103,9 @@ namespace Artemis.Managers
General.Default.LastKeyboard = ActiveKeyboard.Name;
General.Default.Save();
ChangingKeyboard = false;
_events.PublishOnUIThread(new ActiveKeyboardChanged(oldKeyboard, ActiveKeyboard));
_logger.Debug("Enabled keyboard: {0}", keyboardProvider.Name);
}
}
@ -116,9 +120,17 @@ namespace Artemis.Managers
if (ActiveKeyboard == null)
return;
// Store the old keyboard so it can be used in the event we're raising later
var oldKeyboard = ActiveKeyboard;
var releaseName = ActiveKeyboard.Name;
ActiveKeyboard.Disable();
ActiveKeyboard = null;
General.Default.LastKeyboard = null;
General.Default.Save();
_events.PublishOnUIThread(new ActiveKeyboardChanged(oldKeyboard, null));
_logger.Debug("Released keyboard: {0}", releaseName);
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Drawing;
using System.Timers;
using Artemis.Events;
using Caliburn.Micro;
@ -57,7 +58,6 @@ namespace Artemis.Managers
return;
}
// TODO: Deadlock maybe? I don't know what Resharper is on about
if (_effectManager.ActiveEffect == null)
{
var lastEffect = _effectManager.GetLastEffect();
@ -88,18 +88,6 @@ namespace Artemis.Managers
if (!Running)
return;
// Stop if no active keyboard
if (_keyboardManager.ActiveKeyboard == null)
{
_logger.Debug("No active keyboard, stopping");
Stop();
return;
}
// Lock both the active keyboard and active effect so they will not change while rendering.
lock (_keyboardManager)
{
lock (_effectManager)
{
// Stop if no active effect
if (_effectManager.ActiveEffect == null)
{
@ -107,18 +95,32 @@ namespace Artemis.Managers
Stop();
return;
}
var renderEffect = _effectManager.ActiveEffect;
if (_keyboardManager.ChangingKeyboard)
return;
// Stop if no active keyboard
if (_keyboardManager.ActiveKeyboard == null)
{
_logger.Debug("No active keyboard, stopping");
Stop();
return;
}
lock (_keyboardManager.ActiveKeyboard)
{
// Skip frame if effect is still initializing
if (_effectManager.ActiveEffect.Initialized == false)
if (renderEffect.Initialized == false)
return;
// Update the current effect
if (_effectManager.ActiveEffect.Initialized)
_effectManager.ActiveEffect.Update();
if (renderEffect.Initialized)
renderEffect.Update();
// Get ActiveEffect's bitmap
var bitmap = _effectManager.ActiveEffect.Initialized
? _effectManager.ActiveEffect.GenerateBitmap()
var bitmap = renderEffect.Initialized
? renderEffect.GenerateBitmap()
: null;
// Draw enabled overlays on top
@ -133,13 +135,20 @@ namespace Artemis.Managers
if (bitmap == null)
return;
// Fill the bitmap's background with blackness to avoid trailing colors on some keyboards
using (var g = Graphics.FromImage(bitmap))
{
var preFix = (Bitmap)bitmap.Clone();
g.Clear(Color.Black);
g.DrawImage(preFix, 0, 0);
}
// If it exists, send bitmap to the device
_keyboardManager.ActiveKeyboard.DrawBitmap(bitmap);
_keyboardManager.ActiveKeyboard?.DrawBitmap(bitmap);
// debugging TODO: Disable when window isn't shown (in Debug VM, or get rid of it, w/e)
_events.PublishOnUIThread(new ChangeBitmap(bitmap));
}
}
}
}
}

View File

@ -35,13 +35,8 @@ namespace Artemis.Modules.Effects.Debug
KeyboardRectangle = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard, 0, 0, new List<Color>
{
Color.Red,
Color.OrangeRed,
Color.Yellow,
Color.Green,
Color.Blue,
Color.Purple,
Color.DeepPink
Color.FromArgb(0, 226, 190),
Color.FromArgb(0, 208, 255)
}, LinearGradientMode.Horizontal);
Initialized = true;

View File

@ -1,5 +1,4 @@
using System;
using System.ComponentModel;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using Artemis.InjectionFactories;
@ -16,7 +15,6 @@ namespace Artemis.ViewModels.Abstract
public abstract class GameViewModel : Screen
{
private GameSettings _gameSettings;
private bool _startLoopManager;
protected GameViewModel(MainManager mainManager, GameModel gameModel, IEventAggregator events,
IProfileEditorViewModelFactory pFactory)
@ -34,6 +32,7 @@ namespace Artemis.ViewModels.Abstract
[Inject]
public ILogger Logger { get; set; }
[Inject]
public ProfilePreviewModel ProfilePreviewModel { get; set; }
@ -94,39 +93,38 @@ namespace Artemis.ViewModels.Abstract
protected override void OnActivate()
{
base.OnActivate();
SetEditorShown(true);
// OnActivate gets called at odd times, only start the LoopManager if it's been active
// for 600ms.
_startLoopManager = true;
Task.Factory.StartNew(() =>
{
Thread.Sleep(600);
if (MainManager.LoopManager.Running || !_startLoopManager)
return;
Logger.Debug("Starting LoopManager for profile preview");
MainManager.LoopManager.Start();
});
Task.Factory.StartNew(HandleActivationSwitch);
}
protected override void OnDeactivate(bool close)
{
base.OnDeactivate(close);
SetEditorShown(false);
_startLoopManager = false;
Task.Factory.StartNew(HandleActivationSwitch);
}
public void SetEditorShown(bool enable)
private void HandleActivationSwitch()
{
Thread.Sleep(600);
if (IsActive)
{
if (!MainManager.LoopManager.Running)
{
Logger.Debug("Starting LoopManager for profile preview");
MainManager.LoopManager.Start();
}
MainManager.EffectManager.ProfilePreviewModel = ProfilePreviewModel;
ProfilePreviewModel.SelectedProfile = ProfileEditor.SelectedProfile;
}
else
{
MainManager.EffectManager.ProfilePreviewModel = ProfilePreviewModel;
MainManager.EffectManager.ProfilePreviewModel.SelectedProfile = enable ? ProfileEditor.SelectedProfile : null;
ProfilePreviewModel.SelectedProfile = null;
}
}
private void ProfileUpdater(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != "SelectedProfile")
if (e.PropertyName != "SelectedProfile" && IsActive)
return;
GameModel.Profile = ProfileEditor.SelectedProfile;

View File

@ -48,7 +48,8 @@ namespace Artemis.ViewModels.Flyouts
{
get
{
var collection = new BindableCollection<string>(MainManager.KeyboardManager.KeyboardProviders.Select(k => k.Name));
var collection =
new BindableCollection<string>(MainManager.KeyboardManager.KeyboardProviders.Select(k => k.Name));
collection.Insert(0, "None");
return collection;
}
@ -70,7 +71,6 @@ namespace Artemis.ViewModels.Flyouts
get { return MainManager.ProgramEnabled; }
set
{
if (value)
MainManager.EnableProgram();
else
@ -111,7 +111,8 @@ namespace Artemis.ViewModels.Flyouts
return;
_logger.Debug("Handling SelectedKeyboard change in UI");
var keyboard = MainManager.KeyboardManager.KeyboardProviders.FirstOrDefault(k => k.Name == SelectedKeyboardProvider);
var keyboard = MainManager.KeyboardManager.KeyboardProviders
.FirstOrDefault(k => k.Name == SelectedKeyboardProvider);
if (keyboard != null)
{
MainManager.KeyboardManager.EnableKeyboard(keyboard);
@ -119,7 +120,6 @@ namespace Artemis.ViewModels.Flyouts
}
else
MainManager.KeyboardManager.ReleaseActiveKeyboard();
}
public void ToggleEnabled()

View File

@ -212,7 +212,10 @@ namespace Artemis.ViewModels
private void LoadProfiles()
{
Profiles.Clear();
Profiles.AddRange(ProfileProvider.GetAll(_gameModel));
if (_gameModel == null || ActiveKeyboard == null)
return;
Profiles.AddRange(ProfileProvider.GetAll(_gameModel, ActiveKeyboard));
SelectedProfile = Profiles.FirstOrDefault();
}

View File

@ -10,10 +10,12 @@ namespace Artemis.ViewModels
{
private readonly BaseViewModel[] _viewModels;
public ShellViewModel(BaseViewModel[] viewModels, IKernel kernel)
public ShellViewModel(IKernel kernel, IEventAggregator events, BaseViewModel[] viewModels)
{
_viewModels = viewModels;
events.Subscribe(this);
// Setup UI
DisplayName = "Artemis";
Flyouts = new BindableCollection<FlyoutBaseViewModel>

View File

@ -1,9 +1,9 @@
using System.Diagnostics;
using Caliburn.Micro;
using Artemis.ViewModels.Abstract;
namespace Artemis.ViewModels
{
public sealed class WelcomeViewModel : Screen
public sealed class WelcomeViewModel : BaseViewModel
{
public WelcomeViewModel()
{