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

Performance improvements, especially on large profiles

This commit is contained in:
SpoinkyNL 2016-06-05 22:13:46 +02:00
parent 1ea471280b
commit b7423ad6d6
24 changed files with 208 additions and 299 deletions

View File

@ -1,5 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Windows.Media; using System.Windows.Media;
@ -51,8 +50,7 @@ namespace Artemis.Models.Profiles
return; return;
// Preview simply shows the properties as they are. When not previewing they are applied // Preview simply shows the properties as they are. When not previewing they are applied
LayerPropertiesModel appliedProperties; AppliedProperties appliedProperties;
Properties.Brush.Freeze();
if (!preview) if (!preview)
{ {
if (!ConditionsMet<T>(dataModel)) if (!ConditionsMet<T>(dataModel))
@ -60,13 +58,12 @@ namespace Artemis.Models.Profiles
appliedProperties = Properties.GetAppliedProperties(dataModel); appliedProperties = Properties.GetAppliedProperties(dataModel);
} }
else else
appliedProperties = GeneralHelpers.Clone(Properties); appliedProperties = Properties.GetAppliedProperties(dataModel, true);
// Update animations on layer types that support them // Update animations on layer types that support them
if (LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif) if (LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif)
{ {
AnimationUpdater.UpdateAnimation((KeyboardPropertiesModel) Properties, AnimationUpdater.UpdateAnimation((KeyboardPropertiesModel) Properties, updateAnimations);
(KeyboardPropertiesModel) appliedProperties, updateAnimations);
} }
switch (LayerType) switch (LayerType)
@ -77,10 +74,10 @@ namespace Artemis.Models.Profiles
layerModel.Draw<T>(dataModel, c, preview, updateAnimations); layerModel.Draw<T>(dataModel, c, preview, updateAnimations);
break; break;
case LayerType.Keyboard: case LayerType.Keyboard:
Drawer.Draw(c, (KeyboardPropertiesModel) Properties, (KeyboardPropertiesModel) appliedProperties); Drawer.Draw(c, (KeyboardPropertiesModel) Properties, appliedProperties);
break; break;
case LayerType.KeyboardGif: case LayerType.KeyboardGif:
GifImage = Drawer.DrawGif(c, (KeyboardPropertiesModel) appliedProperties, GifImage); GifImage = Drawer.DrawGif(c, (KeyboardPropertiesModel)Properties, appliedProperties, GifImage);
break; break;
} }
} }
@ -93,23 +90,17 @@ namespace Artemis.Models.Profiles
return null; return null;
// Preview simply shows the properties as they are. When not previewing they are applied // Preview simply shows the properties as they are. When not previewing they are applied
LayerPropertiesModel appliedProperties; AppliedProperties appliedProperties;
if (!preview) if (!preview)
{ {
if (!ConditionsMet<T>(dataModel)) if (!ConditionsMet<T>(dataModel))
return null; // Don't return the brush when not previewing and the conditions arent met return null; // Return null when not previewing and the conditions arent met
appliedProperties = Properties.GetAppliedProperties(dataModel); appliedProperties = Properties.GetAppliedProperties(dataModel);
} }
else else
appliedProperties = GeneralHelpers.Clone(Properties); appliedProperties = Properties.GetAppliedProperties(dataModel, true);
// TODO: Mouse/headset animations // TODO: Mouse/headset animations
// Update animations on layer types that support them
//if (LayerType != LayerType.Folder && updateAnimations)
//{
// AnimationUpdater.UpdateAnimation((KeyboardPropertiesModel)Properties,
// (KeyboardPropertiesModel)appliedProperties);
//}
if (LayerType != LayerType.Folder) if (LayerType != LayerType.Folder)
return appliedProperties.Brush; return appliedProperties.Brush;
@ -165,18 +156,24 @@ namespace Artemis.Models.Profiles
/// <returns></returns> /// <returns></returns>
public bool MustDraw() public bool MustDraw()
{ {
// If any of the parents are disabled, this layer must not be drawn
var parent = Parent;
while (parent != null)
{
if (!parent.Enabled)
return false;
parent = parent.Parent;
}
return Enabled && (LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif); return Enabled && (LayerType == LayerType.Keyboard || LayerType == LayerType.KeyboardGif);
} }
public IEnumerable<LayerModel> GetAllLayers(bool ignoreEnabled) public IEnumerable<LayerModel> GetLayers()
{ {
var layers = new List<LayerModel>(); var layers = new List<LayerModel>();
foreach (var layerModel in Children) foreach (var layerModel in Children)
{ {
if (ignoreEnabled && !layerModel.Enabled)
continue;
layers.Add(layerModel); layers.Add(layerModel);
layers.AddRange(layerModel.Children); layers.AddRange(layerModel.GetLayers());
} }
return layers; return layers;
@ -236,7 +233,7 @@ namespace Artemis.Models.Profiles
Profile.Layers.Add(source); Profile.Layers.Add(source);
} }
} }
#region IChildItem<Parent> Members #region IChildItem<Parent> Members
LayerModel IChildItem<LayerModel>.Parent LayerModel IChildItem<LayerModel>.Parent

View File

@ -104,17 +104,13 @@ namespace Artemis.Models.Profiles
/// <summary> /// <summary>
/// Gives all the layers and their children in a flat list /// Gives all the layers and their children in a flat list
/// </summary> /// </summary>
public List<LayerModel> GetLayers(bool ignoreEnabled = true) public List<LayerModel> GetLayers()
{ {
var layers = new List<LayerModel>(); var layers = new List<LayerModel>();
foreach (var layerModel in Layers) foreach (var layerModel in Layers)
{ {
if (ignoreEnabled && !layerModel.Enabled)
{
continue;
}
layers.Add(layerModel); layers.Add(layerModel);
layers.AddRange(layerModel.GetAllLayers(ignoreEnabled)); layers.AddRange(layerModel.GetLayers());
} }
return layers; return layers;
@ -126,7 +122,7 @@ namespace Artemis.Models.Profiles
/// <param name="keyboardRectangle"></param> /// <param name="keyboardRectangle"></param>
public void FixBoundaries(Rect keyboardRectangle) public void FixBoundaries(Rect keyboardRectangle)
{ {
foreach (var layer in GetLayers(false)) foreach (var layer in GetLayers())
{ {
if (layer.LayerType != LayerType.Keyboard && layer.LayerType != LayerType.KeyboardGif) if (layer.LayerType != LayerType.Keyboard && layer.LayerType != LayerType.KeyboardGif)
continue; continue;

View File

@ -37,7 +37,7 @@ namespace Artemis.Models.Profiles.Properties
/// </summary> /// </summary>
public LayerPropertyOptions LayerPropertyOptions { get; set; } public LayerPropertyOptions LayerPropertyOptions { get; set; }
internal void ApplyProperty(IGameDataModel dataModel, KeyboardPropertiesModel properties) internal void ApplyProperty(IGameDataModel dataModel, AppliedProperties properties)
{ {
if (LayerPropertyType == LayerPropertyType.PercentageOf) if (LayerPropertyType == LayerPropertyType.PercentageOf)
ApplyPercentageOf(dataModel, properties, PercentageSource); ApplyPercentageOf(dataModel, properties, PercentageSource);
@ -45,7 +45,7 @@ namespace Artemis.Models.Profiles.Properties
ApplyPercentageOfProperty(dataModel, properties); ApplyPercentageOfProperty(dataModel, properties);
} }
private void ApplyPercentageOf(IGameDataModel dataModel, KeyboardPropertiesModel properties, double src) private void ApplyPercentageOf(IGameDataModel dataModel, AppliedProperties properties, double src)
{ {
if (GameProperty == null) if (GameProperty == null)
return; return;
@ -61,7 +61,7 @@ namespace Artemis.Models.Profiles.Properties
ApplyOpacity(properties, percentage); ApplyOpacity(properties, percentage);
} }
private void ApplyWidth(KeyboardPropertiesModel properties, double percentage) private void ApplyWidth(AppliedProperties properties, double percentage)
{ {
var newWidth = percentage * properties.Width; var newWidth = percentage * properties.Width;
var difference = properties.Width - newWidth; var difference = properties.Width - newWidth;
@ -72,7 +72,7 @@ namespace Artemis.Models.Profiles.Properties
properties.X = properties.X + difference; properties.X = properties.X + difference;
} }
private void ApplyHeight(KeyboardPropertiesModel properties, double percentage) private void ApplyHeight(AppliedProperties properties, double percentage)
{ {
var newHeight = percentage*properties.Height; var newHeight = percentage*properties.Height;
var difference = properties.Height - newHeight; var difference = properties.Height - newHeight;
@ -82,7 +82,7 @@ namespace Artemis.Models.Profiles.Properties
properties.Y = properties.Y + difference; properties.Y = properties.Y + difference;
} }
private void ApplyOpacity(KeyboardPropertiesModel properties, double percentage) private void ApplyOpacity(AppliedProperties properties, double percentage)
{ {
properties.Opacity = percentage*properties.Opacity; properties.Opacity = percentage*properties.Opacity;
if (properties.Opacity < 0.0) if (properties.Opacity < 0.0)
@ -95,7 +95,7 @@ namespace Artemis.Models.Profiles.Properties
properties.Opacity = 1.0 - properties.Opacity; properties.Opacity = 1.0 - properties.Opacity;
} }
private void ApplyPercentageOfProperty(IGameDataModel dataModel, KeyboardPropertiesModel properties) private void ApplyPercentageOfProperty(IGameDataModel dataModel, AppliedProperties properties)
{ {
var value = dataModel.GetPropValue<int>(PercentageProperty); var value = dataModel.GetPropValue<int>(PercentageProperty);
ApplyPercentageOf(dataModel, properties, value); ApplyPercentageOf(dataModel, properties, value);

View File

@ -5,9 +5,9 @@ namespace Artemis.Models.Profiles.Properties
{ {
public class FolderPropertiesModel : LayerPropertiesModel public class FolderPropertiesModel : LayerPropertiesModel
{ {
public override LayerPropertiesModel GetAppliedProperties(IGameDataModel dataModel) public override AppliedProperties GetAppliedProperties(IGameDataModel dataModel, bool ignoreDynamic = false)
{ {
return GeneralHelpers.Clone(this); return new AppliedProperties();
} }
} }
} }

View File

@ -1,14 +1,12 @@
using Artemis.Models.Interfaces; using Artemis.Models.Interfaces;
using Artemis.Utilities;
namespace Artemis.Models.Profiles.Properties namespace Artemis.Models.Profiles.Properties
{ {
public class HeadsetPropertiesModel : LayerPropertiesModel public class HeadsetPropertiesModel : LayerPropertiesModel
{ {
public override LayerPropertiesModel GetAppliedProperties(IGameDataModel dataModel) public override AppliedProperties GetAppliedProperties(IGameDataModel dataModel, bool ignoreDynamic = false)
{ {
// TODO: Apply any properties, if applicable to headsets in the first place. return new AppliedProperties();
return GeneralHelpers.Clone(this);
} }
} }
} }

View File

@ -1,6 +1,8 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Windows; using System.Windows;
using System.Windows.Media;
using System.Xml.Serialization; using System.Xml.Serialization;
using Artemis.Models.Interfaces; using Artemis.Models.Interfaces;
using Artemis.Utilities; using Artemis.Utilities;
@ -33,15 +35,31 @@ namespace Artemis.Models.Profiles.Properties
return new Rect(X*scale, Y*scale, Width*scale, Height*scale); return new Rect(X*scale, Y*scale, Width*scale, Height*scale);
} }
public override LayerPropertiesModel GetAppliedProperties(IGameDataModel dataModel) public override AppliedProperties GetAppliedProperties(IGameDataModel dataModel, bool ignoreDynamic = false)
{ {
var properties = GeneralHelpers.Clone(this); var applied = new AppliedProperties
{
X = X,
Y = Y,
Width = Width,
Height = Height,
Opacity = Opacity,
Brush = Brush.CloneCurrentValue()
};
foreach (var dynamicProperty in properties.DynamicProperties) if (ignoreDynamic)
dynamicProperty.ApplyProperty(dataModel, properties); return applied;
properties.Brush.Opacity = Opacity;
return properties; foreach (var dynamicProperty in DynamicProperties)
dynamicProperty.ApplyProperty(dataModel, applied);
if (Math.Abs(applied.Opacity - 1) > 0.001)
{
applied.Brush = Brush.CloneCurrentValue();
applied.Brush.Opacity = applied.Opacity;
}
return applied;
} }
} }

View File

@ -23,8 +23,6 @@ namespace Artemis.Models.Profiles.Properties
Conditions = new List<LayerConditionModel>(); Conditions = new List<LayerConditionModel>();
} }
public abstract LayerPropertiesModel GetAppliedProperties(IGameDataModel dataModel);
public List<LayerConditionModel> Conditions { get; set; } public List<LayerConditionModel> Conditions { get; set; }
public Brush Brush public Brush Brush
@ -32,10 +30,35 @@ namespace Artemis.Models.Profiles.Properties
get { return _brush; } get { return _brush; }
set set
{ {
var cloned = value.Dispatcher.Invoke(() => GeneralHelpers.CloneAlt(value)); if (value == null)
{
_brush = null;
return;
}
if (value.IsFrozen)
{
_brush = value;
return;
}
// Clone the brush off of the UI thread and freeze it
var cloned = value.Dispatcher.Invoke(value.CloneCurrentValue);
cloned.Freeze(); cloned.Freeze();
_brush = cloned; _brush = cloned;
} }
} }
public abstract AppliedProperties GetAppliedProperties(IGameDataModel dataModel, bool ignoreDynamic = false);
}
public struct AppliedProperties
{
public double X { get; set; }
public double Y { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public double Opacity { get; set; }
public Brush Brush { get; set; }
} }
} }

View File

@ -1,14 +1,12 @@
using Artemis.Models.Interfaces; using Artemis.Models.Interfaces;
using Artemis.Utilities;
namespace Artemis.Models.Profiles.Properties namespace Artemis.Models.Profiles.Properties
{ {
public class MousePropertiesModel : LayerPropertiesModel public class MousePropertiesModel : LayerPropertiesModel
{ {
public override LayerPropertiesModel GetAppliedProperties(IGameDataModel dataModel) public override AppliedProperties GetAppliedProperties(IGameDataModel dataModel, bool ignoreDynamic = false)
{ {
// TODO: Apply any properties, if applicable to mice in the first place. return new AppliedProperties();
return GeneralHelpers.Clone(this);
} }
} }
} }

View File

@ -84,7 +84,7 @@ namespace Artemis.Modules.Games.CounterStrike
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Error(ex, "Failed to deserialize CS:GO JSON"); Logger?.Error(ex, "Failed to deserialize CS:GO JSON");
throw; throw;
} }

View File

@ -141,7 +141,7 @@ namespace Artemis.Modules.Games.Overwatch
{ {
if (Profile == null || GameDataModel == null) if (Profile == null || GameDataModel == null)
return null; return null;
return null;
return Profile.GenerateBrush<OverwatchDataModel>(GameDataModel, LayerType.Mouse, false, true); return Profile.GenerateBrush<OverwatchDataModel>(GameDataModel, LayerType.Mouse, false, true);
} }
@ -149,7 +149,7 @@ namespace Artemis.Modules.Games.Overwatch
{ {
if (Profile == null || GameDataModel == null) if (Profile == null || GameDataModel == null)
return null; return null;
return null;
return Profile.GenerateBrush<OverwatchDataModel>(GameDataModel, LayerType.Headset, false, true); return Profile.GenerateBrush<OverwatchDataModel>(GameDataModel, LayerType.Headset, false, true);
} }
} }

View File

@ -78,9 +78,8 @@ namespace Artemis.Modules.Games.Overwatch
} }
catch (Exception e) catch (Exception e)
{ {
Logger.Error(e, "Couldn't place Overwatch DLL, Overwatch support won't work."); Logger?.Error(e, "Couldn't place Overwatch DLL, Overwatch support won't work.");
} }
} }
} }
} }

View File

@ -1,12 +1,11 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Threading;
using System.Threading.Tasks;
using Artemis.Managers; using Artemis.Managers;
using Artemis.Models; using Artemis.Models;
using Artemis.Models.Profiles; using Artemis.Models.Profiles;
using Artemis.Modules.Effects.TypeWave;
using Artemis.Utilities; using Artemis.Utilities;
using Artemis.Utilities.Keyboard;
using Artemis.Utilities.LogitechDll; using Artemis.Utilities.LogitechDll;
using Brush = System.Windows.Media.Brush; using Brush = System.Windows.Media.Brush;
@ -14,16 +13,11 @@ namespace Artemis.Modules.Games.TheDivision
{ {
public class TheDivisionModel : GameModel public class TheDivisionModel : GameModel
{ {
private Wave _ammoWave;
private KeyboardRectangle _hpRect;
private KeyboardRectangle _p2;
private KeyboardRectangle _p3;
private KeyboardRectangle _p4;
private StickyValue<bool> _stickyAmmo; private StickyValue<bool> _stickyAmmo;
private StickyValue<bool> _stickyHp; private StickyValue<bool> _stickyHp;
private int _trans;
public TheDivisionModel(MainManager mainManager, TheDivisionSettings settings) : base(mainManager, settings, new TheDivisionDataModel()) public TheDivisionModel(MainManager mainManager, TheDivisionSettings settings)
: base(mainManager, settings, new TheDivisionDataModel())
{ {
Name = "TheDivision"; Name = "TheDivision";
ProcessName = "TheDivision"; ProcessName = "TheDivision";
@ -37,7 +31,13 @@ namespace Artemis.Modules.Games.TheDivision
public override void Dispose() public override void Dispose()
{ {
Initialized = false; Initialized = false;
DllManager.RestoreDll();
// Delay restoring the DLL to allow The Division to release it
Task.Factory.StartNew(() =>
{
Thread.Sleep(2000);
DllManager.RestoreDll();
});
_stickyAmmo.Dispose(); _stickyAmmo.Dispose();
_stickyHp.Dispose(); _stickyHp.Dispose();
@ -47,45 +47,6 @@ namespace Artemis.Modules.Games.TheDivision
{ {
Initialized = false; Initialized = false;
_ammoWave = new Wave(new Point(30, 14), 0, Color.Transparent);
_hpRect = new KeyboardRectangle(MainManager.DeviceManager.ActiveKeyboard, 3*Scale, 0*Scale,
new List<Color>(),
LinearGradientMode.Horizontal)
{
Height = 7*Scale,
Width = 21*Scale,
Rotate = true,
ContainedBrush = false
};
_p2 = new KeyboardRectangle(MainManager.DeviceManager.ActiveKeyboard, 0*Scale, 1*Scale,
new List<Color>(),
LinearGradientMode.Horizontal)
{
Height = 2*Scale,
Width = 3*Scale,
Rotate = true,
ContainedBrush = false
};
_p3 = new KeyboardRectangle(MainManager.DeviceManager.ActiveKeyboard, 0*Scale, 3*Scale,
new List<Color>(),
LinearGradientMode.Horizontal)
{
Height = 2*Scale,
Width = 3*Scale,
Rotate = true,
ContainedBrush = false
};
_p4 = new KeyboardRectangle(MainManager.DeviceManager.ActiveKeyboard, 0*Scale, 5*Scale,
new List<Color>(),
LinearGradientMode.Horizontal)
{
Height = 2*Scale,
Width = 3*Scale,
Rotate = true,
ContainedBrush = false
};
_stickyAmmo = new StickyValue<bool>(200); _stickyAmmo = new StickyValue<bool>(200);
_stickyHp = new StickyValue<bool>(200); _stickyHp = new StickyValue<bool>(200);
@ -113,7 +74,7 @@ namespace Artemis.Modules.Games.TheDivision
// Parses Division key data to game data // Parses Division key data to game data
private void InterpertrateDivisionKey(IReadOnlyList<int> parts) private void InterpertrateDivisionKey(IReadOnlyList<int> parts)
{ {
var gameDataModel = (TheDivisionDataModel)GameDataModel; var gameDataModel = (TheDivisionDataModel) GameDataModel;
var keyCode = parts[1]; var keyCode = parts[1];
var rPer = parts[2]; var rPer = parts[2];
var gPer = parts[3]; var gPer = parts[3];
@ -133,10 +94,12 @@ namespace Artemis.Modules.Games.TheDivision
newState = PlayerState.Offline; newState = PlayerState.Offline;
if (playerId == 1) if (playerId == 1)
gameDataModel.PartyMember1 = newState; gameDataModel.LowHp = (newState == PlayerState.Hit);
else if (playerId == 2) else if (playerId == 2)
gameDataModel.PartyMember2 = newState; gameDataModel.PartyMember1 = newState;
else if (playerId == 3) else if (playerId == 3)
gameDataModel.PartyMember2 = newState;
else if (playerId == 4)
gameDataModel.PartyMember3 = newState; gameDataModel.PartyMember3 = newState;
} }
// R blinks white when low on ammo // R blinks white when low on ammo
@ -165,81 +128,16 @@ namespace Artemis.Modules.Games.TheDivision
public override void Update() public override void Update()
{ {
var gameDataModel = (TheDivisionDataModel)GameDataModel; // DataModel updating is done whenever a pipe message is received
if (gameDataModel.LowAmmo)
{
_ammoWave.Size++;
if (_ammoWave.Size > 30)
{
_ammoWave.Size = 0;
_trans = 255;
}
}
else
_ammoWave.Size = 0;
_hpRect.Colors = gameDataModel.LowHp
? new List<Color> {Color.Red, Color.Orange}
: new List<Color> {Color.FromArgb(10, 255, 0), Color.FromArgb(80, 255, 45)};
if (gameDataModel.PartyMember1 == PlayerState.Offline)
_p2.Colors = new List<Color> {Color.Gray, Color.White};
else if (gameDataModel.PartyMember1 == PlayerState.Online)
_p2.Colors = new List<Color> {Color.FromArgb(10, 255, 0), Color.FromArgb(80, 255, 45)};
else
_p2.Colors = new List<Color> {Color.Red, Color.Orange};
if (gameDataModel.PartyMember2 == PlayerState.Offline)
_p3.Colors = new List<Color> {Color.Gray, Color.White};
else if (gameDataModel.PartyMember2 == PlayerState.Online)
_p3.Colors = new List<Color> {Color.FromArgb(10, 255, 0), Color.FromArgb(80, 255, 45)};
else
_p3.Colors = new List<Color> {Color.Red, Color.Orange};
if (gameDataModel.PartyMember3 == PlayerState.Offline)
_p4.Colors = new List<Color> {Color.Gray, Color.White};
else if (gameDataModel.PartyMember3 == PlayerState.Online)
_p4.Colors = new List<Color> {Color.FromArgb(10, 255, 0), Color.FromArgb(80, 255, 45)};
else
_p4.Colors = new List<Color> {Color.Red, Color.Orange};
} }
public override Bitmap GenerateBitmap() public override Bitmap GenerateBitmap()
{ {
var bitmap = MainManager.DeviceManager.ActiveKeyboard.KeyboardBitmap(Scale); if (Profile == null || GameDataModel == null)
using (var g = Graphics.FromImage(bitmap)) return null;
{
g.Clear(Color.Transparent);
_hpRect.Draw(g);
_p2.Draw(g);
_p3.Draw(g);
_p4.Draw(g);
// Very, very PH
if (_ammoWave.Size != 0)
{
var path = new GraphicsPath();
path.AddEllipse(_ammoWave.Point.X - _ammoWave.Size/2, _ammoWave.Point.Y - _ammoWave.Size/2,
_ammoWave.Size, _ammoWave.Size);
if (_ammoWave.Size > 15) var keyboardRect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(Scale);
_trans = _trans - 16; return Profile.GenerateBitmap<TheDivisionDataModel>(keyboardRect, GameDataModel, false, true);
if (_trans < 1)
_trans = 255;
var pthGrBrush = new PathGradientBrush(path)
{
SurroundColors = new[] {_ammoWave.Color},
CenterColor = Color.FromArgb(_trans, 255, 0, 0)
};
g.FillPath(pthGrBrush, path);
pthGrBrush.FocusScales = new PointF(0.3f, 0.8f);
g.FillPath(pthGrBrush, path);
g.DrawEllipse(new Pen(pthGrBrush, 1), _ammoWave.Point.X - _ammoWave.Size/2,
_ammoWave.Point.Y - _ammoWave.Size/2, _ammoWave.Size, _ammoWave.Size);
}
}
return bitmap;
} }
public override Brush GenerateMouseBrush() public override Brush GenerateMouseBrush()

View File

@ -25,7 +25,7 @@
<Label FontSize="20" HorizontalAlignment="Left"> <Label FontSize="20" HorizontalAlignment="Left">
<Label.Content> <Label.Content>
<AccessText TextWrapping="Wrap" <AccessText TextWrapping="Wrap"
Text="Shows verious game states and events on the keyboard." /> Text="Shows verious game states and events on the keyboard. (BETA, uses much CPU!)" />
</Label.Content> </Label.Content>
</Label> </Label>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">

View File

@ -62,25 +62,6 @@ namespace Artemis.Utilities
} }
} }
/// <summary>
/// Perform a deep Copy of the object.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>The copied object.</returns>
public static T CloneAlt<T>(T source)
{
// Don't serialize a null object, simply return the default for that object
if (ReferenceEquals(source, null))
return default(T);
var xaml = XamlWriter.Save(source);
var xamlString = new StringReader(xaml);
var xmlTextReader = new XmlTextReader(xamlString);
var deepCopyObject = (T)XamlReader.Load(xmlTextReader);
return deepCopyObject;
}
public static string Serialize<T>(T source) public static string Serialize<T>(T source)
{ {
// Don't serialize a null object, simply return the default for that object // Don't serialize a null object, simply return the default for that object

View File

@ -4,44 +4,40 @@ namespace Artemis.Utilities.Layers
{ {
public static class AnimationUpdater public static class AnimationUpdater
{ {
public static void UpdateAnimation(KeyboardPropertiesModel properties, KeyboardPropertiesModel appliedProperties, bool updateAnimations) public static void UpdateAnimation(KeyboardPropertiesModel properties, bool updateAnimations)
{ {
const int scale = 4; const int scale = 4;
var animateProperties = properties.Contain ? appliedProperties : properties; var progress = properties.AnimationProgress;
appliedProperties.AnimationProgress = properties.AnimationProgress;
var progress = appliedProperties.AnimationProgress;
switch (animateProperties.Animation) switch (properties.Animation)
{ {
case LayerAnimation.SlideRight: case LayerAnimation.SlideRight:
case LayerAnimation.SlideLeft: case LayerAnimation.SlideLeft:
if (progress + 1 >= animateProperties.Width*scale) if (progress + 1 >= properties.Width*scale)
progress = 0; progress = 0;
progress = progress + animateProperties.AnimationSpeed * 2; progress = progress + properties.AnimationSpeed * 2;
break; break;
case LayerAnimation.SlideDown: case LayerAnimation.SlideDown:
case LayerAnimation.SlideUp: case LayerAnimation.SlideUp:
if (progress + 1 >= animateProperties.Height*scale) if (progress + 1 >= properties.Height*scale)
progress = 0; progress = 0;
progress = progress + animateProperties.AnimationSpeed * 2; progress = progress + properties.AnimationSpeed * 2;
break; break;
case LayerAnimation.Pulse: case LayerAnimation.Pulse:
if (progress > 2) if (progress > 2)
progress = 0; progress = 0;
progress = progress + animateProperties.AnimationSpeed/2; progress = progress + properties.AnimationSpeed/2;
break; break;
case LayerAnimation.Grow: case LayerAnimation.Grow:
if (progress > 10) if (progress > 10)
progress = 0; progress = 0;
progress = progress + animateProperties.AnimationSpeed / 2.5; progress = progress + properties.AnimationSpeed / 2.5;
break; break;
default: default:
progress = progress + animateProperties.AnimationSpeed*2; progress = progress + properties.AnimationSpeed*2;
break; break;
} }
appliedProperties.AnimationProgress = progress;
// If not previewing, store the animation progress in the actual model for the next frame // If not previewing, store the animation progress in the actual model for the next frame
if (updateAnimations) if (updateAnimations)
properties.AnimationProgress = progress; properties.AnimationProgress = progress;

View File

@ -14,7 +14,7 @@ namespace Artemis.Utilities.Layers
{ {
public static class Drawer public static class Drawer
{ {
public static void Draw(DrawingContext c, KeyboardPropertiesModel props, KeyboardPropertiesModel applied) public static void Draw(DrawingContext c, KeyboardPropertiesModel props, AppliedProperties applied)
{ {
if (applied.Brush == null) if (applied.Brush == null)
return; return;
@ -28,56 +28,52 @@ namespace Artemis.Utilities.Layers
var s1 = new Rect(); var s1 = new Rect();
var s2 = new Rect(); var s2 = new Rect();
if (applied.Animation == LayerAnimation.SlideRight) if (props.Animation == LayerAnimation.SlideRight)
{ {
s1 = new Rect(new Point(rect.X + applied.AnimationProgress, rect.Y), new Size(rect.Width, rect.Height)); s1 = new Rect(new Point(rect.X + props.AnimationProgress, rect.Y), new Size(rect.Width, rect.Height));
s2 = new Rect(new Point(s1.X - rect.Width, rect.Y), new Size(rect.Width + 1, rect.Height)); s2 = new Rect(new Point(s1.X - rect.Width, rect.Y), new Size(rect.Width + 0.05, rect.Height));
} }
if (applied.Animation == LayerAnimation.SlideLeft) if (props.Animation == LayerAnimation.SlideLeft)
{ {
s1 = new Rect(new Point(rect.X - applied.AnimationProgress, rect.Y), s1 = new Rect(new Point(rect.X - props.AnimationProgress, rect.Y),
new Size(rect.Width + 1, rect.Height)); new Size(rect.Width + 0.05, rect.Height));
s2 = new Rect(new Point(s1.X + rect.Width, rect.Y), new Size(rect.Width, rect.Height)); s2 = new Rect(new Point(s1.X + rect.Width, rect.Y), new Size(rect.Width, rect.Height));
} }
if (applied.Animation == LayerAnimation.SlideDown) if (props.Animation == LayerAnimation.SlideDown)
{ {
s1 = new Rect(new Point(rect.X, rect.Y + applied.AnimationProgress), new Size(rect.Width, rect.Height)); s1 = new Rect(new Point(rect.X, rect.Y + props.AnimationProgress), new Size(rect.Width, rect.Height));
s2 = new Rect(new Point(s1.X, s1.Y - rect.Height), new Size(rect.Width, rect.Height)); s2 = new Rect(new Point(s1.X, s1.Y - rect.Height), new Size(rect.Width, rect.Height));
} }
if (applied.Animation == LayerAnimation.SlideUp) if (props.Animation == LayerAnimation.SlideUp)
{ {
s1 = new Rect(new Point(rect.X, rect.Y - applied.AnimationProgress), new Size(rect.Width, rect.Height)); s1 = new Rect(new Point(rect.X, rect.Y - props.AnimationProgress), new Size(rect.Width, rect.Height));
s2 = new Rect(new Point(s1.X, s1.Y + rect.Height), new Size(rect.Width, rect.Height)); s2 = new Rect(new Point(s1.X, s1.Y + rect.Height), new Size(rect.Width, rect.Height));
} }
var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale); var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale);
DrawRectangle(c, applied, clip, rect, s1, s2); DrawRectangle(c, props, applied, clip, rect, s1, s2);
} }
private static void DrawRectangle(DrawingContext c, KeyboardPropertiesModel properties, Rect clip, private static void DrawRectangle(DrawingContext c, KeyboardPropertiesModel props, AppliedProperties applied,
Rect rectangle, Rect clip, Rect rectangle, Rect slide1, Rect slide2)
Rect slide1, Rect slide2)
{ {
var brush = properties.Brush.CloneCurrentValue();
brush.Opacity = properties.Opacity;
// Apply the pulse animation // Apply the pulse animation
if (properties.Animation == LayerAnimation.Pulse) if (props.Animation == LayerAnimation.Pulse)
brush.Opacity = (Math.Sin(properties.AnimationProgress*Math.PI) + 1)*(properties.Opacity/2); applied.Brush.Opacity = (Math.Sin(props.AnimationProgress*Math.PI) + 1)*(props.Opacity/2);
else else
brush.Opacity = properties.Opacity; applied.Brush.Opacity = props.Opacity;
if (properties.Animation == LayerAnimation.Grow) if (props.Animation == LayerAnimation.Grow)
{ {
// Take an offset of 4 to allow layers to slightly leave their bounds // Take an offset of 4 to allow layers to slightly leave their bounds
var progress = (6.0 - properties.AnimationProgress)*10.0; var progress = (6.0 - props.AnimationProgress)*10.0;
if (progress < 0) if (progress < 0)
{ {
brush.Opacity = 1 + (0.025*progress); applied.Brush.Opacity = 1 + 0.025*progress;
if (brush.Opacity < 0) if (applied.Brush.Opacity < 0)
brush.Opacity = 0; applied.Brush.Opacity = 0;
if (brush.Opacity > 1) if (applied.Brush.Opacity > 1)
brush.Opacity = 1; applied.Brush.Opacity = 1;
} }
rectangle.Inflate(-rectangle.Width/100.0*progress, -rectangle.Height/100.0*progress); rectangle.Inflate(-rectangle.Width/100.0*progress, -rectangle.Height/100.0*progress);
clip.Inflate(-clip.Width/100.0*progress, -clip.Height/100.0*progress); clip.Inflate(-clip.Width/100.0*progress, -clip.Height/100.0*progress);
@ -85,41 +81,41 @@ namespace Artemis.Utilities.Layers
c.PushClip(new RectangleGeometry(clip)); c.PushClip(new RectangleGeometry(clip));
// Most animation types can be drawn regularly // Most animation types can be drawn regularly
if (properties.Animation == LayerAnimation.None || if (props.Animation == LayerAnimation.None ||
properties.Animation == LayerAnimation.Grow || props.Animation == LayerAnimation.Grow ||
properties.Animation == LayerAnimation.Pulse) props.Animation == LayerAnimation.Pulse)
{ {
c.DrawRectangle(brush, null, rectangle); c.DrawRectangle(applied.Brush, null, rectangle);
} }
// Sliding animations however, require offsetting two rects // Sliding animations however, require offsetting two rects
else else
{ {
c.PushClip(new RectangleGeometry(clip)); c.PushClip(new RectangleGeometry(clip));
c.DrawRectangle(brush, null, slide1); c.DrawRectangle(applied.Brush, null, slide1);
c.DrawRectangle(brush, null, slide2); c.DrawRectangle(applied.Brush, null, slide2);
c.Pop(); c.Pop();
} }
c.Pop(); c.Pop();
} }
public static GifImage DrawGif(DrawingContext c, KeyboardPropertiesModel properties, GifImage gifImage, public static GifImage DrawGif(DrawingContext c, KeyboardPropertiesModel props, AppliedProperties applied,
bool update = true) GifImage gifImage, bool update = true)
{ {
if (string.IsNullOrEmpty(properties.GifFile)) if (string.IsNullOrEmpty(props.GifFile))
return null; return null;
if (!File.Exists(properties.GifFile)) if (!File.Exists(props.GifFile))
return null; return null;
const int scale = 4; const int scale = 4;
// Only reconstruct GifImage if the underlying source has changed // Only reconstruct GifImage if the underlying source has changed
if (gifImage == null) if (gifImage == null)
gifImage = new GifImage(properties.GifFile); gifImage = new GifImage(props.GifFile);
if (gifImage.Source != properties.GifFile) if (gifImage.Source != props.GifFile)
gifImage = new GifImage(properties.GifFile); gifImage = new GifImage(props.GifFile);
var gifRect = new Rect(properties.X*scale, properties.Y*scale, properties.Width*scale, var gifRect = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale,
properties.Height*scale); applied.Height*scale);
var draw = update ? gifImage.GetNextFrame() : gifImage.GetFrame(0); var draw = update ? gifImage.GetNextFrame() : gifImage.GetFrame(0);
c.DrawImage(ImageUtilities.BitmapToBitmapImage(new Bitmap(draw)), gifRect); c.DrawImage(ImageUtilities.BitmapToBitmapImage(new Bitmap(draw)), gifRect);

View File

@ -1,4 +1,5 @@
using System.IO; using System;
using System.IO;
using Artemis.Properties; using Artemis.Properties;
using Microsoft.Win32; using Microsoft.Win32;
@ -13,16 +14,24 @@ namespace Artemis.Utilities.LogitechDll
if (!File.Exists(LogitechPath + @"\LogitechLed.dll") || !File.Exists(LogitechPath + @"\artemis.txt")) if (!File.Exists(LogitechPath + @"\LogitechLed.dll") || !File.Exists(LogitechPath + @"\artemis.txt"))
return false; return false;
// Get rid of our own DLL try
File.Delete(LogitechPath + @"\LogitechLed.dll"); {
// Get rid of our own DLL
File.Delete(LogitechPath + @"\LogitechLed.dll");
// Restore the backup // Restore the backup
if (File.Exists(LogitechPath + @"\LogitechLed.dll.bak")) if (File.Exists(LogitechPath + @"\LogitechLed.dll.bak"))
File.Copy(LogitechPath + @"\LogitechLed.dll.bak", LogitechPath + @"\LogitechLed.dll"); File.Copy(LogitechPath + @"\LogitechLed.dll.bak", LogitechPath + @"\LogitechLed.dll");
File.Delete(LogitechPath + @"\artemis.txt"); File.Delete(LogitechPath + @"\artemis.txt");
return true; return true;
}
catch (Exception)
{
return false;
}
} }
public static void PlaceDll() public static void PlaceDll()
@ -35,8 +44,11 @@ namespace Artemis.Utilities.LogitechDll
// Backup the existing DLL // Backup the existing DLL
if (File.Exists(LogitechPath + @"\LogitechLed.dll")) if (File.Exists(LogitechPath + @"\LogitechLed.dll"))
File.Move(LogitechPath + @"\LogitechLed.dll", {
LogitechPath + @"\LogitechLed.dll.bak"); if (File.Exists(LogitechPath + @"\LogitechLed.dll.bak"))
File.Delete(LogitechPath + @"\LogitechLed.dll.bak");
File.Move(LogitechPath + @"\LogitechLed.dll", LogitechPath + @"\LogitechLed.dll.bak");
}
// Copy our own DLL in place // Copy our own DLL in place
File.WriteAllBytes(LogitechPath + @"\LogitechLED.dll", File.WriteAllBytes(LogitechPath + @"\LogitechLED.dll",

View File

@ -63,7 +63,6 @@ namespace Artemis.Utilities.LogitechDll
private void HandleMessage(byte[] buffer) private void HandleMessage(byte[] buffer)
{ {
var request = Encoding.ASCII.GetString(buffer); var request = Encoding.ASCII.GetString(buffer);
Debug.WriteLine(request);
PipeMessage?.Invoke(request); PipeMessage?.Invoke(request);
} }
@ -106,7 +105,6 @@ namespace Artemis.Utilities.LogitechDll
// Convert byte buffer to string // Convert byte buffer to string
var stringData = Encoding.UTF8.GetString(buffer, 0, buffer.Length); var stringData = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
Debug.WriteLine(stringData + Environment.NewLine);
// Pass message back to calling form // Pass message back to calling form
PipeMessage?.Invoke(stringData); PipeMessage?.Invoke(stringData);

View File

@ -3,6 +3,7 @@ using System.Linq;
using Artemis.Models.Profiles.Properties; using Artemis.Models.Profiles.Properties;
using Artemis.Utilities; using Artemis.Utilities;
using Caliburn.Micro; using Caliburn.Micro;
using Castle.Core.Internal;
namespace Artemis.ViewModels.Profiles namespace Artemis.ViewModels.Profiles
{ {
@ -211,7 +212,8 @@ namespace Artemis.ViewModels.Profiles
if (original != null) if (original != null)
keyboardProperties.DynamicProperties.Remove(original); keyboardProperties.DynamicProperties.Remove(original);
keyboardProperties.DynamicProperties.Add(Proposed); if (!Proposed.GameProperty.IsNullOrEmpty())
keyboardProperties.DynamicProperties.Add(Proposed);
} }
} }
} }

View File

@ -172,6 +172,7 @@ namespace Artemis.ViewModels.Profiles
source.Order = -1; source.Order = -1;
target.Children.Add(source); target.Children.Add(source);
target.FixOrder(); target.FixOrder();
target.Expanded = true;
} }
else else
{ {

View File

@ -5,7 +5,6 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading;
using Artemis.Events; using Artemis.Events;
using Artemis.Managers; using Artemis.Managers;
using Artemis.Models.Profiles; using Artemis.Models.Profiles;
@ -91,7 +90,7 @@ namespace Artemis.ViewModels.Profiles
if (_blurProgress > 2) if (_blurProgress > 2)
_blurProgress = 0; _blurProgress = 0;
_blurProgress = _blurProgress + 0.025; _blurProgress = _blurProgress + 0.025;
BlurRadius = (Math.Sin(_blurProgress * Math.PI) + 1) * 10 + 10; BlurRadius = (Math.Sin(_blurProgress*Math.PI) + 1)*10 + 10;
if (SelectedProfile == null || _deviceManager.ActiveKeyboard == null) if (SelectedProfile == null || _deviceManager.ActiveKeyboard == null)
{ {
@ -112,10 +111,8 @@ namespace Artemis.ViewModels.Profiles
// Draw the layers // Draw the layers
var drawLayers = SelectedProfile.Layers var drawLayers = SelectedProfile.Layers
.OrderByDescending(l => l.Order) .OrderByDescending(l => l.Order)
.Where(l => l.Enabled && .Where(l => l.MustDraw() || (l.Enabled && l.LayerType == LayerType.Folder))
(l.LayerType == LayerType.Keyboard || .ToList();
l.LayerType == LayerType.KeyboardGif ||
l.LayerType == LayerType.Folder));
foreach (var layer in drawLayers) foreach (var layer in drawLayers)
layer.Draw<object>(null, drawingContext, true, false); layer.Draw<object>(null, drawingContext, true, false);
@ -124,12 +121,12 @@ namespace Artemis.ViewModels.Profiles
if (accentColor == null) if (accentColor == null)
return; return;
var pen = new Pen(new SolidColorBrush((Color)accentColor), 0.4); var pen = new Pen(new SolidColorBrush((Color) accentColor), 0.4);
// Draw the selection outline and resize indicator // Draw the selection outline and resize indicator
if (SelectedLayer != null && SelectedLayer.MustDraw()) if (SelectedLayer != null && SelectedLayer.MustDraw())
{ {
var layerRect = ((KeyboardPropertiesModel)SelectedLayer.Properties).GetRect(); var layerRect = ((KeyboardPropertiesModel) SelectedLayer.Properties).GetRect();
// Deflate the rect so that the border is drawn on the inside // Deflate the rect so that the border is drawn on the inside
layerRect.Inflate(-0.2, -0.2); layerRect.Inflate(-0.2, -0.2);

View File

@ -14,7 +14,7 @@ namespace Artemis.ViewModels.Profiles.Properties
: base(gameDataModel) : base(gameDataModel)
{ {
ProposedProperties = GeneralHelpers.Clone(properties); ProposedProperties = GeneralHelpers.Clone(properties);
Brush = GeneralHelpers.CloneAlt(ProposedProperties.Brush); Brush = ProposedProperties.Brush.CloneCurrentValue();
} }
public Brush Brush public Brush Brush

View File

@ -9,16 +9,16 @@ namespace Artemis.ViewModels.Profiles.Properties
{ {
public class KeyboardPropertiesViewModel : LayerPropertiesViewModel public class KeyboardPropertiesViewModel : LayerPropertiesViewModel
{ {
private Brush _brush;
private bool _isGif; private bool _isGif;
private KeyboardPropertiesModel _proposedProperties; private KeyboardPropertiesModel _proposedProperties;
private Brush _brush;
public KeyboardPropertiesViewModel(IGameDataModel gameDataModel, LayerPropertiesModel properties) public KeyboardPropertiesViewModel(IGameDataModel gameDataModel, LayerPropertiesModel properties)
: base(gameDataModel) : base(gameDataModel)
{ {
var keyboardProperties = (KeyboardPropertiesModel) properties; var keyboardProperties = (KeyboardPropertiesModel) properties;
ProposedProperties = GeneralHelpers.Clone(keyboardProperties); ProposedProperties = GeneralHelpers.Clone(keyboardProperties);
Brush = GeneralHelpers.CloneAlt(ProposedProperties.Brush); Brush = ProposedProperties.Brush.CloneCurrentValue();
DataModelProps = new BindableCollection<GeneralHelpers.PropertyCollection>(); DataModelProps = new BindableCollection<GeneralHelpers.PropertyCollection>();
DataModelProps.AddRange(GeneralHelpers.GenerateTypeMap(gameDataModel)); DataModelProps.AddRange(GeneralHelpers.GenerateTypeMap(gameDataModel));
@ -51,6 +51,17 @@ namespace Artemis.ViewModels.Profiles.Properties
} }
} }
public Brush Brush
{
get { return _brush; }
set
{
if (Equals(value, _brush)) return;
_brush = value;
NotifyOfPropertyChange(() => Brush);
}
}
public bool ShowGif => IsGif; public bool ShowGif => IsGif;
public bool ShowBrush => !IsGif; public bool ShowBrush => !IsGif;
@ -65,7 +76,7 @@ namespace Artemis.ViewModels.Profiles.Properties
public void BrowseGif() public void BrowseGif()
{ {
var dialog = new OpenFileDialog { Filter = "Animated image file (*.gif)|*.gif" }; var dialog = new OpenFileDialog {Filter = "Animated image file (*.gif)|*.gif"};
var result = dialog.ShowDialog(); var result = dialog.ShowDialog();
if (result != DialogResult.OK) if (result != DialogResult.OK)
return; return;
@ -76,7 +87,6 @@ namespace Artemis.ViewModels.Profiles.Properties
public override LayerPropertiesModel GetAppliedProperties() public override LayerPropertiesModel GetAppliedProperties()
{ {
HeightProperties.Apply(ProposedProperties); HeightProperties.Apply(ProposedProperties);
WidthProperties.Apply(ProposedProperties); WidthProperties.Apply(ProposedProperties);
OpacityProperties.Apply(ProposedProperties); OpacityProperties.Apply(ProposedProperties);
@ -85,16 +95,5 @@ namespace Artemis.ViewModels.Profiles.Properties
properties.Brush = Brush; properties.Brush = Brush;
return properties; return properties;
} }
public Brush Brush
{
get { return _brush; }
set
{
if (Equals(value, _brush)) return;
_brush = value;
NotifyOfPropertyChange(() => Brush);
}
}
} }
} }

View File

@ -15,7 +15,7 @@ namespace Artemis.ViewModels.Profiles.Properties
: base(gameDataModel) : base(gameDataModel)
{ {
ProposedProperties = GeneralHelpers.Clone(properties); ProposedProperties = GeneralHelpers.Clone(properties);
Brush = GeneralHelpers.CloneAlt(ProposedProperties.Brush); Brush = ProposedProperties.Brush.CloneCurrentValue();
} }
public Brush Brush public Brush Brush