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:
parent
954f4864d8
commit
5c8968a32d
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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:
|
||||
|
||||
@ -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}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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; }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user