1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +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>
/// Loads the last active effect and starts the program
/// </summary>
public void EnableProgram()
public async void EnableProgram()
{
Logger.Debug("Enabling program");
ProgramEnabled = true;
LoopManager.StartAsync();
foreach (var overlayModule in ModuleManager.OverlayModules)
{
if (overlayModule.Settings.IsEnabled)
overlayModule.Enable();
}
await LoopManager.StartAsync();
RaiseEnabledChangedEvent(new EnabledChangedEventArgs(ProgramEnabled));
}

View File

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

View File

@ -59,7 +59,7 @@ namespace Artemis.Modules.Games.EurotruckSimulator2
Settings.Save();
if (!File.Exists(dir + "/plugins/ets2-telemetry-server.dll"))
PlacePlugins();
PlaceTruckSimulatorPlugin(dir, "eurotrucks2.exe");
}
public void FindAtsGameDir()
@ -76,22 +76,14 @@ namespace Artemis.Modules.Games.EurotruckSimulator2
Settings.Save();
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(ets2Path))
PlaceTruckSimulatorPlugin(ets2Path, "eurotrucks2.exe");
if (string.IsNullOrEmpty(path))
return;
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
if (!Directory.Exists(path))
{

View File

@ -68,7 +68,7 @@
<Grid>
<TextBox x:Name="Ets2GameDirectory" Height="23" TextWrapping="Wrap" Margin="5,0,30,0"
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"
HorizontalAlignment="Right" Width="25"
Style="{DynamicResource SquareButtonStyle}" Height="26" />
@ -80,7 +80,7 @@
<Grid>
<TextBox x:Name="AtsGameDirectory" Height="23" TextWrapping="Wrap" Margin="5,0,30,0"
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"
HorizontalAlignment="Right" Width="25"
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.Modules.Abstract;
using Ninject;
@ -17,39 +16,48 @@ namespace Artemis.Modules.Games.EurotruckSimulator2
public override bool UsesProfileEditor => true;
public void PlacePlugins()
{
((EurotruckSimulator2Model) ModuleModel).PlacePlugins();
}
public void Ets2BrowseDirectory()
{
var settings = (EurotruckSimulator2Settings) Settings;
var model = (EurotruckSimulator2Model) ModuleModel;
var dialog = new FolderBrowserDialog {SelectedPath = settings.Ets2GameDirectory};
var result = dialog.ShowDialog();
if (result != DialogResult.OK)
return;
settings.Ets2GameDirectory = Path.GetDirectoryName(dialog.SelectedPath);
settings.Ets2GameDirectory = dialog.SelectedPath;
NotifyOfPropertyChange(() => Settings);
Settings.Save();
((EurotruckSimulator2Model) ModuleModel).PlacePlugins();
model.PlaceTruckSimulatorPlugin(settings.Ets2GameDirectory, "eurotrucks2.exe");
}
public void AtsBrowseDirectory()
{
var settings = (EurotruckSimulator2Settings) Settings;
var model = (EurotruckSimulator2Model)ModuleModel;
var dialog = new FolderBrowserDialog {SelectedPath = settings.AtsGameDirectory};
var result = dialog.ShowDialog();
if (result != DialogResult.OK)
return;
settings.AtsGameDirectory = Path.GetDirectoryName(dialog.SelectedPath);
settings.AtsGameDirectory = dialog.SelectedPath;
NotifyOfPropertyChange(() => Settings);
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.General.GeneralProfile;
using MoonSharp.Interpreter;
namespace Artemis.Modules.Overlays.OverlayProfile
{
@ -7,9 +8,17 @@ namespace Artemis.Modules.Overlays.OverlayProfile
{
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.Events;
using Artemis.Managers;
using Artemis.Modules.Abstract;
using Artemis.Modules.General.GeneralProfile;
using Ninject;
using CSCore.CoreAudioAPI;
namespace Artemis.Modules.Overlays.OverlayProfile
{
public class OverlayProfileModel : ModuleModel
{
private readonly GeneralProfileModel _generalProfileModule;
private AudioEndpointVolume _endPointVolume;
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>();
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 bool IsOverlay => true;
public override bool IsBoundToProcess => false;
private void OnAudioDeviceChanged(object sender, AudioDeviceChangedEventArgs e)
{
_endPointVolume = AudioEndpointVolume.FromDevice(e.DefaultPlayback);
}
public override void Update()
{
if (!Settings.IsEnabled)
return;
var dataModel = (OverlayProfileDataModel) DataModel;
if (!_generalProfileModule.IsInitialized)
_generalProfileModule.Update();
dataModel.GeneralDataModel = (GeneralProfileDataModel) _generalProfileModule.DataModel;
dataModel.Keyboard.NumLock = ((ushort) GeneralProfileModel.GetKeyState(0x90) & 0xffff) != 0;
dataModel.Keyboard.CapsLock = ((ushort) GeneralProfileModel.GetKeyState(0x14) & 0xffff) != 0;
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;
}
public void Draw(LayerModel layerModel, DrawingContext c)
public void Draw(LayerModel layerModel, DrawingContext c, int drawScale)
{
if (layerModel.Brush == null)
return;
// Set up variables for this frame
var rect = layerModel.Properties.Contain
? layerModel.LayerRect()
: layerModel.Properties.PropertiesRect();
? layerModel.LayerRect(drawScale)
: 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
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;
}
public void Draw(LayerModel layerModel, DrawingContext c)
public void Draw(LayerModel layerModel, DrawingContext c, int drawScale)
{
if (layerModel.Brush == null)
return;
// Set up variables for this frame
var rect = layerModel.Properties.Contain
? layerModel.LayerRect()
: layerModel.Properties.PropertiesRect();
? layerModel.LayerRect(drawScale)
: layerModel.Properties.PropertiesRect(drawScale);
var clip = layerModel.LayerRect();
var clip = layerModel.LayerRect(drawScale);
// Can't meddle with the original brush because it's frozen.
var brush = layerModel.Brush.Clone();

View File

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

View File

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

View File

@ -1,4 +1,5 @@
using System;
using System.Globalization;
using Artemis.Modules.Abstract;
using Artemis.Utilities;
using DynamicExpresso;
@ -8,6 +9,7 @@ namespace Artemis.Profiles.Layers.Models
public class LayerConditionModel
{
private readonly Interpreter _interpreter;
private object _lastValue;
public LayerConditionModel()
{
@ -23,39 +25,92 @@ namespace Artemis.Profiles.Layers.Models
{
lock (subject)
{
if (string.IsNullOrEmpty(Field) || string.IsNullOrEmpty(Value) || string.IsNullOrEmpty(Type))
if (string.IsNullOrEmpty(Field) || string.IsNullOrEmpty(Type))
return false;
var inspect = GeneralHelpers.GetPropertyValue(subject, Field);
if (inspect == null)
{
_lastValue = null;
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;
}
bool returnValue;
if (Operator == "changed" || Operator == "decreased" || Operator == "increased")
returnValue = EvaluateEventOperator(subject, inspect);
else
returnValue = EvaluateOperator(subject);
return _interpreter.Eval<bool>($"subject.{Field} {Operator} value",
new Parameter("subject", subject.GetType(), subject), rightParam);
_lastValue = inspect;
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.Utilities;
using Artemis.ViewModels;
using Artemis.ViewModels.Profiles;
using Newtonsoft.Json;
namespace Artemis.Profiles.Layers.Types.AmbientLight
@ -26,6 +25,7 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight
public string Name => "Keyboard - Ambient Light";
public bool ShowInEdtor => true;
public DrawType DrawType => DrawType.Keyboard;
public int DrawScale => 4;
[JsonIgnore] private AmbienceCreatorType? _lastAmbienceCreatorType;
@ -77,11 +77,7 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight
public void Draw(LayerModel layerModel, DrawingContext c)
{
var rect = new Rect(layerModel.Properties.X*4,
layerModel.Properties.Y*4,
layerModel.Properties.Width*4,
layerModel.Properties.Height*4);
var rect = layerModel.LayerRect(DrawScale);
c.DrawRectangle(((AmbientLightPropertiesModel) layerModel.Properties).AmbientLightBrush, null, rect);
}

View File

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

View File

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

View File

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

View File

@ -18,6 +18,7 @@ namespace Artemis.Profiles.Layers.Types.Generic
public string Name => "Generic (Logitech)";
public bool ShowInEdtor => false;
public DrawType DrawType => DrawType.Generic;
public int DrawScale => 1;
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 (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{
layerModel.LayerAnimation.Draw(layerModel, c);
layerModel.LayerAnimation.Draw(layerModel, c, DrawScale);
return;
}
// 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.
var brush = layerModel.Brush.Clone();

View File

@ -18,6 +18,7 @@ namespace Artemis.Profiles.Layers.Types.Headset
public string Name => "Headset";
public bool ShowInEdtor => false;
public DrawType DrawType => DrawType.Headset;
public int DrawScale => 1;
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 (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{
layerModel.LayerAnimation.Draw(layerModel, c);
layerModel.LayerAnimation.Draw(layerModel, c, DrawScale);
return;
}
// 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.
var brush = layerModel.Brush.Clone();

View File

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

View File

@ -15,6 +15,7 @@ namespace Artemis.Profiles.Layers.Types.Keyboard
public string Name => "Keyboard";
public bool ShowInEdtor => true;
public DrawType DrawType => DrawType.Keyboard;
public int DrawScale => 4;
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 (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{
layerModel.LayerAnimation.Draw(layerModel, c);
layerModel.LayerAnimation.Draw(layerModel, c, DrawScale);
return;
}
@ -49,7 +50,7 @@ namespace Artemis.Profiles.Layers.Types.Keyboard
: new Rect(layerModel.Properties.X*4, layerModel.Properties.Y*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.
var brush = layerModel.Brush.Clone();

View File

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

View File

@ -18,6 +18,7 @@ namespace Artemis.Profiles.Layers.Types.Mouse
public string Name => "Mouse";
public bool ShowInEdtor => false;
public DrawType DrawType => DrawType.Mouse;
public int DrawScale => 1;
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 (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{
layerModel.LayerAnimation.Draw(layerModel, c);
layerModel.LayerAnimation.Draw(layerModel, c, DrawScale);
return;
}
// 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.
var brush = layerModel.Brush.Clone();

View File

@ -18,6 +18,7 @@ namespace Artemis.Profiles.Layers.Types.Mousemat
public string Name => "Mousemat";
public bool ShowInEdtor => false;
public DrawType DrawType => DrawType.Mousemat;
public int DrawScale => 1;
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 (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{
layerModel.LayerAnimation.Draw(layerModel, c);
layerModel.LayerAnimation.Draw(layerModel, c, DrawScale);
return;
}
// 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.
var brush = layerModel.Brush.Clone();

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@
xmlns:utilities="clr-namespace:Artemis.Utilities"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
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:converters="clr-namespace:Artemis.Utilities.Converters"
xmlns:models="clr-namespace:Artemis.Profiles.Layers.Models"

View File

@ -156,7 +156,8 @@
</Button>
<Button x:Name="EditLua" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
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>
<StackPanel Orientation="Horizontal">
<Rectangle