1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2026-03-24 02:08:47 +00:00

Fixed Truck Simulator directory selection

Made render scale configurable per type and set non-keyboard types to 1 instead of 4
Fixed overlay enable/disable
Added changed/increased/decreased to layer event triggers
Fixed layer condition changes in UI always applying
This commit is contained in:
SpoinkyNL 2017-01-23 14:45:50 +01:00
parent eab261cd46
commit 03264fcee7
33 changed files with 497 additions and 393 deletions

View File

@ -105,16 +105,12 @@ namespace Artemis.Managers
/// <summary> /// <summary>
/// Loads the last active effect and starts the program /// Loads the last active effect and starts the program
/// </summary> /// </summary>
public void EnableProgram() public async void EnableProgram()
{ {
Logger.Debug("Enabling program"); Logger.Debug("Enabling program");
ProgramEnabled = true; ProgramEnabled = true;
LoopManager.StartAsync(); await LoopManager.StartAsync();
foreach (var overlayModule in ModuleManager.OverlayModules)
{
if (overlayModule.Settings.IsEnabled)
overlayModule.Enable();
}
RaiseEnabledChangedEvent(new EnabledChangedEventArgs(ProgramEnabled)); RaiseEnabledChangedEvent(new EnabledChangedEventArgs(ProgramEnabled));
} }

View File

@ -68,7 +68,7 @@ namespace Artemis.Modules.Abstract
{ {
get get
{ {
if (ModuleModel.IsBoundToProcess || ModuleModel.IsBoundToProcess) if (ModuleModel.IsBoundToProcess || ModuleModel.IsOverlay)
return Settings.IsEnabled; return Settings.IsEnabled;
return _generalSettings.LastModule == ModuleModel.Name; return _generalSettings.LastModule == ModuleModel.Name;
} }

View File

@ -59,7 +59,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2
Settings.Save(); Settings.Save();
if (!File.Exists(dir + "/plugins/ets2-telemetry-server.dll")) if (!File.Exists(dir + "/plugins/ets2-telemetry-server.dll"))
PlacePlugins(); PlaceTruckSimulatorPlugin(dir, "eurotrucks2.exe");
} }
public void FindAtsGameDir() public void FindAtsGameDir()
@ -76,22 +76,14 @@ namespace Artemis.Modules.Games.EurotruckSimulator2
Settings.Save(); Settings.Save();
if (!File.Exists(dir + "/plugins/ets2-telemetry-server.dll")) if (!File.Exists(dir + "/plugins/ets2-telemetry-server.dll"))
PlacePlugins(); PlaceTruckSimulatorPlugin(dir, "amtrucks.exe");
} }
public void PlacePlugins() public void PlaceTruckSimulatorPlugin(string path, string game)
{ {
var ets2Path = ((EurotruckSimulator2Settings) Settings).Ets2GameDirectory; if (string.IsNullOrEmpty(path))
if (!string.IsNullOrEmpty(ets2Path)) return;
PlaceTruckSimulatorPlugin(ets2Path, "eurotrucks2.exe");
var atsPath = ((EurotruckSimulator2Settings) Settings).AtsGameDirectory;
if (!string.IsNullOrEmpty(atsPath))
PlaceTruckSimulatorPlugin(atsPath, "amtrucks.exe");
}
private void PlaceTruckSimulatorPlugin(string path, string game)
{
// Ensure the selected directory exists // Ensure the selected directory exists
if (!Directory.Exists(path)) if (!Directory.Exists(path))
{ {

View File

@ -68,7 +68,7 @@
<Grid> <Grid>
<TextBox x:Name="Ets2GameDirectory" Height="23" TextWrapping="Wrap" Margin="5,0,30,0" <TextBox x:Name="Ets2GameDirectory" Height="23" TextWrapping="Wrap" Margin="5,0,30,0"
Text="{Binding Path=Settings.Ets2GameDirectory, Mode=TwoWay}" Text="{Binding Path=Settings.Ets2GameDirectory, Mode=TwoWay}"
cal:Message.Attach="[Event LostFocus] = [Action PlacePlugins]" /> cal:Message.Attach="[Event LostFocus] = [Action Ets2PlacePlugin]" />
<Button x:Name="Ets2BrowseDirectory" Content="..." RenderTransformOrigin="-0.039,-0.944" <Button x:Name="Ets2BrowseDirectory" Content="..." RenderTransformOrigin="-0.039,-0.944"
HorizontalAlignment="Right" Width="25" HorizontalAlignment="Right" Width="25"
Style="{DynamicResource SquareButtonStyle}" Height="26" /> Style="{DynamicResource SquareButtonStyle}" Height="26" />
@ -80,7 +80,7 @@
<Grid> <Grid>
<TextBox x:Name="AtsGameDirectory" Height="23" TextWrapping="Wrap" Margin="5,0,30,0" <TextBox x:Name="AtsGameDirectory" Height="23" TextWrapping="Wrap" Margin="5,0,30,0"
Text="{Binding Path=Settings.AtsGameDirectory, Mode=TwoWay}" Text="{Binding Path=Settings.AtsGameDirectory, Mode=TwoWay}"
cal:Message.Attach="[Event LostFocus] = [Action PlacePlugins]" /> cal:Message.Attach="[Event LostFocus] = [Action AtsPlacePlugin]" />
<Button x:Name="AtsBrowseDirectory" Content="..." RenderTransformOrigin="-0.039,-0.944" <Button x:Name="AtsBrowseDirectory" Content="..." RenderTransformOrigin="-0.039,-0.944"
HorizontalAlignment="Right" Width="25" HorizontalAlignment="Right" Width="25"
Style="{DynamicResource SquareButtonStyle}" Height="26" /> Style="{DynamicResource SquareButtonStyle}" Height="26" />

View File

@ -1,5 +1,4 @@
using System.IO; using System.Windows.Forms;
using System.Windows.Forms;
using Artemis.Managers; using Artemis.Managers;
using Artemis.Modules.Abstract; using Artemis.Modules.Abstract;
using Ninject; using Ninject;
@ -17,39 +16,48 @@ namespace Artemis.Modules.Games.EurotruckSimulator2
public override bool UsesProfileEditor => true; public override bool UsesProfileEditor => true;
public void PlacePlugins()
{
((EurotruckSimulator2Model) ModuleModel).PlacePlugins();
}
public void Ets2BrowseDirectory() public void Ets2BrowseDirectory()
{ {
var settings = (EurotruckSimulator2Settings) Settings; var settings = (EurotruckSimulator2Settings) Settings;
var model = (EurotruckSimulator2Model) ModuleModel;
var dialog = new FolderBrowserDialog {SelectedPath = settings.Ets2GameDirectory}; var dialog = new FolderBrowserDialog {SelectedPath = settings.Ets2GameDirectory};
var result = dialog.ShowDialog(); var result = dialog.ShowDialog();
if (result != DialogResult.OK) if (result != DialogResult.OK)
return; return;
settings.Ets2GameDirectory = Path.GetDirectoryName(dialog.SelectedPath); settings.Ets2GameDirectory = dialog.SelectedPath;
NotifyOfPropertyChange(() => Settings); NotifyOfPropertyChange(() => Settings);
Settings.Save(); Settings.Save();
model.PlaceTruckSimulatorPlugin(settings.Ets2GameDirectory, "eurotrucks2.exe");
((EurotruckSimulator2Model) ModuleModel).PlacePlugins();
} }
public void AtsBrowseDirectory() public void AtsBrowseDirectory()
{ {
var settings = (EurotruckSimulator2Settings) Settings; var settings = (EurotruckSimulator2Settings) Settings;
var model = (EurotruckSimulator2Model)ModuleModel;
var dialog = new FolderBrowserDialog {SelectedPath = settings.AtsGameDirectory}; var dialog = new FolderBrowserDialog {SelectedPath = settings.AtsGameDirectory};
var result = dialog.ShowDialog(); var result = dialog.ShowDialog();
if (result != DialogResult.OK) if (result != DialogResult.OK)
return; return;
settings.AtsGameDirectory = Path.GetDirectoryName(dialog.SelectedPath); settings.AtsGameDirectory = dialog.SelectedPath;
NotifyOfPropertyChange(() => Settings); NotifyOfPropertyChange(() => Settings);
Settings.Save(); Settings.Save();
model.PlaceTruckSimulatorPlugin(settings.Ets2GameDirectory, "amtrucks.exe");
}
public void Ets2PlacePlugin()
{
var ets2Path = ((EurotruckSimulator2Settings)Settings).Ets2GameDirectory;
((EurotruckSimulator2Model)ModuleModel).PlaceTruckSimulatorPlugin(ets2Path, "eurotrucks2.exe");
}
((EurotruckSimulator2Model) ModuleModel).PlacePlugins(); public void AtsPlacePlugin()
{
var atsPath = ((EurotruckSimulator2Settings)Settings).AtsGameDirectory;
((EurotruckSimulator2Model)ModuleModel).PlaceTruckSimulatorPlugin(atsPath, "amtrucks.exe");
} }
} }
} }

View File

@ -1,5 +1,6 @@
using Artemis.Modules.Abstract; using Artemis.Modules.Abstract;
using Artemis.Modules.General.GeneralProfile; using Artemis.Modules.General.GeneralProfile;
using MoonSharp.Interpreter;
namespace Artemis.Modules.Overlays.OverlayProfile namespace Artemis.Modules.Overlays.OverlayProfile
{ {
@ -7,9 +8,17 @@ namespace Artemis.Modules.Overlays.OverlayProfile
{ {
public OverlayProfileDataModel() public OverlayProfileDataModel()
{ {
GeneralDataModel = new GeneralProfileDataModel(); Keyboard = new KbDataModel();
Audio = new Audio();
} }
public GeneralProfileDataModel GeneralDataModel { get; set; } public KbDataModel Keyboard { get; set; }
public Audio Audio { get; set; }
}
[MoonSharpUserData]
public class Audio
{
public float Volume { get; set; }
} }
} }

View File

@ -1,34 +1,62 @@
using Artemis.DAL; using Artemis.DAL;
using Artemis.Events;
using Artemis.Managers; using Artemis.Managers;
using Artemis.Modules.Abstract; using Artemis.Modules.Abstract;
using Artemis.Modules.General.GeneralProfile; using Artemis.Modules.General.GeneralProfile;
using Ninject; using CSCore.CoreAudioAPI;
namespace Artemis.Modules.Overlays.OverlayProfile namespace Artemis.Modules.Overlays.OverlayProfile
{ {
public class OverlayProfileModel : ModuleModel public class OverlayProfileModel : ModuleModel
{ {
private readonly GeneralProfileModel _generalProfileModule; private AudioEndpointVolume _endPointVolume;
public OverlayProfileModel(DeviceManager deviceManager, LuaManager luaManager, public OverlayProfileModel(DeviceManager deviceManager, LuaManager luaManager,
[Named(nameof(GeneralProfileModel))] ModuleModel generalProfileModule) : base(deviceManager, luaManager) AudioCaptureManager audioCaptureManager) : base(deviceManager, luaManager)
{ {
_generalProfileModule = (GeneralProfileModel) generalProfileModule;
Settings = SettingsProvider.Load<OverlayProfileSettings>(); Settings = SettingsProvider.Load<OverlayProfileSettings>();
DataModel = new OverlayProfileDataModel(); DataModel = new OverlayProfileDataModel();
var defaultPlayback = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
_endPointVolume = AudioEndpointVolume.FromDevice(defaultPlayback);
audioCaptureManager.AudioDeviceChanged += OnAudioDeviceChanged;
Enable();
} }
public override string Name => "OverlayProfile"; public override string Name => "OverlayProfile";
public override bool IsOverlay => true; public override bool IsOverlay => true;
public override bool IsBoundToProcess => false; public override bool IsBoundToProcess => false;
private void OnAudioDeviceChanged(object sender, AudioDeviceChangedEventArgs e)
{
_endPointVolume = AudioEndpointVolume.FromDevice(e.DefaultPlayback);
}
public override void Update() public override void Update()
{ {
if (!Settings.IsEnabled)
return;
var dataModel = (OverlayProfileDataModel) DataModel; var dataModel = (OverlayProfileDataModel) DataModel;
if (!_generalProfileModule.IsInitialized) dataModel.Keyboard.NumLock = ((ushort) GeneralProfileModel.GetKeyState(0x90) & 0xffff) != 0;
_generalProfileModule.Update(); dataModel.Keyboard.CapsLock = ((ushort) GeneralProfileModel.GetKeyState(0x14) & 0xffff) != 0;
dataModel.GeneralDataModel = (GeneralProfileDataModel) _generalProfileModule.DataModel; dataModel.Keyboard.ScrollLock = ((ushort) GeneralProfileModel.GetKeyState(0x91) & 0xffff) != 0;
if (_endPointVolume != null)
dataModel.Audio.Volume = _endPointVolume.GetMasterVolumeLevelScalar();
}
public override void Render(RenderFrame frame, bool keyboardOnly)
{
if (Settings.IsEnabled)
base.Render(frame, keyboardOnly);
}
public override void Dispose()
{
PreviewLayers = null;
} }
} }
} }

View File

@ -27,17 +27,17 @@ namespace Artemis.Profiles.Layers.Animations
layerModel.AnimationProgress = progress; layerModel.AnimationProgress = progress;
} }
public void Draw(LayerModel layerModel, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c, int drawScale)
{ {
if (layerModel.Brush == null) if (layerModel.Brush == null)
return; return;
// Set up variables for this frame // Set up variables for this frame
var rect = layerModel.Properties.Contain var rect = layerModel.Properties.Contain
? layerModel.LayerRect() ? layerModel.LayerRect(drawScale)
: layerModel.Properties.PropertiesRect(); : layerModel.Properties.PropertiesRect(drawScale);
var clip = layerModel.LayerRect(); var clip = layerModel.LayerRect(drawScale);
// 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 - layerModel.AnimationProgress)*10.0; var progress = (6.0 - layerModel.AnimationProgress)*10.0;

View File

@ -12,7 +12,7 @@ namespace Artemis.Profiles.Layers.Animations
{ {
} }
public void Draw(LayerModel layerModel, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c, int drawScale)
{ {
} }

View File

@ -27,17 +27,17 @@ namespace Artemis.Profiles.Layers.Animations
layerModel.AnimationProgress = progress; layerModel.AnimationProgress = progress;
} }
public void Draw(LayerModel layerModel, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c, int drawScale)
{ {
if (layerModel.Brush == null) if (layerModel.Brush == null)
return; return;
// Set up variables for this frame // Set up variables for this frame
var rect = layerModel.Properties.Contain var rect = layerModel.Properties.Contain
? layerModel.LayerRect() ? layerModel.LayerRect(drawScale)
: layerModel.Properties.PropertiesRect(); : layerModel.Properties.PropertiesRect(drawScale);
var clip = layerModel.LayerRect(); var clip = layerModel.LayerRect(drawScale);
// Can't meddle with the original brush because it's frozen. // Can't meddle with the original brush because it's frozen.
var brush = layerModel.Brush.Clone(); var brush = layerModel.Brush.Clone();

View File

@ -14,29 +14,29 @@ namespace Artemis.Profiles.Layers.Animations
var progress = layerModel.AnimationProgress; var progress = layerModel.AnimationProgress;
if (MustExpire(layerModel)) if (MustExpire(layerModel))
progress = 0; progress = 0;
progress = progress + layerModel.Properties.AnimationSpeed*2; progress = progress + layerModel.Properties.AnimationSpeed * 2 / 4 * layerModel.LayerType.DrawScale;
// 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)
layerModel.AnimationProgress = progress; layerModel.AnimationProgress = progress;
} }
public void Draw(LayerModel layerModel, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c, int drawScale)
{ {
if (layerModel.Brush == null) if (layerModel.Brush == null)
return; return;
// Set up variables for this frame // Set up variables for this frame
var rect = layerModel.Properties.Contain var rect = layerModel.Properties.Contain
? layerModel.LayerRect() ? layerModel.LayerRect(drawScale)
: layerModel.Properties.PropertiesRect(); : layerModel.Properties.PropertiesRect(drawScale);
var s1 = new Rect(new Point(rect.X, rect.Y + layerModel.AnimationProgress), var s1 = new Rect(new Point(rect.X, rect.Y + layerModel.AnimationProgress),
new Size(rect.Width, rect.Height)); new Size(rect.Width, rect.Height));
var s2 = new Rect(new Point(s1.X, s1.Y - rect.Height), var s2 = new Rect(new Point(s1.X, s1.Y - rect.Height),
new Size(rect.Width, rect.Height + .5)); new Size(rect.Width, rect.Height + .5));
var clip = layerModel.LayerRect(); var clip = layerModel.LayerRect(drawScale);
c.PushClip(new RectangleGeometry(clip)); c.PushClip(new RectangleGeometry(clip));
c.DrawRectangle(layerModel.Brush, null, s1); c.DrawRectangle(layerModel.Brush, null, s1);
@ -46,7 +46,8 @@ namespace Artemis.Profiles.Layers.Animations
public bool MustExpire(LayerModel layer) public bool MustExpire(LayerModel layer)
{ {
return layer.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Height*4; return layer.AnimationProgress + layer.Properties.AnimationSpeed * 2 >=
layer.Properties.Height * layer.LayerType.DrawScale;
} }
} }
} }

View File

@ -14,29 +14,29 @@ namespace Artemis.Profiles.Layers.Animations
var progress = layerModel.AnimationProgress; var progress = layerModel.AnimationProgress;
if (MustExpire(layerModel)) if (MustExpire(layerModel))
progress = 0; progress = 0;
progress = progress + layerModel.Properties.AnimationSpeed*2; progress = progress + layerModel.Properties.AnimationSpeed * 2 / 4 * layerModel.LayerType.DrawScale;
// 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)
layerModel.AnimationProgress = progress; layerModel.AnimationProgress = progress;
} }
public void Draw(LayerModel layerModel, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c, int drawScale)
{ {
if (layerModel.Brush == null) if (layerModel.Brush == null)
return; return;
// Set up variables for this frame // Set up variables for this frame
var rect = layerModel.Properties.Contain var rect = layerModel.Properties.Contain
? layerModel.LayerRect() ? layerModel.LayerRect(drawScale)
: layerModel.Properties.PropertiesRect(); : layerModel.Properties.PropertiesRect(drawScale);
var s1 = new Rect(new Point(rect.X - layerModel.AnimationProgress, rect.Y), var s1 = new Rect(new Point(rect.X - layerModel.AnimationProgress, rect.Y),
new Size(rect.Width + .5, rect.Height)); new Size(rect.Width + .5, rect.Height));
var s2 = new Rect(new Point(s1.X + rect.Width, rect.Y), var s2 = new Rect(new Point(s1.X + rect.Width, rect.Y),
new Size(rect.Width, rect.Height)); new Size(rect.Width, rect.Height));
var clip = layerModel.LayerRect(); var clip = layerModel.LayerRect(drawScale);
c.PushClip(new RectangleGeometry(clip)); c.PushClip(new RectangleGeometry(clip));
c.DrawRectangle(layerModel.Brush, null, s1); c.DrawRectangle(layerModel.Brush, null, s1);
@ -46,7 +46,8 @@ namespace Artemis.Profiles.Layers.Animations
public bool MustExpire(LayerModel layer) public bool MustExpire(LayerModel layer)
{ {
return layer.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Width*4; return layer.AnimationProgress + layer.Properties.AnimationSpeed * 2 >=
layer.Properties.Width * layer.LayerType.DrawScale;
} }
} }
} }

View File

@ -14,29 +14,29 @@ namespace Artemis.Profiles.Layers.Animations
var progress = layerModel.AnimationProgress; var progress = layerModel.AnimationProgress;
if (MustExpire(layerModel)) if (MustExpire(layerModel))
progress = 0; progress = 0;
progress = progress + layerModel.Properties.AnimationSpeed*2; progress = progress + layerModel.Properties.AnimationSpeed * 2 / 4 * layerModel.LayerType.DrawScale;
// 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)
layerModel.AnimationProgress = progress; layerModel.AnimationProgress = progress;
} }
public void Draw(LayerModel layerModel, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c, int drawScale)
{ {
if (layerModel.Brush == null) if (layerModel.Brush == null)
return; return;
// Set up variables for this frame // Set up variables for this frame
var rect = layerModel.Properties.Contain var rect = layerModel.Properties.Contain
? layerModel.LayerRect() ? layerModel.LayerRect(drawScale)
: layerModel.Properties.PropertiesRect(); : layerModel.Properties.PropertiesRect(drawScale);
var s1 = new Rect(new Point(rect.X + layerModel.AnimationProgress, rect.Y), var s1 = new Rect(new Point(rect.X + layerModel.AnimationProgress, rect.Y),
new Size(rect.Width, rect.Height)); new Size(rect.Width, rect.Height));
var s2 = new Rect(new Point(s1.X - rect.Width, rect.Y), var s2 = new Rect(new Point(s1.X - rect.Width, rect.Y),
new Size(rect.Width + .5, rect.Height)); new Size(rect.Width + .5, rect.Height));
var clip = layerModel.LayerRect(); var clip = layerModel.LayerRect(drawScale);
c.PushClip(new RectangleGeometry(clip)); c.PushClip(new RectangleGeometry(clip));
c.DrawRectangle(layerModel.Brush, null, s1); c.DrawRectangle(layerModel.Brush, null, s1);
@ -46,7 +46,8 @@ namespace Artemis.Profiles.Layers.Animations
public bool MustExpire(LayerModel layer) public bool MustExpire(LayerModel layer)
{ {
return layer.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Width*4; return layer.AnimationProgress + layer.Properties.AnimationSpeed * 2 >=
layer.Properties.Width * layer.LayerType.DrawScale;
} }
} }
} }

View File

@ -14,28 +14,28 @@ namespace Artemis.Profiles.Layers.Animations
var progress = layerModel.AnimationProgress; var progress = layerModel.AnimationProgress;
if (MustExpire(layerModel)) if (MustExpire(layerModel))
progress = 0; progress = 0;
progress = progress + layerModel.Properties.AnimationSpeed*2; progress = progress + layerModel.Properties.AnimationSpeed * 2 / 4 * layerModel.LayerType.DrawScale;
// 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)
layerModel.AnimationProgress = progress; layerModel.AnimationProgress = progress;
} }
public void Draw(LayerModel layerModel, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c, int drawScale)
{ {
if (layerModel.Brush == null) if (layerModel.Brush == null)
return; return;
// Set up variables for this frame // Set up variables for this frame
var rect = layerModel.Properties.Contain var rect = layerModel.Properties.Contain
? layerModel.LayerRect() ? layerModel.LayerRect(drawScale)
: layerModel.Properties.PropertiesRect(); : layerModel.Properties.PropertiesRect(drawScale);
var s1 = new Rect(new Point(rect.X, rect.Y - layerModel.AnimationProgress), var s1 = new Rect(new Point(rect.X, rect.Y - layerModel.AnimationProgress),
new Size(rect.Width, rect.Height + .5)); new Size(rect.Width, rect.Height + .5));
var s2 = new Rect(new Point(s1.X, s1.Y + rect.Height), new Size(rect.Width, rect.Height)); var s2 = new Rect(new Point(s1.X, s1.Y + rect.Height), new Size(rect.Width, rect.Height));
var clip = layerModel.LayerRect(); var clip = layerModel.LayerRect(drawScale);
c.PushClip(new RectangleGeometry(clip)); c.PushClip(new RectangleGeometry(clip));
c.DrawRectangle(layerModel.Brush, null, s1); c.DrawRectangle(layerModel.Brush, null, s1);
@ -45,7 +45,8 @@ namespace Artemis.Profiles.Layers.Animations
public bool MustExpire(LayerModel layer) public bool MustExpire(LayerModel layer)
{ {
return layer.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Height*4; return layer.AnimationProgress + layer.Properties.AnimationSpeed * 2 >=
layer.Properties.Height * layer.LayerType.DrawScale;
} }
} }
} }

View File

@ -10,7 +10,7 @@ namespace Artemis.Profiles.Layers.Interfaces
string Name { get; } string Name { get; }
void Update(LayerModel layerModel, bool updateAnimations); void Update(LayerModel layerModel, bool updateAnimations);
void Draw(LayerModel layerModel, DrawingContext c); void Draw(LayerModel layerModel, DrawingContext c, int drawScale);
bool MustExpire(LayerModel layerModel); bool MustExpire(LayerModel layerModel);
} }
} }

View File

@ -3,7 +3,6 @@ using Artemis.Modules.Abstract;
using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Abstract;
using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Layers.Models;
using Artemis.ViewModels; using Artemis.ViewModels;
using Artemis.ViewModels.Profiles;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Artemis.Profiles.Layers.Interfaces namespace Artemis.Profiles.Layers.Interfaces
@ -29,6 +28,12 @@ namespace Artemis.Profiles.Layers.Interfaces
[JsonIgnore] [JsonIgnore]
DrawType DrawType { get; } DrawType DrawType { get; }
/// <summary>
/// Gets the scale on which the layer should be drawn
/// </summary>
[JsonIgnore]
int DrawScale { get; }
/// <summary> /// <summary>
/// The the thumbnail for this layer type /// The the thumbnail for this layer type
/// </summary> /// </summary>

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Globalization;
using Artemis.Modules.Abstract; using Artemis.Modules.Abstract;
using Artemis.Utilities; using Artemis.Utilities;
using DynamicExpresso; using DynamicExpresso;
@ -8,6 +9,7 @@ namespace Artemis.Profiles.Layers.Models
public class LayerConditionModel public class LayerConditionModel
{ {
private readonly Interpreter _interpreter; private readonly Interpreter _interpreter;
private object _lastValue;
public LayerConditionModel() public LayerConditionModel()
{ {
@ -23,39 +25,92 @@ namespace Artemis.Profiles.Layers.Models
{ {
lock (subject) lock (subject)
{ {
if (string.IsNullOrEmpty(Field) || string.IsNullOrEmpty(Value) || string.IsNullOrEmpty(Type)) if (string.IsNullOrEmpty(Field) || string.IsNullOrEmpty(Type))
return false; return false;
var inspect = GeneralHelpers.GetPropertyValue(subject, Field); var inspect = GeneralHelpers.GetPropertyValue(subject, Field);
if (inspect == null) if (inspect == null)
{
_lastValue = null;
return false; return false;
// Put the subject in a list, allowing Dynamic Linq to be used.
if (Type == "String")
{
return _interpreter.Eval<bool>($"subject.{Field}.ToLower(){Operator}(value)",
new Parameter("subject", subject.GetType(), subject),
new Parameter("value", Value.ToLower()));
} }
Parameter rightParam = null; bool returnValue;
switch (Type) if (Operator == "changed" || Operator == "decreased" || Operator == "increased")
{ returnValue = EvaluateEventOperator(subject, inspect);
case "Enum": else
var enumType = GeneralHelpers.GetPropertyValue(subject, Field).GetType(); returnValue = EvaluateOperator(subject);
rightParam = new Parameter("value", Enum.Parse(enumType, Value));
break;
case "Boolean":
rightParam = new Parameter("value", bool.Parse(Value));
break;
case "Int32":
rightParam = new Parameter("value", int.Parse(Value));
break;
}
return _interpreter.Eval<bool>($"subject.{Field} {Operator} value", _lastValue = inspect;
new Parameter("subject", subject.GetType(), subject), rightParam); return returnValue;
} }
} }
private bool EvaluateEventOperator(ModuleDataModel subject, object inspect)
{
// DynamicExpresso doesn't want a null so when it was previously null (should only happen first iteration)
// return false since that would be the only possible outcome
if (_lastValue == null)
return false;
// Assign the right parameter
var rightParam = new Parameter("value", _lastValue);
// Come up with the proper operator
var changeOperator = "";
if (Operator == "changed")
changeOperator = "!=";
else if (Operator == "decreased")
changeOperator = "<";
else if (Operator == "increased")
changeOperator = ">";
// Evaluate the result and store it
var returnValue = _interpreter.Eval<bool>($"subject.{Field} {changeOperator} value",
new Parameter("subject", subject.GetType(), subject), rightParam);
// Set the last value to the new value
_lastValue = inspect;
// Return the evaluated result
return returnValue;
}
private bool EvaluateOperator(ModuleDataModel subject)
{
// Since _lastValue won't be used, rely on Value to not be null
if (string.IsNullOrEmpty(Value))
return false;
// Put the subject in a list, allowing Dynamic Linq to be used.
if (Type == "String")
{
return _interpreter.Eval<bool>($"subject.{Field}.ToLower(){Operator}(value)",
new Parameter("subject", subject.GetType(), subject),
new Parameter("value", Value.ToLower()));
}
Parameter rightParam = null;
switch (Type)
{
case "Enum":
var enumType = GeneralHelpers.GetPropertyValue(subject, Field).GetType();
rightParam = new Parameter("value", Enum.Parse(enumType, Value));
break;
case "Boolean":
rightParam = new Parameter("value", bool.Parse(Value));
break;
case "Int32":
rightParam = new Parameter("value", int.Parse(Value));
break;
case "Single":
// Parse commas as decimals
rightParam = new Parameter("value", float.Parse(Value.Replace(",", "."),
CultureInfo.InvariantCulture));
break;
}
return _interpreter.Eval<bool>($"subject.{Field} {Operator} value",
new Parameter("subject", subject.GetType(), subject), rightParam);
}
} }
} }

View File

@ -14,7 +14,6 @@ using Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing;
using Artemis.Properties; using Artemis.Properties;
using Artemis.Utilities; using Artemis.Utilities;
using Artemis.ViewModels; using Artemis.ViewModels;
using Artemis.ViewModels.Profiles;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Artemis.Profiles.Layers.Types.AmbientLight namespace Artemis.Profiles.Layers.Types.AmbientLight
@ -26,6 +25,7 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight
public string Name => "Keyboard - Ambient Light"; public string Name => "Keyboard - Ambient Light";
public bool ShowInEdtor => true; public bool ShowInEdtor => true;
public DrawType DrawType => DrawType.Keyboard; public DrawType DrawType => DrawType.Keyboard;
public int DrawScale => 4;
[JsonIgnore] private AmbienceCreatorType? _lastAmbienceCreatorType; [JsonIgnore] private AmbienceCreatorType? _lastAmbienceCreatorType;
@ -77,11 +77,7 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight
public void Draw(LayerModel layerModel, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
var rect = new Rect(layerModel.Properties.X*4, var rect = layerModel.LayerRect(DrawScale);
layerModel.Properties.Y*4,
layerModel.Properties.Width*4,
layerModel.Properties.Height*4);
c.DrawRectangle(((AmbientLightPropertiesModel) layerModel.Properties).AmbientLightBrush, null, rect); c.DrawRectangle(((AmbientLightPropertiesModel) layerModel.Properties).AmbientLightBrush, null, rect);
} }

View File

@ -23,12 +23,10 @@ namespace Artemis.Profiles.Layers.Types.Audio
public class AudioType : ILayerType public class AudioType : ILayerType
{ {
private readonly AudioCaptureManager _audioCaptureManager; private readonly AudioCaptureManager _audioCaptureManager;
private const GeometryCombineMode CombineMode = GeometryCombineMode.Union;
private AudioCapture _audioCapture; private AudioCapture _audioCapture;
private int _lines; private int _lines;
private LineSpectrum _lineSpectrum; private LineSpectrum _lineSpectrum;
private List<double> _lineValues; private List<double> _lineValues;
private int _drawCount;
public AudioType(AudioCaptureManager audioCaptureManager) public AudioType(AudioCaptureManager audioCaptureManager)
{ {
@ -50,6 +48,7 @@ namespace Artemis.Profiles.Layers.Types.Audio
public string Name => "Keyboard - Audio visualization"; public string Name => "Keyboard - Audio visualization";
public bool ShowInEdtor => true; public bool ShowInEdtor => true;
public DrawType DrawType => DrawType.Keyboard; public DrawType DrawType => DrawType.Keyboard;
public int DrawScale => 4;
public ImageSource DrawThumbnail(LayerModel layer) public ImageSource DrawThumbnail(LayerModel layer)
{ {
@ -66,7 +65,6 @@ namespace Artemis.Profiles.Layers.Types.Audio
public void Draw(LayerModel layerModel, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
_drawCount++;
if (_lineValues == null) if (_lineValues == null)
return; return;
@ -178,7 +176,7 @@ namespace Artemis.Profiles.Layers.Types.Audio
// If an animation is present, let it handle the drawing // If an animation is present, let it handle the drawing
if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation)) if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{ {
layerModel.LayerAnimation.Draw(layerModel, c); layerModel.LayerAnimation.Draw(layerModel, c, DrawScale);
return; return;
} }
@ -188,7 +186,7 @@ namespace Artemis.Profiles.Layers.Types.Audio
: new Rect(layerModel.Properties.X*4, layerModel.Properties.Y*4, : new Rect(layerModel.Properties.X*4, layerModel.Properties.Y*4,
layerModel.Properties.Width*4, layerModel.Properties.Height*4); layerModel.Properties.Width*4, layerModel.Properties.Height*4);
var clip = layerModel.LayerRect(); var clip = layerModel.LayerRect(DrawScale);
// Can't meddle with the original brush because it's frozen. // Can't meddle with the original brush because it's frozen.
var brush = layerModel.Brush.Clone(); var brush = layerModel.Brush.Clone();

View File

@ -22,6 +22,7 @@ namespace Artemis.Profiles.Layers.Types.ConicalBrush
public string Name => "Conical Brush"; public string Name => "Conical Brush";
public bool ShowInEdtor => true; public bool ShowInEdtor => true;
public DrawType DrawType => DrawType.Keyboard; public DrawType DrawType => DrawType.Keyboard;
public int DrawScale => 4;
#endregion #endregion
@ -62,15 +63,15 @@ namespace Artemis.Profiles.Layers.Types.ConicalBrush
// If an animation is present, let it handle the drawing // If an animation is present, let it handle the drawing
if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation)) if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{ {
layerModel.LayerAnimation.Draw(layerModel, c); layerModel.LayerAnimation.Draw(layerModel, c, DrawScale);
return; return;
} }
// Otherwise draw the rectangle with its layer.AppliedProperties dimensions and brush // Otherwise draw the rectangle with its layer.AppliedProperties dimensions and brush
Rect rect = layerModel.Properties.Contain Rect rect = layerModel.Properties.Contain
? layerModel.LayerRect() ? layerModel.LayerRect(DrawScale)
: new Rect(layerModel.Properties.X * 4, layerModel.Properties.Y * 4, : new Rect(layerModel.Properties.X * DrawScale, layerModel.Properties.Y * DrawScale,
layerModel.Properties.Width * 4, layerModel.Properties.Height * 4); layerModel.Properties.Width * DrawScale, layerModel.Properties.Height * DrawScale);
Rect clip = layerModel.LayerRect(); Rect clip = layerModel.LayerRect();

View File

@ -17,6 +17,7 @@ namespace Artemis.Profiles.Layers.Types.Folder
public bool ShowInEdtor => false; public bool ShowInEdtor => false;
// FolderType pretents to be a keyboard so it's children get drawn // FolderType pretents to be a keyboard so it's children get drawn
public DrawType DrawType => DrawType.Keyboard; public DrawType DrawType => DrawType.Keyboard;
public int DrawScale => 1;
public ImageSource DrawThumbnail(LayerModel layer) public ImageSource DrawThumbnail(LayerModel layer)
{ {

View File

@ -18,6 +18,7 @@ namespace Artemis.Profiles.Layers.Types.Generic
public string Name => "Generic (Logitech)"; public string Name => "Generic (Logitech)";
public bool ShowInEdtor => false; public bool ShowInEdtor => false;
public DrawType DrawType => DrawType.Generic; public DrawType DrawType => DrawType.Generic;
public int DrawScale => 1;
public ImageSource DrawThumbnail(LayerModel layer) public ImageSource DrawThumbnail(LayerModel layer)
{ {
@ -35,12 +36,12 @@ namespace Artemis.Profiles.Layers.Types.Generic
// If an animation is present, let it handle the drawing // If an animation is present, let it handle the drawing
if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation)) if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{ {
layerModel.LayerAnimation.Draw(layerModel, c); layerModel.LayerAnimation.Draw(layerModel, c, DrawScale);
return; return;
} }
// Otherwise draw the rectangle with its applied dimensions and brush // Otherwise draw the rectangle with its applied dimensions and brush
var rect = layerModel.LayerRect(); var rect = layerModel.LayerRect(DrawScale);
// Can't meddle with the original brush because it's frozen. // Can't meddle with the original brush because it's frozen.
var brush = layerModel.Brush.Clone(); var brush = layerModel.Brush.Clone();

View File

@ -18,6 +18,7 @@ namespace Artemis.Profiles.Layers.Types.Headset
public string Name => "Headset"; public string Name => "Headset";
public bool ShowInEdtor => false; public bool ShowInEdtor => false;
public DrawType DrawType => DrawType.Headset; public DrawType DrawType => DrawType.Headset;
public int DrawScale => 1;
public ImageSource DrawThumbnail(LayerModel layer) public ImageSource DrawThumbnail(LayerModel layer)
{ {
@ -35,12 +36,12 @@ namespace Artemis.Profiles.Layers.Types.Headset
// If an animation is present, let it handle the drawing // If an animation is present, let it handle the drawing
if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation)) if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{ {
layerModel.LayerAnimation.Draw(layerModel, c); layerModel.LayerAnimation.Draw(layerModel, c, DrawScale);
return; return;
} }
// Otherwise draw the rectangle with its applied dimensions and brush // Otherwise draw the rectangle with its applied dimensions and brush
var rect = layerModel.LayerRect(); var rect = layerModel.LayerRect(DrawScale);
// Can't meddle with the original brush because it's frozen. // Can't meddle with the original brush because it's frozen.
var brush = layerModel.Brush.Clone(); var brush = layerModel.Brush.Clone();

View File

@ -23,6 +23,7 @@ namespace Artemis.Profiles.Layers.Types.KeyPress
private readonly DeviceManager _deviceManager; private readonly DeviceManager _deviceManager;
private List<LayerModel> _keyPressLayers; private List<LayerModel> _keyPressLayers;
private LayerModel _layerModel; private LayerModel _layerModel;
public int DrawScale => 4;
public KeyPressType(DeviceManager deviceManager) public KeyPressType(DeviceManager deviceManager)
{ {

View File

@ -15,6 +15,7 @@ namespace Artemis.Profiles.Layers.Types.Keyboard
public string Name => "Keyboard"; public string Name => "Keyboard";
public bool ShowInEdtor => true; public bool ShowInEdtor => true;
public DrawType DrawType => DrawType.Keyboard; public DrawType DrawType => DrawType.Keyboard;
public int DrawScale => 4;
public ImageSource DrawThumbnail(LayerModel layer) public ImageSource DrawThumbnail(LayerModel layer)
{ {
@ -39,7 +40,7 @@ namespace Artemis.Profiles.Layers.Types.Keyboard
// If an animation is present, let it handle the drawing // If an animation is present, let it handle the drawing
if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation)) if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{ {
layerModel.LayerAnimation.Draw(layerModel, c); layerModel.LayerAnimation.Draw(layerModel, c, DrawScale);
return; return;
} }
@ -49,7 +50,7 @@ namespace Artemis.Profiles.Layers.Types.Keyboard
: new Rect(layerModel.Properties.X*4, layerModel.Properties.Y*4, : new Rect(layerModel.Properties.X*4, layerModel.Properties.Y*4,
layerModel.Properties.Width*4, layerModel.Properties.Height*4); layerModel.Properties.Width*4, layerModel.Properties.Height*4);
var clip = layerModel.LayerRect(); var clip = layerModel.LayerRect(DrawScale);
// Can't meddle with the original brush because it's frozen. // Can't meddle with the original brush because it's frozen.
var brush = layerModel.Brush.Clone(); var brush = layerModel.Brush.Clone();

View File

@ -19,6 +19,7 @@ namespace Artemis.Profiles.Layers.Types.KeyboardGif
public string Name => "Keyboard - GIF"; public string Name => "Keyboard - GIF";
public bool ShowInEdtor => true; public bool ShowInEdtor => true;
public DrawType DrawType => DrawType.Keyboard; public DrawType DrawType => DrawType.Keyboard;
public int DrawScale => 4;
public ImageSource DrawThumbnail(LayerModel layer) public ImageSource DrawThumbnail(LayerModel layer)
{ {

View File

@ -18,6 +18,7 @@ namespace Artemis.Profiles.Layers.Types.Mouse
public string Name => "Mouse"; public string Name => "Mouse";
public bool ShowInEdtor => false; public bool ShowInEdtor => false;
public DrawType DrawType => DrawType.Mouse; public DrawType DrawType => DrawType.Mouse;
public int DrawScale => 1;
public ImageSource DrawThumbnail(LayerModel layer) public ImageSource DrawThumbnail(LayerModel layer)
{ {
@ -37,12 +38,12 @@ namespace Artemis.Profiles.Layers.Types.Mouse
// If an animation is present, let it handle the drawing // If an animation is present, let it handle the drawing
if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation)) if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{ {
layerModel.LayerAnimation.Draw(layerModel, c); layerModel.LayerAnimation.Draw(layerModel, c, DrawScale);
return; return;
} }
// Otherwise draw the rectangle with its applied dimensions and brush // Otherwise draw the rectangle with its applied dimensions and brush
var rect = layerModel.LayerRect(); var rect = layerModel.LayerRect(DrawScale);
// Can't meddle with the original brush because it's frozen. // Can't meddle with the original brush because it's frozen.
var brush = layerModel.Brush.Clone(); var brush = layerModel.Brush.Clone();

View File

@ -18,6 +18,7 @@ namespace Artemis.Profiles.Layers.Types.Mousemat
public string Name => "Mousemat"; public string Name => "Mousemat";
public bool ShowInEdtor => false; public bool ShowInEdtor => false;
public DrawType DrawType => DrawType.Mousemat; public DrawType DrawType => DrawType.Mousemat;
public int DrawScale => 1;
public ImageSource DrawThumbnail(LayerModel layer) public ImageSource DrawThumbnail(LayerModel layer)
{ {
@ -35,12 +36,12 @@ namespace Artemis.Profiles.Layers.Types.Mousemat
// If an animation is present, let it handle the drawing // If an animation is present, let it handle the drawing
if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation)) if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{ {
layerModel.LayerAnimation.Draw(layerModel, c); layerModel.LayerAnimation.Draw(layerModel, c, DrawScale);
return; return;
} }
// Otherwise draw the rectangle with its applied dimensions and brush // Otherwise draw the rectangle with its applied dimensions and brush
var rect = layerModel.LayerRect(); var rect = layerModel.LayerRect(1);
// Can't meddle with the original brush because it's frozen. // Can't meddle with the original brush because it's frozen.
var brush = layerModel.Brush.Clone(); var brush = layerModel.Brush.Clone();

View File

@ -42,8 +42,8 @@ namespace Artemis.ViewModels
if (Layer.Properties == null) if (Layer.Properties == null)
Layer.SetupProperties(); Layer.SetupProperties();
// Setup existing conditions // Setup existing conditions
var conditions = layer.Properties.Conditions.Select(c => new LayerConditionViewModel(this, c)); var conditions = ProposedLayer.Properties.Conditions.Select(c => new LayerConditionViewModel(this, c));
LayerConditionVms = new BindableCollection<LayerConditionViewModel>(conditions); LayerConditionVms = new BindableCollection<LayerConditionViewModel>(conditions);
PropertyChanged += PropertiesViewModelHandler; PropertyChanged += PropertiesViewModelHandler;
@ -155,6 +155,10 @@ namespace Artemis.ViewModels
EventPropertiesViewModel = ProposedLayer.IsEvent EventPropertiesViewModel = ProposedLayer.IsEvent
? new EventPropertiesViewModel(Layer.EventProperties) ? new EventPropertiesViewModel(Layer.EventProperties)
: null; : null;
// The form inside each condition VM changes upon event toggle
foreach (var layerConditionViewModel in LayerConditionVms)
layerConditionViewModel.SetupPropertyInput();
} }
public void AddCondition() public void AddCondition()
@ -171,7 +175,7 @@ namespace Artemis.ViewModels
JsonConvert.PopulateObject(JsonConvert.SerializeObject(ProposedLayer), Layer); JsonConvert.PopulateObject(JsonConvert.SerializeObject(ProposedLayer), Layer);
Layer.Properties.Conditions.Clear(); Layer.Properties.Conditions.Clear();
foreach (var conditionViewModel in LayerConditionVms) foreach (var conditionViewModel in LayerConditionVms)
Layer.Properties.Conditions.Add(conditionViewModel.LayerConditionModel); Layer.Properties.Conditions.Add(conditionViewModel.ConditionModel);
// TODO: EventPropVM must have layer too // TODO: EventPropVM must have layer too
if (EventPropertiesViewModel != null) if (EventPropertiesViewModel != null)
@ -202,7 +206,7 @@ namespace Artemis.ViewModels
ProposedLayer.EventProperties = EventPropertiesViewModel.GetAppliedProperties(); ProposedLayer.EventProperties = EventPropertiesViewModel.GetAppliedProperties();
ProposedLayer.Properties.Conditions.Clear(); ProposedLayer.Properties.Conditions.Clear();
foreach (var conditionViewModel in LayerConditionVms) foreach (var conditionViewModel in LayerConditionVms)
ProposedLayer.Properties.Conditions.Add(conditionViewModel.LayerConditionModel); ProposedLayer.Properties.Conditions.Add(conditionViewModel.ConditionModel);
// If not a keyboard, ignore size and position // If not a keyboard, ignore size and position
if ((ProposedLayer.LayerType.DrawType != DrawType.Keyboard) || !ProposedLayer.LayerType.ShowInEdtor) if ((ProposedLayer.LayerType.DrawType != DrawType.Keyboard) || !ProposedLayer.LayerType.ShowInEdtor)

View File

@ -193,6 +193,8 @@ namespace Artemis.ViewModels
public bool EditorEnabled => SelectedProfile != null && !SelectedProfile.IsDefault && public bool EditorEnabled => SelectedProfile != null && !SelectedProfile.IsDefault &&
_deviceManager.ActiveKeyboard != null; _deviceManager.ActiveKeyboard != null;
public bool LuaButtonVisible => !_moduleModel.IsOverlay;
#endregion #endregion
#region Layers #region Layers

View File

@ -1,257 +1,254 @@
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Layers.Models;
using Artemis.Utilities; using Artemis.Utilities;
using Caliburn.Micro; using Caliburn.Micro;
namespace Artemis.ViewModels.Profiles namespace Artemis.ViewModels.Profiles
{ {
public sealed class LayerConditionViewModel : Screen public sealed class LayerConditionViewModel : Screen
{ {
private readonly NamedOperator[] _boolOperators = private readonly NamedOperator[] _boolOperators =
{ {
new NamedOperator("Equal to", "==") new NamedOperator("Equal to", "==")
}; };
private readonly LayerEditorViewModel _conditionModel; private readonly LayerEditorViewModel _editorViewModel;
private readonly NamedOperator[] _int32Operators = private readonly NamedOperator[] _int32Operators =
{ {
new NamedOperator("Lower than", "<"), new NamedOperator("Lower than", "<"),
new NamedOperator("Lower or equal to", "<="), new NamedOperator("Lower or equal to", "<="),
new NamedOperator("Higher than", ">"), new NamedOperator("Higher than", ">"),
new NamedOperator("Higher or equal to", ">="), new NamedOperator("Higher or equal to", ">="),
new NamedOperator("Equal to", "=="), new NamedOperator("Equal to", "=="),
new NamedOperator("Not equal to", "!=") new NamedOperator("Not equal to", "!=")
}; };
private readonly NamedOperator[] _operators = private readonly NamedOperator[] _operators =
{ {
new NamedOperator("Equal to", "=="), new NamedOperator("Equal to", "=="),
new NamedOperator("Not equal to", "!=") new NamedOperator("Not equal to", "!=")
}; };
private readonly NamedOperator[] _stringOperators = private readonly NamedOperator[] _stringOperators =
{ {
new NamedOperator("Equal to", "=="), new NamedOperator("Equal to", "=="),
new NamedOperator("Not equal to", "!="), new NamedOperator("Not equal to", "!="),
new NamedOperator("Contains", ".Contains"), new NamedOperator("Contains", ".Contains"),
new NamedOperator("Starts with", ".StartsWith"), new NamedOperator("Starts with", ".StartsWith"),
new NamedOperator("Ends with", ".EndsWith") new NamedOperator("Ends with", ".EndsWith")
}; };
private bool _enumValueIsVisible; private bool _enumValueIsVisible;
private bool _preselecting; private GeneralHelpers.PropertyCollection _selectedDataModelProp;
private GeneralHelpers.PropertyCollection _selectedDataModelProp; private string _selectedEnum;
private string _selectedEnum; private NamedOperator _selectedOperator;
private NamedOperator _selectedOperator; private string _userValue;
private string _userValue; private bool _userValueIsVisible;
private bool _userValueIsVisible;
public LayerConditionViewModel(LayerEditorViewModel editorViewModel, LayerConditionModel conditionModel)
public LayerConditionViewModel(LayerEditorViewModel conditionModel, LayerConditionModel layerConditionModel) {
{ _editorViewModel = editorViewModel;
_conditionModel = conditionModel;
_preselecting = false; ConditionModel = conditionModel;
DataModelProps = editorViewModel.DataModelProps;
LayerConditionModel = layerConditionModel; Operators = new BindableCollection<NamedOperator>();
DataModelProps = conditionModel.DataModelProps; Enums = new BindableCollection<string>();
Operators = new BindableCollection<NamedOperator>();
Enums = new BindableCollection<string>(); PropertyChanged += MapViewToModel;
MapModelToView();
PropertyChanged += UpdateModel; }
PropertyChanged += UpdateForm;
public LayerConditionModel ConditionModel { get; set; }
PreSelect();
} public BindableCollection<GeneralHelpers.PropertyCollection> DataModelProps { get; set; }
public LayerConditionModel LayerConditionModel { get; set; } public BindableCollection<NamedOperator> Operators { get; set; }
public BindableCollection<string> Enums { get; set; }
public BindableCollection<GeneralHelpers.PropertyCollection> DataModelProps { get; set; }
public string UserValue
public BindableCollection<NamedOperator> Operators { get; set; } {
public BindableCollection<string> Enums { get; set; } get { return _userValue; }
set
public string UserValue {
{ if (value == _userValue) return;
get { return _userValue; } _userValue = value;
set NotifyOfPropertyChange(() => UserValue);
{ }
if (value == _userValue) return; }
_userValue = value;
NotifyOfPropertyChange(() => UserValue); public GeneralHelpers.PropertyCollection SelectedDataModelProp
} {
} get { return _selectedDataModelProp; }
set
public GeneralHelpers.PropertyCollection SelectedDataModelProp {
{ if (value.Equals(_selectedDataModelProp)) return;
get { return _selectedDataModelProp; } _selectedDataModelProp = value;
set SetupPropertyInput();
{ NotifyOfPropertyChange(() => SelectedDataModelProp);
if (value.Equals(_selectedDataModelProp)) return; }
_selectedDataModelProp = value; }
NotifyOfPropertyChange(() => SelectedDataModelProp);
} public bool UserValueIsVisible
} {
get { return _userValueIsVisible; }
set
public bool UserValueIsVisible {
{ if (value == _userValueIsVisible) return;
get { return _userValueIsVisible; } _userValueIsVisible = value;
set NotifyOfPropertyChange(() => UserValueIsVisible);
{ }
if (value == _userValueIsVisible) return; }
_userValueIsVisible = value;
NotifyOfPropertyChange(() => UserValueIsVisible); public bool EnumValueIsVisible
} {
} get { return _enumValueIsVisible; }
set
public bool EnumValueIsVisible {
{ if (value == _enumValueIsVisible) return;
get { return _enumValueIsVisible; } _enumValueIsVisible = value;
set NotifyOfPropertyChange(() => EnumValueIsVisible);
{ }
if (value == _enumValueIsVisible) return; }
_enumValueIsVisible = value;
NotifyOfPropertyChange(() => EnumValueIsVisible); public NamedOperator SelectedOperator
} {
} get { return _selectedOperator; }
set
public NamedOperator SelectedOperator {
{ _selectedOperator = value;
get { return _selectedOperator; } SetupUserValueInput();
set NotifyOfPropertyChange(() => SelectedOperator);
{ }
_selectedOperator = value; }
NotifyOfPropertyChange(() => SelectedOperator);
} public string SelectedEnum
} {
get { return _selectedEnum; }
public string SelectedEnum set
{ {
get { return _selectedEnum; } if (value == _selectedEnum) return;
set _selectedEnum = value;
{ NotifyOfPropertyChange(() => SelectedEnum);
if (value == _selectedEnum) return; }
_selectedEnum = value; }
NotifyOfPropertyChange(() => SelectedEnum);
} public void MapModelToView()
} {
PropertyChanged -= MapViewToModel;
/// <summary>
/// Handles updating the form to match the selected data model property // Select the right property
/// </summary> SelectedDataModelProp = DataModelProps.FirstOrDefault(m => m.Path == ConditionModel.Field);
/// <param name="sender"></param> // Select the operator
/// <param name="e"></param> SelectedOperator = Operators.FirstOrDefault(o => o.Value == ConditionModel.Operator);
private void UpdateForm(object sender, PropertyChangedEventArgs e)
{ if (ConditionModel.Type == "Enum" || ConditionModel.Type == "Boolean")
if (e.PropertyName != "SelectedDataModelProp") SelectedEnum = ConditionModel.Value;
return; else
UserValue = ConditionModel.Value;
Operators.Clear();
Enums.Clear(); PropertyChanged += MapViewToModel;
UserValueIsVisible = false; }
EnumValueIsVisible = false;
public void MapViewToModel()
switch (SelectedDataModelProp.Type) {
{ ConditionModel.Field = SelectedDataModelProp.Path;
case "Int32": ConditionModel.Operator = SelectedOperator.Value;
case "Single": ConditionModel.Type = SelectedDataModelProp.Type;
Operators.AddRange(_int32Operators);
UserValueIsVisible = true; if (ConditionModel.Type == "Enum" || ConditionModel.Type == "Boolean")
break; ConditionModel.Value = SelectedEnum;
case "Boolean": else
Operators.AddRange(_boolOperators); ConditionModel.Value = UserValue;
Enums.Add("True"); }
Enums.Add("False");
EnumValueIsVisible = true; private void MapViewToModel(object sender, PropertyChangedEventArgs e)
break; {
case "String": MapViewToModel();
Operators.AddRange(_stringOperators); }
UserValueIsVisible = true;
break; public void SetupPropertyInput()
default: {
Operators.AddRange(_operators); Operators.Clear();
UserValueIsVisible = true; Enums.Clear();
break;
} switch (SelectedDataModelProp.Type)
{
// Setup Enum selection if needed case "Int32":
if (SelectedDataModelProp.EnumValues != null) case "Single":
{ Operators.AddRange(_int32Operators);
Enums.AddRange(SelectedDataModelProp.EnumValues); UserValueIsVisible = true;
EnumValueIsVisible = true; break;
} case "Boolean":
Operators.AddRange(_boolOperators);
SelectedOperator = Operators.First(); Enums.Add("True");
} Enums.Add("False");
EnumValueIsVisible = true;
break;
/// <summary> case "String":
/// Handles saving user input to the model Operators.AddRange(_stringOperators);
/// TODO: Data validation? UserValueIsVisible = true;
/// </summary> break;
/// <param name="sender"></param> default:
/// <param name="e"></param> Operators.AddRange(_operators);
private void UpdateModel(object sender, PropertyChangedEventArgs e) UserValueIsVisible = true;
{ break;
// Don't mess with model during preselect }
if (_preselecting)
return; // Add Changed operator is the type is event
if (_editorViewModel.ProposedLayer.IsEvent)
// Only care about these fields {
if (e.PropertyName != "UserValue" && Operators.Add(new NamedOperator("Changed", "changed"));
e.PropertyName != "SelectedOperator" && // Also add decreased and increased operator on numbers
e.PropertyName != "SelectedDataModelProp" && if (SelectedDataModelProp.Type == "Int32" || SelectedDataModelProp.Type == "Single")
e.PropertyName != "SelectedEnum") {
return; Operators.Add(new NamedOperator("Decreased", "decreased"));
Operators.Add(new NamedOperator("Increased", "increased"));
LayerConditionModel.Field = SelectedDataModelProp.Path; }
LayerConditionModel.Operator = SelectedOperator.Value; }
LayerConditionModel.Type = SelectedDataModelProp.Type;
SetupUserValueInput();
if (SelectedDataModelProp.Type == "Enum" || SelectedDataModelProp.Type == "Boolean") }
LayerConditionModel.Value = SelectedEnum;
else private void SetupUserValueInput()
LayerConditionModel.Value = UserValue; {
UserValueIsVisible = false;
UpdateForm(sender, e); EnumValueIsVisible = false;
}
if (SelectedOperator.Value == "changed" || SelectedOperator.Value == "decreased" ||
/// <summary> SelectedOperator.Value == "increased")
/// Setup the current UI elements to show the backing model return;
/// </summary>
private void PreSelect() if (SelectedDataModelProp.Type == "Boolean")
{ {
_preselecting = true; EnumValueIsVisible = true;
SelectedDataModelProp = DataModelProps.FirstOrDefault(m => m.Path == LayerConditionModel.Field); }
SelectedOperator = Operators.FirstOrDefault(o => o.Value == LayerConditionModel.Operator); else if (SelectedDataModelProp.EnumValues != null)
LayerConditionModel.Type = SelectedDataModelProp.Type; {
if (LayerConditionModel.Type == "Enum" || LayerConditionModel.Type == "Boolean") Enums.AddRange(SelectedDataModelProp.EnumValues);
SelectedEnum = LayerConditionModel.Value; EnumValueIsVisible = true;
else }
UserValue = LayerConditionModel.Value; }
_preselecting = false; /// <summary>
} /// Delete the current model from the parent
/// </summary>
/// <summary> public void Delete()
/// Delete the current model from the parent {
/// </summary> _editorViewModel.DeleteCondition(this, ConditionModel);
public void Delete() }
{
_conditionModel.DeleteCondition(this, LayerConditionModel); public struct NamedOperator
} {
public string Display { get; set; }
public struct NamedOperator public string Value { get; set; }
{
public string Display { get; set; } public NamedOperator(string display, string value)
public string Value { get; set; } {
Display = display;
public NamedOperator(string display, string value) Value = value;
{ }
Display = display; }
Value = value; }
}
}
}
} }

View File

@ -7,7 +7,7 @@
xmlns:utilities="clr-namespace:Artemis.Utilities" xmlns:utilities="clr-namespace:Artemis.Utilities"
xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d" mc:Ignorable="d"
Title="Artemis | Edit Layer" Height="820" Width="630" Title="Artemis | Edit Layer" Height="860" Width="630"
xmlns:cal="http://www.caliburnproject.org" xmlns:cal="http://www.caliburnproject.org"
xmlns:converters="clr-namespace:Artemis.Utilities.Converters" xmlns:converters="clr-namespace:Artemis.Utilities.Converters"
xmlns:models="clr-namespace:Artemis.Profiles.Layers.Models" xmlns:models="clr-namespace:Artemis.Profiles.Layers.Models"

View File

@ -156,7 +156,8 @@
</Button> </Button>
<Button x:Name="EditLua" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" <Button x:Name="EditLua" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Import profile" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Import profile"
IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"> IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"
Visibility="{Binding Path=LuaButtonVisible, Converter={StaticResource BoolToVis} }">
<Button.Content> <Button.Content>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Rectangle <Rectangle