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

Profile preview rewrite

This commit is contained in:
SpoinkyNL 2017-01-05 16:01:34 +01:00
parent fdcb3568d9
commit 9ddde37333
16 changed files with 938 additions and 892 deletions

View File

@ -336,6 +336,7 @@
<Compile Include="Events\ModuleChangedEventArgs.cs" /> <Compile Include="Events\ModuleChangedEventArgs.cs" />
<Compile Include="Events\EnabledChangedEventArgs.cs" /> <Compile Include="Events\EnabledChangedEventArgs.cs" />
<Compile Include="Events\KeyboardChangedEventArgs.cs" /> <Compile Include="Events\KeyboardChangedEventArgs.cs" />
<Compile Include="Events\ProfileChangedEventArgs.cs" />
<Compile Include="Events\ProfileDeviceEventsArg.cs" /> <Compile Include="Events\ProfileDeviceEventsArg.cs" />
<Compile Include="Events\RazerColorArrayChanged.cs" /> <Compile Include="Events\RazerColorArrayChanged.cs" />
<Compile Include="Events\RazerColorsChangedEventArgs.cs" /> <Compile Include="Events\RazerColorsChangedEventArgs.cs" />

View File

@ -0,0 +1,15 @@
using System;
using Artemis.Profiles;
namespace Artemis.Events
{
public class ProfileChangedEventArgs : EventArgs
{
public ProfileChangedEventArgs(ProfileModel profileModel)
{
ProfileModel = profileModel;
}
public ProfileModel ProfileModel { get; }
}
}

View File

@ -137,6 +137,10 @@ namespace Artemis.Managers
var processes = System.Diagnostics.Process.GetProcesses(); var processes = System.Diagnostics.Process.GetProcesses();
var module = ModuleManager.ActiveModule; var module = ModuleManager.ActiveModule;
// If the current active module is in preview-mode, leave it alone
if (module?.PreviewLayers != null)
return;
// If the active module is a process bound module, make sure it should still be enabled // If the active module is a process bound module, make sure it should still be enabled
if (module != null && module.IsBoundToProcess) if (module != null && module.IsBoundToProcess)
{ {

View File

@ -72,7 +72,8 @@ namespace Artemis.Managers
/// </summary> /// </summary>
/// <param name="moduleModel">The module to activate</param> /// <param name="moduleModel">The module to activate</param>
/// <param name="loopManager">Optionally pass the LoopManager to automatically start it, if it's not running.</param> /// <param name="loopManager">Optionally pass the LoopManager to automatically start it, if it's not running.</param>
public void ChangeActiveModule(ModuleModel moduleModel, LoopManager loopManager = null) /// <param name="storeAsLast">Whether or not to store this effect as the last effect</param>
public void ChangeActiveModule(ModuleModel moduleModel, LoopManager loopManager = null, bool storeAsLast = true)
{ {
if (_waitEffect != null) if (_waitEffect != null)
{ {
@ -82,8 +83,6 @@ namespace Artemis.Managers
if (moduleModel == null) if (moduleModel == null)
throw new ArgumentNullException(nameof(moduleModel)); throw new ArgumentNullException(nameof(moduleModel));
if (moduleModel.IsOverlay)
throw new ArgumentException("Can't set an General module as the active module");
if (_deviceManager.ActiveKeyboard == null) if (_deviceManager.ActiveKeyboard == null)
{ {
@ -102,7 +101,6 @@ namespace Artemis.Managers
return; return;
} }
var wasNull = false; var wasNull = false;
if (ActiveModule == null) if (ActiveModule == null)
{ {
@ -135,9 +133,8 @@ namespace Artemis.Managers
_logger.Debug("Changed active module to: {0}", moduleModel.Name); _logger.Debug("Changed active module to: {0}", moduleModel.Name);
if (ActiveModule.IsBoundToProcess || ActiveModule.IsOverlay || ActiveModule.Name == "Profile preview") if (ActiveModule.IsBoundToProcess || ActiveModule.IsOverlay || !storeAsLast)
return; return;
// Regular modules are stored as the last active module // Regular modules are stored as the last active module
_generalSettings.LastModule = ActiveModule?.Name; _generalSettings.LastModule = ActiveModule?.Name;
_generalSettings.Save(); _generalSettings.Save();
@ -156,7 +153,6 @@ namespace Artemis.Managers
ChangeActiveModule(module, loopManager); ChangeActiveModule(module, loopManager);
} }
/// <summary> /// <summary>
/// Clears the current module /// Clears the current module
/// </summary> /// </summary>

View File

@ -4,18 +4,17 @@ using System.Timers;
using Artemis.DAL; using Artemis.DAL;
using Artemis.Modules.Abstract; using Artemis.Modules.Abstract;
using Artemis.Settings; using Artemis.Settings;
using Ninject;
using Ninject.Extensions.Logging; using Ninject.Extensions.Logging;
namespace Artemis.Managers namespace Artemis.Managers
{ {
public class ProfileManager public class ProfileManager
{ {
private readonly ILogger _logger;
private readonly ModuleManager _moduleManager;
private readonly DeviceManager _deviceManager; private readonly DeviceManager _deviceManager;
private readonly LoopManager _loopManager;
private readonly GeneralSettings _generalSettings; private readonly GeneralSettings _generalSettings;
private readonly ILogger _logger;
private readonly LoopManager _loopManager;
private readonly ModuleManager _moduleManager;
public ProfileManager(ILogger logger, ModuleManager moduleManager, DeviceManager deviceManager, public ProfileManager(ILogger logger, ModuleManager moduleManager, DeviceManager deviceManager,
LoopManager loopManager) LoopManager loopManager)
@ -44,39 +43,41 @@ namespace Artemis.Managers
/// <param name="e"></param> /// <param name="e"></param>
private void SetupProfilePreview(object sender, ElapsedEventArgs e) private void SetupProfilePreview(object sender, ElapsedEventArgs e)
{ {
// if (string.IsNullOrEmpty(_generalSettings.LastKeyboard) || _deviceManager.ChangingKeyboard) if (string.IsNullOrEmpty(_generalSettings.LastKeyboard) || _deviceManager.ChangingKeyboard)
// return; return;
//
// var activePreview = PreviewViewModules.FirstOrDefault(vm => vm.IsActive); var activePreview = PreviewViewModules.FirstOrDefault(vm => vm.IsActive && vm.UsesProfileEditor);
// if (activePreview == null) if (activePreview != null)
// { EnsurePreviewActive(activePreview);
// // Should not be active if no selected profile is set else
// if (_moduleManager.ActiveModule != _profilePreviewModel) EnsurePreviewInactive();
// return; }
//
// _logger.Debug("Loading last module after profile preview"); private void EnsurePreviewActive(ModuleViewModel toBeActive)
// var lastModule = _moduleManager.GetLastModule(); {
// if (lastModule != null) // If the current module is the same as what should be active, don't do anything
// _moduleManager.ChangeActiveModule(lastModule); if (_moduleManager.ActiveModule != null && _moduleManager.ActiveModule == toBeActive.ModuleModel)
// else return;
// _moduleManager.ClearActiveModule();
// } _logger.Debug("Activate profile preview");
// else _moduleManager.ChangeActiveModule(toBeActive.ModuleModel, null, false);
// {
// if (_moduleManager.ActiveModule != null && _moduleManager.ActiveModule != _profilePreviewModel && // LoopManager might be running, this method won't do any harm in that case.
// _moduleManager.ActiveModule != activePreview.ModuleModel) _loopManager.StartAsync();
// { }
// _logger.Debug("Activate profile preview");
// _moduleManager.ChangeActiveModule(_profilePreviewModel); private void EnsurePreviewInactive()
// } {
// // Check if the active module is being previewed, if so, that should no longer be happening
// // LoopManager might be running, this method won't do any harm in that case. if (_moduleManager.ActiveModule?.PreviewLayers == null)
// _loopManager.StartAsync(); return;
//
// // Can safely spam this, it won't do anything if they are equal _logger.Debug("Deactivate profile preview");
// _profilePreviewModel.ProfileViewModel = activePreview.ProfileEditor.ProfileViewModel; var lastModule = _moduleManager.GetLastModule();
// _profilePreviewModel.ChangeProfile(activePreview.ModuleModel.ProfileModel); if (lastModule != null)
// } _moduleManager.ChangeActiveModule(lastModule);
else
_moduleManager.ClearActiveModule();
} }
} }
} }

View File

@ -2,6 +2,5 @@
{ {
public abstract class ModuleDataModel public abstract class ModuleDataModel
{ {
public ModuleDataModel ParentDataModel { get; set; }
} }
} }

View File

@ -23,13 +23,17 @@ namespace Artemis.Modules.Abstract
public ModuleModel(DeviceManager deviceManager, LuaManager luaManager) public ModuleModel(DeviceManager deviceManager, LuaManager luaManager)
{ {
_luaManager = luaManager; _luaManager = luaManager;
DeviceManager = deviceManager; DeviceManager = deviceManager;
PreviewLayers = new List<LayerModel>();
DeviceManager.OnKeyboardChanged += OnKeyboardChanged; DeviceManager.OnKeyboardChanged += OnKeyboardChanged;
} }
#region Events
public event EventHandler<ProfileChangedEventArgs> ProfileChanged;
#endregion
#region Abstract properties #region Abstract properties
/// <summary> /// <summary>
@ -95,6 +99,8 @@ namespace Artemis.Modules.Abstract
ProfileModel = profileModel; ProfileModel = profileModel;
ProfileModel?.Activate(_luaManager); ProfileModel?.Activate(_luaManager);
RaiseProfileChangedEvent(new ProfileChangedEventArgs(ProfileModel));
} }
public virtual void Enable() public virtual void Enable()
@ -107,7 +113,7 @@ namespace Artemis.Modules.Abstract
{ {
IsInitialized = false; IsInitialized = false;
PreviewLayers.Clear(); PreviewLayers = null;
ProfileModel?.Deactivate(_luaManager); ProfileModel?.Deactivate(_luaManager);
ProfileModel = null; ProfileModel = null;
} }
@ -123,6 +129,12 @@ namespace Artemis.Modules.Abstract
ChangeProfile(ProfileProvider.GetProfile(DeviceManager.ActiveKeyboard, this, profileName)); ChangeProfile(ProfileProvider.GetProfile(DeviceManager.ActiveKeyboard, this, profileName));
} }
protected virtual void RaiseProfileChangedEvent(ProfileChangedEventArgs e)
{
var handler = ProfileChanged;
handler?.Invoke(this, e);
}
public abstract void Update(); public abstract void Update();
public virtual void Render(RenderFrame frame, bool keyboardOnly) public virtual void Render(RenderFrame frame, bool keyboardOnly)
@ -134,35 +146,36 @@ namespace Artemis.Modules.Abstract
{ {
lock (ProfileModel) lock (ProfileModel)
{ {
// Get all enabled layers who's conditions are met // Use the preview layers if they are present, else get all layers who's conditions are met
var layers = GetRenderLayers(keyboardOnly); var layers = PreviewLayers ?? GetRenderLayers(keyboardOnly);
var preview = PreviewLayers != null;
// Render the keyboard layer-by-layer // Render the keyboard layer-by-layer
var keyboardRect = DeviceManager.ActiveKeyboard.KeyboardRectangle(); var keyboardRect = DeviceManager.ActiveKeyboard.KeyboardRectangle();
using (var g = Graphics.FromImage(frame.KeyboardBitmap)) using (var g = Graphics.FromImage(frame.KeyboardBitmap))
{ {
ProfileModel?.DrawLayers(g, layers, DrawType.Keyboard, DataModel, keyboardRect, false, true); ProfileModel?.DrawLayers(g, layers, DrawType.Keyboard, DataModel, keyboardRect, preview);
} }
// Render mice layer-by-layer // Render mice layer-by-layer
var devRec = new Rect(0, 0, 40, 40); var devRec = new Rect(0, 0, 40, 40);
using (var g = Graphics.FromImage(frame.MouseBitmap)) using (var g = Graphics.FromImage(frame.MouseBitmap))
{ {
ProfileModel?.DrawLayers(g, layers, DrawType.Mouse, DataModel, devRec, false, true); ProfileModel?.DrawLayers(g, layers, DrawType.Mouse, DataModel, devRec, preview);
} }
// Render headsets layer-by-layer // Render headsets layer-by-layer
using (var g = Graphics.FromImage(frame.HeadsetBitmap)) using (var g = Graphics.FromImage(frame.HeadsetBitmap))
{ {
ProfileModel?.DrawLayers(g, layers, DrawType.Headset, DataModel, devRec, false, true); ProfileModel?.DrawLayers(g, layers, DrawType.Headset, DataModel, devRec, preview);
} }
// Render generic devices layer-by-layer // Render generic devices layer-by-layer
using (var g = Graphics.FromImage(frame.GenericBitmap)) using (var g = Graphics.FromImage(frame.GenericBitmap))
{ {
ProfileModel?.DrawLayers(g, layers, DrawType.Generic, DataModel, devRec, false, true); ProfileModel?.DrawLayers(g, layers, DrawType.Generic, DataModel, devRec, preview);
} }
// Render mousemats layer-by-layer // Render mousemats layer-by-layer
using (var g = Graphics.FromImage(frame.MousematBitmap)) using (var g = Graphics.FromImage(frame.MousematBitmap))
{ {
ProfileModel?.DrawLayers(g, layers, DrawType.Mousemat, DataModel, devRec, false, true); ProfileModel?.DrawLayers(g, layers, DrawType.Mousemat, DataModel, devRec, preview);
} }
// Trace debugging // Trace debugging

View File

@ -13,22 +13,16 @@ namespace Artemis.Modules.Abstract
{ {
private readonly ModuleManager _moduleManager; private readonly ModuleManager _moduleManager;
private readonly MainManager _mainManager; private readonly MainManager _mainManager;
private readonly IKernel _kernel;
private ModuleSettings _settings; private ModuleSettings _settings;
public ModuleViewModel(MainManager mainManager, ModuleModel moduleModel, IKernel kernel) public ModuleViewModel(MainManager mainManager, ModuleModel moduleModel, IKernel kernel)
{ {
_mainManager = mainManager; _mainManager = mainManager;
_kernel = kernel;
_moduleManager = mainManager.ModuleManager; _moduleManager = mainManager.ModuleManager;
ModuleModel = moduleModel; ModuleModel = moduleModel;
Settings = moduleModel.Settings; Settings = moduleModel.Settings;
IParameter[] args =
{
new ConstructorArgument("mainManager", _mainManager),
new ConstructorArgument("moduleModel", ModuleModel),
new ConstructorArgument("lastProfile", Settings.LastProfile)
};
ProfileEditor = kernel.Get<ProfileEditorViewModel>(args);
_mainManager.EnabledChanged += MainManagerOnEnabledChanged; _mainManager.EnabledChanged += MainManagerOnEnabledChanged;
_moduleManager.EffectChanged += ModuleManagerOnModuleChanged; _moduleManager.EffectChanged += ModuleManagerOnModuleChanged;
@ -125,13 +119,24 @@ namespace Artemis.Modules.Abstract
protected override void OnActivate() protected override void OnActivate()
{ {
base.OnActivate(); base.OnActivate();
ProfileEditor.Activate();
if (!UsesProfileEditor)
return;
IParameter[] args =
{
new ConstructorArgument("mainManager", _mainManager),
new ConstructorArgument("moduleModel", ModuleModel),
new ConstructorArgument("lastProfile", Settings.LastProfile)
};
ProfileEditor = _kernel.Get<ProfileEditorViewModel>(args);
} }
protected override void OnDeactivate(bool close) protected override void OnDeactivate(bool close)
{ {
base.OnDeactivate(close); base.OnDeactivate(close);
ProfileEditor.Deactivate(); ProfileEditor?.Dispose();
ProfileEditor = null;
} }
} }
} }

View File

@ -1,4 +1,5 @@
using Artemis.Modules.Abstract; using Artemis.Modules.Abstract;
using Artemis.Modules.General.GeneralProfile;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
namespace Artemis.Modules.Games.Dota2 namespace Artemis.Modules.Games.Dota2
@ -15,8 +16,6 @@ namespace Artemis.Modules.Games.Dota2
public Previously previously { get; set; } public Previously previously { get; set; }
} }
[MoonSharpUserData] [MoonSharpUserData]
public class Provider public class Provider
{ {

View File

@ -29,7 +29,7 @@
</Label> </Label>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Label Content="Enable module" Margin="0 3 0 0" HorizontalAlignment="Right" /> <Label Content="Enable module" Margin="0 3 0 0" HorizontalAlignment="Right" />
<ToggleButton Margin="0 3 0 0" Width="25" Height="25" <ToggleButton Margin="0 3 0 0" Width="25" Height="25"
Style="{DynamicResource MetroCircleToggleButtonStyle}" Style="{DynamicResource MetroCircleToggleButtonStyle}"
ToolTip="Note: You can't enable an module when Artemis is disabled" ToolTip="Note: You can't enable an module when Artemis is disabled"
IsChecked="{Binding Path=Settings.Enabled, Mode=OneWay}" IsChecked="{Binding Path=Settings.Enabled, Mode=OneWay}"
@ -41,9 +41,8 @@
<ContentControl Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ProfileEditor" Margin="0,0,-30,0" /> <ContentControl Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ProfileEditor" Margin="0,0,-30,0" />
<TextBlock x:Name="VersionText" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" <TextBlock x:Name="VersionText" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center"
Margin="0,8" Margin="0,8" TextWrapping="Wrap" HorizontalAlignment="Left"
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold" Foreground="{DynamicResource HighlightBrush}" />
Foreground="{DynamicResource HighlightBrush}" MaxWidth="510" TextAlignment="Justify" />
<!-- Buttons --> <!-- Buttons -->
<StackPanel Grid.Column="0" Grid.Row="5" Orientation="Horizontal" VerticalAlignment="Bottom"> <StackPanel Grid.Column="0" Grid.Row="5" Orientation="Horizontal" VerticalAlignment="Bottom">

View File

@ -7,7 +7,9 @@ namespace Artemis.Modules.Overlays.OverlayProfile
{ {
public OverlayProfileDataModel() public OverlayProfileDataModel()
{ {
ParentDataModel = new GeneralProfileDataModel(); GeneralDataModel = new GeneralProfileDataModel();
} }
public GeneralProfileDataModel GeneralDataModel { get; set; }
} }
} }

View File

@ -25,7 +25,8 @@ namespace Artemis.Modules.Overlays.OverlayProfile
public override void Update() public override void Update()
{ {
// TODO: Find a clean way to update the parent profile model // TODO: Find a clean way to update the parent profile model
DataModel.ParentDataModel = _generalProfileModel.DataModel; ((OverlayProfileDataModel) DataModel).GeneralDataModel =
(GeneralProfileDataModel) _generalProfileModel.DataModel;
} }
} }
} }

View File

@ -104,9 +104,8 @@ namespace Artemis.Profiles
/// <param name="dataModel">The data model to base the layer's properties on</param> /// <param name="dataModel">The data model to base the layer's properties on</param>
/// <param name="rect">A rectangle matching the current keyboard's size on a scale of 4, used for clipping</param> /// <param name="rect">A rectangle matching the current keyboard's size on a scale of 4, used for clipping</param>
/// <param name="preview">Indicates wheter the layer is drawn as a preview, ignoring dynamic properties</param> /// <param name="preview">Indicates wheter the layer is drawn as a preview, ignoring dynamic properties</param>
/// <param name="updateAnimations">Wheter or not to update the layer's animations</param>
internal void DrawLayers(Graphics g, List<LayerModel> renderLayers, DrawType drawType, ModuleDataModel dataModel, internal void DrawLayers(Graphics g, List<LayerModel> renderLayers, DrawType drawType, ModuleDataModel dataModel,
Rect rect, bool preview, bool updateAnimations) Rect rect, bool preview)
{ {
renderLayers = renderLayers.Where(rl => rl.LayerType.DrawType == drawType).ToList(); renderLayers = renderLayers.Where(rl => rl.LayerType.DrawType == drawType).ToList();
var visual = new DrawingVisual(); var visual = new DrawingVisual();
@ -119,12 +118,12 @@ namespace Artemis.Profiles
// Update the layers // Update the layers
foreach (var layerModel in layerModels) foreach (var layerModel in layerModels)
layerModel.Update(dataModel, preview, updateAnimations); layerModel.Update(dataModel, preview, true);
RaiseDeviceUpdatedEvent(new ProfileDeviceEventsArg(drawType, dataModel, preview, null)); RaiseDeviceUpdatedEvent(new ProfileDeviceEventsArg(drawType, dataModel, preview, null));
// Draw the layers // Draw the layers
foreach (var layerModel in layerModels) foreach (var layerModel in layerModels)
layerModel.Draw(dataModel, c, preview, updateAnimations); layerModel.Draw(dataModel, c, preview, true);
RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(drawType, dataModel, preview, c)); RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(drawType, dataModel, preview, c));
// Remove the clip // Remove the clip

View File

@ -35,7 +35,7 @@ namespace Artemis.Utilities
return null; return null;
var value = prop.GetValue(o, null); var value = prop.GetValue(o, null);
if ((propertyNames.Length == 1) || (value == null)) if (propertyNames.Length == 1 || value == null)
return value; return value;
return GetPropertyValue(value, path.Replace(propertyNames[0] + ".", "")); return GetPropertyValue(value, path.Replace(propertyNames[0] + ".", ""));
} }
@ -46,31 +46,31 @@ namespace Artemis.Utilities
string path = "") string path = "")
{ {
var list = new List<PropertyCollection>(); var list = new List<PropertyCollection>();
foreach (var propertyInfo in getProperties) foreach (var propInfo in getProperties)
{ {
var friendlyName = Empty; var friendlyName = Empty;
if (propertyInfo.PropertyType.Name == "Int32") if (propInfo.PropertyType.Name == "Int32")
friendlyName = "(Number)"; friendlyName = "(Number)";
else if (propertyInfo.PropertyType.Name == "Single") else if (propInfo.PropertyType.Name == "Single")
friendlyName = "(Decimal)"; friendlyName = "(Decimal)";
else if (propertyInfo.PropertyType.Name == "String") else if (propInfo.PropertyType.Name == "String")
friendlyName = "(Text)"; friendlyName = "(Text)";
else if (propertyInfo.PropertyType.Name == "Boolean") else if (propInfo.PropertyType.Name == "Boolean")
friendlyName = "(Yes/no)"; friendlyName = "(Yes/no)";
if (propertyInfo.PropertyType.BaseType?.Name == "Enum") if (propInfo.PropertyType.BaseType?.Name == "Enum")
friendlyName = "(Choice)"; friendlyName = "(Choice)";
var parent = new PropertyCollection var parent = new PropertyCollection
{ {
Type = propertyInfo.PropertyType.Name, Type = propInfo.PropertyType.Name,
DisplayType = friendlyName, DisplayType = friendlyName,
Display = $"{path.Replace(".", " ")}{propertyInfo.Name}", Display = $"{path.Replace(".", " ")}{propInfo.Name}",
Path = $"{path}{propertyInfo.Name}" Path = $"{path}{propInfo.Name}"
}; };
if (propertyInfo.PropertyType.BaseType?.Name == "Enum") if (propInfo.PropertyType.BaseType?.Name == "Enum")
{ {
parent.EnumValues = Enum.GetNames(propertyInfo.PropertyType); parent.EnumValues = Enum.GetNames(propInfo.PropertyType);
parent.Type = "Enum"; parent.Type = "Enum";
} }
@ -78,13 +78,10 @@ namespace Artemis.Utilities
list.Add(parent); list.Add(parent);
// Don't go into Strings, DateTimes or anything with JsonIgnore on it // Don't go into Strings, DateTimes or anything with JsonIgnore on it
if (propertyInfo.PropertyType.Name != "String" && if (propInfo.PropertyType.Name != "String" &&
propertyInfo.PropertyType.Name != "DateTime" && propInfo.PropertyType.Name != "DateTime" &&
propertyInfo.CustomAttributes.All(a => a.AttributeType != typeof(JsonIgnoreAttribute))) propInfo.CustomAttributes.All(a => a.AttributeType != typeof(JsonIgnoreAttribute)))
{ list.AddRange(GenerateTypeMap(propInfo.PropertyType.GetProperties(), path + $"{propInfo.Name}."));
list.AddRange(GenerateTypeMap(propertyInfo.PropertyType.GetProperties(),
path + $"{propertyInfo.Name}."));
}
} }
return list; return list;
} }

View File

@ -35,13 +35,13 @@ using Timer = System.Timers.Timer;
namespace Artemis.ViewModels.Profiles namespace Artemis.ViewModels.Profiles
{ {
public sealed class ProfileEditorViewModel : Screen, IDropTarget public sealed class ProfileEditorViewModel : Screen, IDropTarget, IDisposable
{ {
private readonly DeviceManager _deviceManager; private readonly DeviceManager _deviceManager;
private readonly MetroDialogService _dialogService;
private readonly LuaManager _luaManager; private readonly LuaManager _luaManager;
private readonly ModuleModel _moduleModel; private readonly ModuleModel _moduleModel;
private readonly Timer _saveTimer; private readonly Timer _saveTimer;
private readonly MetroDialogService _dialogService;
private readonly WindowService _windowService; private readonly WindowService _windowService;
private ImageSource _keyboardPreview; private ImageSource _keyboardPreview;
private ObservableCollection<LayerModel> _layers; private ObservableCollection<LayerModel> _layers;
@ -62,14 +62,18 @@ namespace Artemis.ViewModels.Profiles
Layers = new ObservableCollection<LayerModel>(); Layers = new ObservableCollection<LayerModel>();
ProfileViewModel = profileViewModel; ProfileViewModel = profileViewModel;
ProfileViewModel.ModuleModel = _moduleModel;
PropertyChanged += EditorStateHandler; PropertyChanged += EditorStateHandler;
ProfileViewModel.PropertyChanged += LayerSelectedHandler; ProfileViewModel.PropertyChanged += LayerSelectedHandler;
_deviceManager.OnKeyboardChanged += DeviceManagerOnOnKeyboardChanged; _deviceManager.OnKeyboardChanged += DeviceManagerOnOnKeyboardChanged;
_moduleModel.ProfileChanged += ModuleModelOnProfileChanged;
LoadProfiles();
ProfileViewModel.Activate();
_saveTimer = new Timer(5000); _saveTimer = new Timer(5000);
_saveTimer.Elapsed += ProfileSaveHandler; _saveTimer.Elapsed += ProfileSaveHandler;
_saveTimer.Start();
LoadProfiles();
} }
public ProfileViewModel ProfileViewModel { get; set; } public ProfileViewModel ProfileViewModel { get; set; }
@ -113,7 +117,6 @@ namespace Artemis.ViewModels.Profiles
_moduleModel.ChangeProfile(ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _moduleModel, value)); _moduleModel.ChangeProfile(ProfileProvider.GetProfile(_deviceManager.ActiveKeyboard, _moduleModel, value));
NotifyOfPropertyChange(() => SelectedProfileName); NotifyOfPropertyChange(() => SelectedProfileName);
NotifyOfPropertyChange(() => SelectedProfile);
} }
} }
@ -201,6 +204,13 @@ namespace Artemis.ViewModels.Profiles
UpdateLayerList(source); UpdateLayerList(source);
} }
private void ModuleModelOnProfileChanged(object sender, ProfileChangedEventArgs e)
{
NotifyOfPropertyChange(() => SelectedProfileName);
NotifyOfPropertyChange(() => SelectedProfile);
NotifyOfPropertyChange(() => ProfileViewModel.SelectedProfile);
}
/// <summary> /// <summary>
/// Handles chaning the active keyboard, updating the preview image and profiles collection /// Handles chaning the active keyboard, updating the preview image and profiles collection
/// </summary> /// </summary>
@ -210,19 +220,6 @@ namespace Artemis.ViewModels.Profiles
LoadProfiles(); LoadProfiles();
} }
public void Activate()
{
ProfileViewModel.Activate();
_saveTimer.Start();
}
public void Deactivate()
{
ProfileViewModel.Deactivate();
SelectedProfile?.Deactivate(_luaManager);
_saveTimer.Stop();
}
/// <summary> /// <summary>
/// Loads all profiles for the current game and keyboard /// Loads all profiles for the current game and keyboard
/// </summary> /// </summary>
@ -781,6 +778,15 @@ namespace Artemis.ViewModels.Profiles
} }
} }
public void Dispose()
{
ProfileViewModel.Deactivate();
_saveTimer?.Stop();
_saveTimer?.Dispose();
_watcher?.Dispose();
}
#endregion #endregion
} }
} }

View File

@ -7,6 +7,7 @@ using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using Artemis.Events; using Artemis.Events;
using Artemis.Managers; using Artemis.Managers;
using Artemis.Modules.Abstract;
using Artemis.Profiles; using Artemis.Profiles;
using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Layers.Models;
@ -43,7 +44,8 @@ namespace Artemis.ViewModels.Profiles
deviceManager.OnKeyboardChanged += DeviceManagerOnOnKeyboardChanged; deviceManager.OnKeyboardChanged += DeviceManagerOnOnKeyboardChanged;
} }
public ProfileModel SelectedProfile { get; set; } public ModuleModel ModuleModel { get; set; }
public ProfileModel SelectedProfile => ModuleModel?.ProfileModel;
public LayerModel SelectedLayer public LayerModel SelectedLayer
{ {
@ -99,6 +101,7 @@ namespace Artemis.ViewModels.Profiles
if (!Activated) if (!Activated)
return; return;
// Update the glowing effect around the keyboard
if (_blurProgress > 2) if (_blurProgress > 2)
_blurProgress = 0; _blurProgress = 0;
_blurProgress = _blurProgress + 0.025; _blurProgress = _blurProgress + 0.025;
@ -111,9 +114,16 @@ namespace Artemis.ViewModels.Profiles
var preview = new DrawingImage(); var preview = new DrawingImage();
preview.Freeze(); preview.Freeze();
KeyboardPreview = preview; KeyboardPreview = preview;
// Setup layers for the next frame
if (ModuleModel.IsInitialized)
ModuleModel.PreviewLayers = new List<LayerModel>();
return; return;
} }
var renderLayers = GetRenderLayers();
// Draw the current frame to the preview
var keyboardRect = _deviceManager.ActiveKeyboard.KeyboardRectangle(4); var keyboardRect = _deviceManager.ActiveKeyboard.KeyboardRectangle(4);
var visual = new DrawingVisual(); var visual = new DrawingVisual();
using (var drawingContext = visual.RenderOpen()) using (var drawingContext = visual.RenderOpen())
@ -122,11 +132,8 @@ namespace Artemis.ViewModels.Profiles
drawingContext.PushClip(new RectangleGeometry(keyboardRect)); drawingContext.PushClip(new RectangleGeometry(keyboardRect));
drawingContext.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect); drawingContext.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, keyboardRect);
// Get the layers that must be drawn
var drawLayers = GetRenderLayers();
// Draw the layers // Draw the layers
foreach (var layer in drawLayers) foreach (var layer in renderLayers)
{ {
layer.Update(null, true, false); layer.Update(null, true, false);
if (layer.LayerType.ShowInEdtor) if (layer.LayerType.ShowInEdtor)
@ -166,16 +173,18 @@ namespace Artemis.ViewModels.Profiles
new Point(layerRect.BottomRight.X - 0.7, layerRect.BottomRight.Y - 0.7)); new Point(layerRect.BottomRight.X - 0.7, layerRect.BottomRight.Y - 0.7));
} }
SelectedProfile.RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(DrawType.Preview, null, true, SelectedProfile.RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(DrawType.Preview, null, true, drawingContext));
drawingContext));
// Remove the clip // Remove the clip
drawingContext.Pop(); drawingContext.Pop();
} }
var drawnPreview = new DrawingImage(visual.Drawing); var drawnPreview = new DrawingImage(visual.Drawing);
drawnPreview.Freeze(); drawnPreview.Freeze();
KeyboardPreview = drawnPreview; KeyboardPreview = drawnPreview;
// Setup layers for the next frame
if (ModuleModel.IsInitialized)
ModuleModel.PreviewLayers = renderLayers;
} }
private void DeviceManagerOnOnKeyboardChanged(object sender, KeyboardChangedEventArgs e) private void DeviceManagerOnOnKeyboardChanged(object sender, KeyboardChangedEventArgs e)