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

Disable layers by default when Toggle Enable keybind is first keybind

Layer editor move and resize selected layer when underneath other layers
Fix copy-paste crash
This commit is contained in:
SpoinkyNL 2017-04-30 22:34:11 +02:00
parent 954f4864d8
commit 5c8968a32d
5 changed files with 545 additions and 520 deletions

View File

@ -61,7 +61,7 @@ namespace Artemis
}
// If there is another type of of IInputControl get the non-scaled position - or do some processing to get a scaled position, whatever needs to happen
if ((e != null) && (input != null))
if (e != null && input != null)
return e.GetPosition(input).X;
// Return 0 if no processing could be done
@ -98,7 +98,7 @@ namespace Artemis
logger.Info("Artemis was run using the autorun shortcut, sleeping for 15 sec.");
Thread.Sleep(15000);
}
InputHook.Start();
_kernel = new StandardKernel(new BaseModules(), new ManagerModules());
_kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
@ -145,6 +145,7 @@ namespace Artemis
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<ShellViewModel>();
InputHook.Start();
}
}
}

View File

@ -63,9 +63,15 @@ namespace Artemis.Profiles.Layers.Models
switch (ToggleType)
{
case ToggleType.Enable:
// Apply RenderAllowed only if this is the first keybind
if (index == 0)
layerModel.RenderAllowed = false;
action = () => layerModel.RenderAllowed = true;
break;
case ToggleType.Disable:
// Apply RenderAllowed only if this is the first keybind
if (index == 0)
layerModel.RenderAllowed = false;
action = () => layerModel.RenderAllowed = false;
break;
case ToggleType.Toggle:

View File

@ -1,261 +1,261 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using Artemis.Modules.Abstract;
using Artemis.Profiles.Layers.Abstract;
using Artemis.Profiles.Layers.Animations;
using Artemis.Profiles.Layers.Conditions;
using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Types.Keyboard;
using Artemis.Utilities;
using Artemis.Utilities.ParentChild;
using Newtonsoft.Json;
namespace Artemis.Profiles.Layers.Models
{
public class LayerModel : IChildItem<LayerModel>, IChildItem<ProfileModel>
{
public LayerModel()
{
Children = new ChildItemCollection<LayerModel, LayerModel>(this);
TweenModel = new TweenModel(this);
RenderAllowed = true;
var model = Properties as KeyboardPropertiesModel;
if (model != null)
GifImage = new GifImage(model.GifFile, Properties.AnimationSpeed);
}
[JsonIgnore]
public ImageSource LayerImage => LayerType.DrawThumbnail(this);
[JsonIgnore]
public TweenModel TweenModel { get; set; }
/// <summary>
/// Checks whether this layers conditions are met.
/// If they are met and this layer is an event, this also triggers that event.
/// </summary>
/// <param name="dataModel"></param>
/// <returns></returns>
public bool AreConditionsMet(ModuleDataModel dataModel)
{
// Conditions are not even checked if the layer isn't enabled
return Enabled && LayerCondition.ConditionsMet(this, dataModel);
}
/// <summary>
/// Update the layer
/// </summary>
/// <param name="dataModel"></param>
/// <param name="preview"></param>
/// <param name="updateAnimations"></param>
public void Update(ModuleDataModel dataModel, bool preview, bool updateAnimations)
{
if (LayerType == null)
return;
LayerType.Update(this, dataModel, preview);
LayerAnimation?.Update(this, updateAnimations);
if (!preview)
TweenModel.Update();
LastRender = DateTime.Now;
}
/// <summary>
/// Applies the saved properties to the current properties
/// </summary>
/// <param name="advanced">Include advanced properties (opacity, brush)</param>
public void ApplyProperties(bool advanced)
{
X = Properties.X;
Y = Properties.Y;
Width = Properties.Width;
Height = Properties.Height;
if (!advanced)
return;
Opacity = Properties.Opacity;
Brush = Properties.Brush;
}
/// <summary>
/// Draw the layer using the provided context
/// </summary>
/// <param name="dataModel"></param>
/// <param name="c"></param>
/// <param name="preview"></param>
/// <param name="updateAnimations"></param>
public void Draw(ModuleDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations)
{
if (Brush == null || !preview && !RenderAllowed)
return;
LayerType.Draw(this, c);
}
/// <summary>
/// Tells the current layer type to setup the layer's LayerProperties
/// </summary>
public void SetupProperties()
{
LayerType.SetupProperties(this);
// If the type is an event, set it up
if (IsEvent && EventProperties == null)
EventProperties = new KeyboardEventPropertiesModel
{
ExpirationType = ExpirationType.Time,
Length = new TimeSpan(0, 0, 1),
TriggerDelay = new TimeSpan(0)
};
}
/// <summary>
/// Ensures all child layers have a unique order
/// </summary>
public void FixOrder()
{
Children.Sort(l => l.Order);
for (var i = 0; i < Children.Count; i++)
Children[i].Order = i;
}
/// <summary>
/// Returns whether the layer meets the requirements to be drawn in the profile editor
/// </summary>
/// <returns></returns>
public bool MustDraw()
{
// If any of the parents are disabled, this layer must not be drawn
var parent = Parent;
while (parent != null)
{
if (!parent.Enabled)
return false;
parent = parent.Parent;
}
return Enabled && LayerType.ShowInEdtor;
}
/// <summary>
/// Returns every descendant of this layer
/// </summary>
/// <returns></returns>
public IEnumerable<LayerModel> GetLayers()
{
var layers = new List<LayerModel>();
foreach (var layerModel in Children.OrderBy(c => c.Order))
{
layers.Add(layerModel);
layers.AddRange(layerModel.GetLayers());
}
return layers;
}
/// <summary>
/// Creates a new Keyboard layer with default settings
/// </summary>
/// <returns></returns>
public static LayerModel CreateLayer()
{
return new LayerModel
{
Name = "New layer",
Enabled = true,
Order = -1,
LayerType = new KeyboardType(),
LayerCondition = new DataModelCondition(),
LayerAnimation = new NoneAnimation(),
Properties = new KeyboardPropertiesModel
{
Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()),
Height = 1,
Width = 1,
X = 0,
Y = 0,
Opacity = 1,
HeightEaseTime = 0,
HeightEase = "Linear",
WidthEaseTime = 0,
WidthEase = "Linear",
OpacityEaseTime = 0,
OpacityEase = "Linear"
}
};
}
/// <summary>
/// Insert this layer before the given layer
/// </summary>
/// <param name="source"></param>
public void InsertBefore(LayerModel source)
{
source.Order = Order;
Insert(source);
}
/// <summary>
/// Insert this layer after the given layer
/// </summary>
/// <param name="source"></param>
public void InsertAfter(LayerModel source)
{
source.Order = Order + 1;
Insert(source);
}
/// <summary>
/// Insert the layer as a sibling
/// </summary>
/// <param name="source"></param>
private void Insert(LayerModel source)
{
if (Parent != null)
{
foreach (var child in Parent.Children.OrderBy(c => c.Order))
if (child.Order >= source.Order)
child.Order++;
Parent.Children.Add(source);
}
else if (Profile != null)
{
foreach (var layer in Profile.Layers.OrderBy(l => l.Order))
if (layer.Order >= source.Order)
layer.Order++;
Profile.Layers.Add(source);
}
}
public Rect LayerRect(int scale = 4)
{
var width = Width;
var height = Height;
if (width < 0)
width = 0;
if (height < 0)
height = 0;
return new Rect(X * scale, Y * scale, width * scale, height * scale);
}
// TODO: Make this and ProfileModel's GetRenderLayers the same through inheritance
/// <summary>
/// Generates a flat list containing all layers that must be rendered on the keyboard,
/// the first mouse layer to be rendered and the first headset layer to be rendered
/// </summary>
/// <param name="dataModel">Instance of said game data model</param>
/// <param name="keyboardOnly">Whether or not to ignore anything but keyboards</param>
/// <param name="ignoreConditions"></param>
/// <returns>A flat list containing all layers that must be rendered</returns>
public List<LayerModel> GetRenderLayers(ModuleDataModel dataModel, bool keyboardOnly, bool ignoreConditions = false)
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using Artemis.Modules.Abstract;
using Artemis.Profiles.Layers.Abstract;
using Artemis.Profiles.Layers.Animations;
using Artemis.Profiles.Layers.Conditions;
using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Types.Keyboard;
using Artemis.Utilities;
using Artemis.Utilities.ParentChild;
using Newtonsoft.Json;
namespace Artemis.Profiles.Layers.Models
{
public class LayerModel : IChildItem<LayerModel>, IChildItem<ProfileModel>
{
public LayerModel()
{
Children = new ChildItemCollection<LayerModel, LayerModel>(this);
TweenModel = new TweenModel(this);
RenderAllowed = true;
var model = Properties as KeyboardPropertiesModel;
if (model != null)
GifImage = new GifImage(model.GifFile, Properties.AnimationSpeed);
}
[JsonIgnore]
public ImageSource LayerImage => LayerType.DrawThumbnail(this);
[JsonIgnore]
public TweenModel TweenModel { get; set; }
/// <summary>
/// Checks whether this layers conditions are met.
/// If they are met and this layer is an event, this also triggers that event.
/// </summary>
/// <param name="dataModel"></param>
/// <returns></returns>
public bool AreConditionsMet(ModuleDataModel dataModel)
{
// Conditions are not even checked if the layer isn't enabled
return Enabled && LayerCondition.ConditionsMet(this, dataModel);
}
/// <summary>
/// Update the layer
/// </summary>
/// <param name="dataModel"></param>
/// <param name="preview"></param>
/// <param name="updateAnimations"></param>
public void Update(ModuleDataModel dataModel, bool preview, bool updateAnimations)
{
if (LayerType == null)
return;
LayerType.Update(this, dataModel, preview);
LayerAnimation?.Update(this, updateAnimations);
if (!preview)
TweenModel.Update();
LastRender = DateTime.Now;
}
/// <summary>
/// Applies the saved properties to the current properties
/// </summary>
/// <param name="advanced">Include advanced properties (opacity, brush)</param>
public void ApplyProperties(bool advanced)
{
X = Properties.X;
Y = Properties.Y;
Width = Properties.Width;
Height = Properties.Height;
if (!advanced)
return;
Opacity = Properties.Opacity;
Brush = Properties.Brush;
}
/// <summary>
/// Draw the layer using the provided context
/// </summary>
/// <param name="dataModel"></param>
/// <param name="c"></param>
/// <param name="preview"></param>
/// <param name="updateAnimations"></param>
public void Draw(ModuleDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations)
{
if (Brush == null || !preview && !RenderAllowed)
return;
LayerType.Draw(this, c);
}
/// <summary>
/// Tells the current layer type to setup the layer's LayerProperties
/// </summary>
public void SetupProperties()
{
LayerType.SetupProperties(this);
// If the type is an event, set it up
if (IsEvent && EventProperties == null)
EventProperties = new KeyboardEventPropertiesModel
{
ExpirationType = ExpirationType.Time,
Length = new TimeSpan(0, 0, 1),
TriggerDelay = new TimeSpan(0)
};
}
/// <summary>
/// Ensures all child layers have a unique order
/// </summary>
public void FixOrder()
{
Children.Sort(l => l.Order);
for (var i = 0; i < Children.Count; i++)
Children[i].Order = i;
}
/// <summary>
/// Returns whether the layer meets the requirements to be drawn in the profile editor
/// </summary>
/// <returns></returns>
public bool MustDraw()
{
// If any of the parents are disabled, this layer must not be drawn
var parent = Parent;
while (parent != null)
{
if (!parent.Enabled)
return false;
parent = parent.Parent;
}
return Enabled && LayerType.ShowInEdtor;
}
/// <summary>
/// Returns every descendant of this layer
/// </summary>
/// <returns></returns>
public IEnumerable<LayerModel> GetLayers()
{
var layers = new List<LayerModel>();
foreach (var layerModel in Children.OrderBy(c => c.Order))
{
layers.Add(layerModel);
layers.AddRange(layerModel.GetLayers());
}
return layers;
}
/// <summary>
/// Creates a new Keyboard layer with default settings
/// </summary>
/// <returns></returns>
public static LayerModel CreateLayer()
{
return new LayerModel
{
Name = "New layer",
Enabled = true,
Order = -1,
LayerType = new KeyboardType(),
LayerCondition = new DataModelCondition(),
LayerAnimation = new NoneAnimation(),
Properties = new KeyboardPropertiesModel
{
Brush = new SolidColorBrush(ColorHelpers.GetRandomRainbowMediaColor()),
Height = 1,
Width = 1,
X = 0,
Y = 0,
Opacity = 1,
HeightEaseTime = 0,
HeightEase = "Linear",
WidthEaseTime = 0,
WidthEase = "Linear",
OpacityEaseTime = 0,
OpacityEase = "Linear"
}
};
}
/// <summary>
/// Insert this layer before the given layer
/// </summary>
/// <param name="source"></param>
public void InsertBefore(LayerModel source)
{
source.Order = Order;
Insert(source);
}
/// <summary>
/// Insert this layer after the given layer
/// </summary>
/// <param name="source"></param>
public void InsertAfter(LayerModel source)
{
source.Order = Order + 1;
Insert(source);
}
/// <summary>
/// Insert the layer as a sibling
/// </summary>
/// <param name="source"></param>
private void Insert(LayerModel source)
{
if (Parent != null)
{
foreach (var child in Parent.Children.OrderBy(c => c.Order))
if (child.Order >= source.Order)
child.Order++;
Parent.Children.Add(source);
}
else if (Profile != null)
{
foreach (var layer in Profile.Layers.OrderBy(l => l.Order))
if (layer.Order >= source.Order)
layer.Order++;
Profile.Layers.Add(source);
}
}
public Rect LayerRect(int scale = 4)
{
var width = Width;
var height = Height;
if (width < 0)
width = 0;
if (height < 0)
height = 0;
return new Rect(X * scale, Y * scale, width * scale, height * scale);
}
// TODO: Make this and ProfileModel's GetRenderLayers the same through inheritance
/// <summary>
/// Generates a flat list containing all layers that must be rendered on the keyboard,
/// the first mouse layer to be rendered and the first headset layer to be rendered
/// </summary>
/// <param name="dataModel">Instance of said game data model</param>
/// <param name="keyboardOnly">Whether or not to ignore anything but keyboards</param>
/// <param name="ignoreConditions"></param>
/// <returns>A flat list containing all layers that must be rendered</returns>
public List<LayerModel> GetRenderLayers(ModuleDataModel dataModel, bool keyboardOnly, bool ignoreConditions = false)
{
var layers = new List<LayerModel>();
foreach (var layerModel in Children.OrderByDescending(l => l.Order))
{
@ -272,149 +272,149 @@ namespace Artemis.Profiles.Layers.Models
layers.AddRange(layerModel.GetRenderLayers(dataModel, keyboardOnly, ignoreConditions));
}
return layers;
}
public void SetupCondition()
{
if (IsEvent && !(LayerCondition is EventCondition))
LayerCondition = new EventCondition();
else if (!IsEvent && !(LayerCondition is DataModelCondition))
LayerCondition = new DataModelCondition();
}
public void SetupKeybinds()
{
RenderAllowed = true;
// Clean up old keybinds
RemoveKeybinds();
for (var index = 0; index < Properties.LayerKeybindModels.Count; index++)
{
var keybindModel = Properties.LayerKeybindModels[index];
keybindModel.Register(this, index);
}
}
public void RemoveKeybinds()
{
foreach (var keybindModel in Properties.LayerKeybindModels)
keybindModel.Unregister();
}
#region Properties
#region Layer type properties
public ILayerType LayerType { get; set; }
public ILayerCondition LayerCondition { get; set; }
public ILayerAnimation LayerAnimation { get; set; }
#endregion
#region Generic properties
public string Name { get; set; }
public int Order { get; set; }
public bool Enabled { get; set; }
public bool RenderAllowed { get; set; }
public bool Expanded { get; set; }
public bool IsEvent { get; set; }
public LayerPropertiesModel Properties { get; set; }
public EventPropertiesModel EventProperties { get; set; }
#endregion
#region Relational properties
public ChildItemCollection<LayerModel, LayerModel> Children { get; }
[JsonIgnore]
public LayerModel Parent { get; internal set; }
[JsonIgnore]
public ProfileModel Profile { get; internal set; }
#endregion
#region Render properties
[JsonIgnore] private Brush _brush;
[JsonIgnore]
public double X { get; set; }
[JsonIgnore]
public double Y { get; set; }
[JsonIgnore]
public double Width { get; set; }
[JsonIgnore]
public double Height { get; set; }
[JsonIgnore]
public double Opacity { get; set; }
[JsonIgnore]
public Brush Brush
{
get { return _brush; }
set
{
if (value == null)
{
_brush = null;
return;
}
if (value.IsFrozen)
{
_brush = value;
return;
}
// Clone the brush off of the UI thread and freeze it
var cloned = value.Dispatcher.Invoke(value.CloneCurrentValue);
cloned.Freeze();
_brush = cloned;
}
}
[JsonIgnore]
public double AnimationProgress { get; set; }
[JsonIgnore]
public GifImage GifImage { get; set; }
[JsonIgnore]
public DateTime LastRender { get; set; }
#endregion
#endregion
#region IChildItem<Parent> Members
LayerModel IChildItem<LayerModel>.Parent
{
get { return Parent; }
set { Parent = value; }
}
ProfileModel IChildItem<ProfileModel>.Parent
{
get { return Profile; }
set { Profile = value; }
}
#endregion
/// <inheritdoc />
public override string ToString()
{
return $"{nameof(Name)}: {Name}, {nameof(Order)}: {Order}, {nameof(X)}: {X}, {nameof(Y)}: {Y}, {nameof(Width)}: {Width}, {nameof(Height)}: {Height}";
}
}
}
return layers;
}
public void SetupCondition()
{
if (IsEvent && !(LayerCondition is EventCondition))
LayerCondition = new EventCondition();
else if (!IsEvent && !(LayerCondition is DataModelCondition))
LayerCondition = new DataModelCondition();
}
public void SetupKeybinds()
{
RenderAllowed = true;
// Clean up old keybinds
RemoveKeybinds();
for (var index = 0; index < Properties.LayerKeybindModels.Count; index++)
{
var keybindModel = Properties.LayerKeybindModels[index];
keybindModel.Register(this, index);
}
}
public void RemoveKeybinds()
{
foreach (var keybindModel in Properties.LayerKeybindModels)
keybindModel.Unregister();
}
#region Properties
#region Layer type properties
public ILayerType LayerType { get; set; }
public ILayerCondition LayerCondition { get; set; }
public ILayerAnimation LayerAnimation { get; set; }
#endregion
#region Generic properties
public string Name { get; set; }
public int Order { get; set; }
public bool Enabled { get; set; }
public bool RenderAllowed { get; set; }
public bool Expanded { get; set; }
public bool IsEvent { get; set; }
public LayerPropertiesModel Properties { get; set; }
public EventPropertiesModel EventProperties { get; set; }
#endregion
#region Relational properties
public ChildItemCollection<LayerModel, LayerModel> Children { get; }
[JsonIgnore]
public LayerModel Parent { get; internal set; }
[JsonIgnore]
public ProfileModel Profile { get; internal set; }
#endregion
#region Render properties
[JsonIgnore] private Brush _brush;
[JsonIgnore]
public double X { get; set; }
[JsonIgnore]
public double Y { get; set; }
[JsonIgnore]
public double Width { get; set; }
[JsonIgnore]
public double Height { get; set; }
[JsonIgnore]
public double Opacity { get; set; }
[JsonIgnore]
public Brush Brush
{
get { return _brush; }
set
{
if (value == null)
{
_brush = null;
return;
}
if (value.IsFrozen)
{
_brush = value;
return;
}
// Clone the brush off of the UI thread and freeze it
var cloned = value.Dispatcher.Invoke(value.CloneCurrentValue);
cloned.Freeze();
_brush = cloned;
}
}
[JsonIgnore]
public double AnimationProgress { get; set; }
[JsonIgnore]
public GifImage GifImage { get; set; }
[JsonIgnore]
public DateTime LastRender { get; set; }
#endregion
#endregion
#region IChildItem<Parent> Members
LayerModel IChildItem<LayerModel>.Parent
{
get { return Parent; }
set { Parent = value; }
}
ProfileModel IChildItem<ProfileModel>.Parent
{
get { return Profile; }
set { Profile = value; }
}
#endregion
/// <inheritdoc />
public override string ToString()
{
return $"{nameof(Name)}: {Name}, {nameof(Order)}: {Order}, {nameof(X)}: {X}, {nameof(Y)}: {Y}, {nameof(Width)}: {Width}, {nameof(Height)}: {Height}";
}
}
}

View File

@ -1,95 +1,95 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Media;
using Artemis.Utilities.Converters;
using Newtonsoft.Json;
namespace Artemis.Profiles.Layers.Models
{
public abstract class LayerPropertiesModel
{
private Brush _brush;
public LayerPropertiesModel(LayerPropertiesModel source = null)
{
if (source == null)
return;
// Clone the source's properties onto the new properties model (useful when changing property type)
X = source.X;
Y = source.Y;
Width = source.Width;
Height = source.Height;
Contain = source.Contain;
Opacity = source.Opacity;
AnimationSpeed = source.AnimationSpeed;
Conditions = source.Conditions;
LayerKeybindModels = source.LayerKeybindModels;
ConditionType = source.ConditionType;
DynamicProperties = source.DynamicProperties;
Brush = source.Brush;
HeightEase = source.HeightEase;
WidthEase = source.WidthEase;
OpacityEase = source.OpacityEase;
HeightEaseTime = source.HeightEaseTime;
WidthEaseTime = source.WidthEaseTime;
OpacityEaseTime = source.OpacityEaseTime;
}
public double X { get; set; }
public double Y { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public bool Contain { get; set; }
public double Opacity { get; set; }
public double AnimationSpeed { get; set; }
public double OpacityEaseTime { get; set; }
public double HeightEaseTime { get; set; }
public double WidthEaseTime { get; set; }
public string WidthEase { set; get; }
public string HeightEase { get; set; }
public string OpacityEase { get; set; }
public ConditionType ConditionType { get; set; }
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Media;
using Artemis.Utilities.Converters;
using Newtonsoft.Json;
namespace Artemis.Profiles.Layers.Models
{
public abstract class LayerPropertiesModel
{
private Brush _brush;
public LayerPropertiesModel(LayerPropertiesModel source = null)
{
if (source == null)
return;
// Clone the source's properties onto the new properties model (useful when changing property type)
X = source.X;
Y = source.Y;
Width = source.Width;
Height = source.Height;
Contain = source.Contain;
Opacity = source.Opacity;
AnimationSpeed = source.AnimationSpeed;
Conditions = source.Conditions;
LayerKeybindModels = source.LayerKeybindModels;
ConditionType = source.ConditionType;
DynamicProperties = source.DynamicProperties;
Brush = source.Brush;
HeightEase = source.HeightEase;
WidthEase = source.WidthEase;
OpacityEase = source.OpacityEase;
HeightEaseTime = source.HeightEaseTime;
WidthEaseTime = source.WidthEaseTime;
OpacityEaseTime = source.OpacityEaseTime;
}
public double X { get; set; }
public double Y { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public bool Contain { get; set; }
public double Opacity { get; set; }
public double AnimationSpeed { get; set; }
public double OpacityEaseTime { get; set; }
public double HeightEaseTime { get; set; }
public double WidthEaseTime { get; set; }
public string WidthEase { set; get; }
public string HeightEase { get; set; }
public string OpacityEase { get; set; }
public ConditionType ConditionType { get; set; }
public List<LayerConditionModel> Conditions { get; set; } = new List<LayerConditionModel>();
public List<LayerKeybindModel> LayerKeybindModels { get; set; } = new List<LayerKeybindModel>();
public List<DynamicPropertiesModel> DynamicProperties { get; set; } = new List<DynamicPropertiesModel>();
[JsonConverter(typeof(BrushJsonConverter))]
public Brush Brush
{
get { return _brush; }
set
{
if (value == null)
{
_brush = null;
return;
}
if (value.IsFrozen)
{
_brush = value;
return;
}
// Clone the brush off of the UI thread and freeze it
var cloned = value.Dispatcher.Invoke(value.CloneCurrentValue);
cloned.Freeze();
_brush = cloned;
}
}
public Rect PropertiesRect(int scale = 4)
{
return new Rect(X*scale, Y*scale, Width*scale, Height*scale);
}
}
public enum ConditionType
{
[Description("All met")] AllMet,
[Description("Any met")] AnyMet,
[Description("None met")] NoneMet
}
public List<LayerKeybindModel> LayerKeybindModels { get; set; } = new List<LayerKeybindModel>();
public List<DynamicPropertiesModel> DynamicProperties { get; set; } = new List<DynamicPropertiesModel>();
[JsonConverter(typeof(BrushJsonConverter))]
public Brush Brush
{
get { return _brush; }
set
{
if (value == null)
{
_brush = null;
return;
}
if (value.IsFrozen)
{
_brush = value;
return;
}
// Clone the brush off of the UI thread and freeze it
var cloned = value.Dispatcher.Invoke(value.CloneCurrentValue);
cloned.Freeze();
_brush = cloned;
}
}
public Rect PropertiesRect(int scale = 4)
{
return new Rect(X*scale, Y*scale, Width*scale, Height*scale);
}
}
public enum ConditionType
{
[Description("All met")] AllMet,
[Description("Any met")] AnyMet,
[Description("None met")] NoneMet
}
}

View File

@ -324,7 +324,7 @@ namespace Artemis.ViewModels
public void LayerToClipboard()
{
if (SelectedLayer == null || !ActiveWindowHelper.MainWindowActive)
if (SelectedLayer == null || !ActiveWindowHelper.MainWindowActive || !IsActive)
return;
// Probably not how the cool kids do it but leveraging on JsonConvert gives flawless serialization
@ -333,28 +333,35 @@ namespace Artemis.ViewModels
public void ClipboardToLayer()
{
if (!ActiveWindowHelper.MainWindowActive)
if (!ActiveWindowHelper.MainWindowActive || !IsActive)
return;
GeneralHelpers.ExecuteSta(() =>
try
{
var data = (string) Clipboard.GetData("layer");
if (data == null)
return;
var layerModel = JsonConvert.DeserializeObject<LayerModel>(data);
if (layerModel == null)
return;
if (SelectedLayer != null)
SelectedLayer.InsertAfter(layerModel);
else
GeneralHelpers.ExecuteSta(() =>
{
SelectedProfile.Layers.Add(layerModel);
SelectedProfile.FixOrder();
}
Execute.OnUIThread(() => UpdateLayerList(layerModel));
});
var data = (string) Clipboard.GetData("layer");
if (data == null)
return;
var layerModel = JsonConvert.DeserializeObject<LayerModel>(data);
if (layerModel == null)
return;
if (SelectedLayer != null)
SelectedLayer.InsertAfter(layerModel);
else
{
SelectedProfile.Layers.Add(layerModel);
SelectedProfile.FixOrder();
}
Execute.OnUIThread(() => UpdateLayerList(layerModel));
});
}
catch (Exception)
{
// ignored
}
}
private void UpdateLayerList(LayerModel selectModel)
@ -665,7 +672,7 @@ namespace Artemis.ViewModels
return;
var pos = GetScaledPosition(e);
var hoverLayer = GetLayers().Where(l => l.MustDraw()).FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(pos.X, pos.Y));
var hoverLayer = GetHoverLayer(pos.X, pos.Y);
if (hoverLayer != null)
SelectedLayer = hoverLayer;
@ -681,7 +688,7 @@ namespace Artemis.ViewModels
return;
var pos = GetScaledPosition(e);
var hoverLayer = GetLayers().Where(l => l.MustDraw()).FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(pos.X, pos.Y));
var hoverLayer = GetHoverLayer(pos.X, pos.Y);
HandleDragging(e, pos.X, pos.Y, hoverLayer);
@ -703,6 +710,8 @@ namespace Artemis.ViewModels
KeyboardPreviewCursor = Cursors.Hand;
}
private Point GetScaledPosition(MouseEventArgs e)
{
var previewSettings = _deviceManager.ActiveKeyboard.PreviewSettings;
@ -723,6 +732,15 @@ namespace Artemis.ViewModels
return pos;
}
private LayerModel GetHoverLayer(double x, double y)
{
// Prefer the selected layer as the hover layer even if it's underneath something else
if (SelectedLayer != null && SelectedLayer.Properties.PropertiesRect(1).Contains(x, y))
return SelectedLayer;
return GetLayers().Where(l => l.MustDraw()).FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(x, y));
}
public Cursor KeyboardPreviewCursor
{
get { return _keyboardPreviewCursor; }