1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2026-01-02 10:43:31 +00:00

Simplified layer render pipeline

This commit is contained in:
SpoinkyNL 2016-11-30 14:43:20 +01:00
parent 590d6991fe
commit 33094731aa
28 changed files with 464 additions and 338 deletions

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Layers.Models;
@ -8,16 +7,16 @@ namespace Artemis.Profiles.Layers.Animations
{ {
public class GrowAnimation : ILayerAnimation public class GrowAnimation : ILayerAnimation
{ {
public string Name { get; } = "Grow"; public string Name => "Grow";
public void Update(LayerModel layerModel, bool updateAnimations) public void Update(LayerModel layerModel, bool updateAnimations)
{ {
// TODO: Generic implementation // TODO: Generic implementation
// Reset animation progress if layer wasn't drawn for 100ms // Reset animation progress if layer wasn't drawn for 100ms
if ((new TimeSpan(0, 0, 0, 0, 100) < DateTime.Now - layerModel.LastRender) && updateAnimations) if ((new TimeSpan(0, 0, 0, 0, 100) < DateTime.Now - layerModel.LastRender) && updateAnimations)
layerModel.Properties.AnimationProgress = 0; layerModel.AnimationProgress = 0;
var progress = layerModel.Properties.AnimationProgress; var progress = layerModel.AnimationProgress;
if (MustExpire(layerModel)) if (MustExpire(layerModel))
progress = 0; progress = 0;
@ -25,43 +24,42 @@ namespace Artemis.Profiles.Layers.Animations
// If not previewing, store the animation progress in the actual model for the next frame // If not previewing, store the animation progress in the actual model for the next frame
if (updateAnimations) if (updateAnimations)
layerModel.Properties.AnimationProgress = progress; layerModel.AnimationProgress = progress;
} }
public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
if (applied?.Brush == null) if (layerModel.Brush == null)
return; return;
const int scale = 4;
// Set up variables for this frame // Set up variables for this frame
var rect = applied.Contain var rect = layerModel.Properties.Contain
? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale) ? layerModel.LayerRect()
: new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale); : layerModel.Properties.PropertiesRect();
var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale); var clip = layerModel.LayerRect();
// Take an offset of 4 to allow layers to slightly leave their bounds // Take an offset of 4 to allow layers to slightly leave their bounds
var progress = (6.0 - props.AnimationProgress)*10.0; var progress = (6.0 - layerModel.AnimationProgress)*10.0;
if (progress < 0) if (progress < 0)
{ {
// Can't meddle with the original brush because it's frozen. // Can't meddle with the original brush because it's frozen.
var brush = applied.Brush.Clone(); var brush = layerModel.Brush.Clone();
brush.Opacity = 1 + 0.025*progress; brush.Opacity = 1 + 0.025*progress;
if (brush.Opacity < 0) if (brush.Opacity < 0)
brush.Opacity = 0; brush.Opacity = 0;
if (brush.Opacity > 1) if (brush.Opacity > 1)
brush.Opacity = 1; brush.Opacity = 1;
applied.Brush = brush; layerModel.Brush = brush;
} }
rect.Inflate(-rect.Width/100.0*progress, -rect.Height/100.0*progress); rect.Inflate(-rect.Width/100.0*progress, -rect.Height/100.0*progress);
clip.Inflate(-clip.Width/100.0*progress, -clip.Height/100.0*progress); clip.Inflate(-clip.Width/100.0*progress, -clip.Height/100.0*progress);
c.PushClip(new RectangleGeometry(clip)); c.PushClip(new RectangleGeometry(clip));
c.DrawRectangle(applied.Brush, null, rect); c.DrawRectangle(layerModel.Brush, null, rect);
c.Pop(); c.Pop();
} }
public bool MustExpire(LayerModel layer) => layer.Properties.AnimationProgress > 10; public bool MustExpire(LayerModel layer) => layer.AnimationProgress > 10;
} }
} }

View File

@ -6,13 +6,13 @@ namespace Artemis.Profiles.Layers.Animations
{ {
public class NoneAnimation : ILayerAnimation public class NoneAnimation : ILayerAnimation
{ {
public string Name { get; } = "None"; public string Name => "None";
public void Update(LayerModel layerModel, bool updateAnimations) public void Update(LayerModel layerModel, bool updateAnimations)
{ {
} }
public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
} }

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Layers.Models;
@ -8,16 +7,16 @@ namespace Artemis.Profiles.Layers.Animations
{ {
public class PulseAnimation : ILayerAnimation public class PulseAnimation : ILayerAnimation
{ {
public string Name { get; } = "Pulse"; public string Name => "Pulse";
public void Update(LayerModel layerModel, bool updateAnimations) public void Update(LayerModel layerModel, bool updateAnimations)
{ {
// TODO: Generic implementation // TODO: Generic implementation
// Reset animation progress if layer wasn't drawn for 100ms // Reset animation progress if layer wasn't drawn for 100ms
if ((new TimeSpan(0, 0, 0, 0, 100) < DateTime.Now - layerModel.LastRender) && updateAnimations) if ((new TimeSpan(0, 0, 0, 0, 100) < DateTime.Now - layerModel.LastRender) && updateAnimations)
layerModel.Properties.AnimationProgress = 0; layerModel.AnimationProgress = 0;
var progress = layerModel.Properties.AnimationProgress; var progress = layerModel.AnimationProgress;
if (MustExpire(layerModel)) if (MustExpire(layerModel))
progress = 0; progress = 0;
@ -25,32 +24,31 @@ namespace Artemis.Profiles.Layers.Animations
// If not previewing, store the animation progress in the actual model for the next frame // If not previewing, store the animation progress in the actual model for the next frame
if (updateAnimations) if (updateAnimations)
layerModel.Properties.AnimationProgress = progress; layerModel.AnimationProgress = progress;
} }
public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
if (applied.Brush == null) if (layerModel.Brush == null)
return; return;
const int scale = 4;
// Set up variables for this frame // Set up variables for this frame
var rect = applied.Contain var rect = layerModel.Properties.Contain
? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale) ? layerModel.LayerRect()
: new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale); : layerModel.Properties.PropertiesRect();
var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale); var clip = layerModel.LayerRect();
// Can't meddle with the original brush because it's frozen. // Can't meddle with the original brush because it's frozen.
var brush = applied.Brush.Clone(); var brush = layerModel.Brush.Clone();
brush.Opacity = (Math.Sin(props.AnimationProgress*Math.PI) + 1)*(props.Opacity/2); brush.Opacity = (Math.Sin(layerModel.AnimationProgress*Math.PI) + 1)*(layerModel.Opacity/2);
applied.Brush = brush; layerModel.Brush = brush;
c.PushClip(new RectangleGeometry(clip)); c.PushClip(new RectangleGeometry(clip));
c.DrawRectangle(applied.Brush, null, rect); c.DrawRectangle(layerModel.Brush, null, rect);
c.Pop(); c.Pop();
} }
public bool MustExpire(LayerModel layer) => layer.Properties.AnimationProgress > 2; public bool MustExpire(LayerModel layer) => layer.AnimationProgress > 2;
} }
} }

View File

@ -7,45 +7,46 @@ namespace Artemis.Profiles.Layers.Animations
{ {
public class SlideDownAnimation : ILayerAnimation public class SlideDownAnimation : ILayerAnimation
{ {
public string Name { get; } = "Slide down"; public string Name => "Slide down";
public void Update(LayerModel layerModel, bool updateAnimations) public void Update(LayerModel layerModel, bool updateAnimations)
{ {
var progress = layerModel.Properties.AnimationProgress; var progress = layerModel.AnimationProgress;
if (MustExpire(layerModel)) if (MustExpire(layerModel))
progress = 0; progress = 0;
progress = progress + layerModel.Properties.AnimationSpeed*2; progress = progress + layerModel.Properties.AnimationSpeed*2;
// If not previewing, store the animation progress in the actual model for the next frame // If not previewing, store the animation progress in the actual model for the next frame
if (updateAnimations) if (updateAnimations)
layerModel.Properties.AnimationProgress = progress; layerModel.AnimationProgress = progress;
} }
public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
if (applied.Brush == null) if (layerModel.Brush == null)
return; return;
const int scale = 4;
// Set up variables for this frame // Set up variables for this frame
var rect = applied.Contain var rect = layerModel.Properties.Contain
? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale) ? layerModel.LayerRect()
: new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale); : layerModel.Properties.PropertiesRect();
var s1 = new Rect(new Point(rect.X, rect.Y + props.AnimationProgress), new Size(rect.Width, rect.Height)); var s1 = new Rect(new Point(rect.X, rect.Y + layerModel.AnimationProgress),
var s2 = new Rect(new Point(s1.X, s1.Y - rect.Height), new Size(rect.Width, rect.Height + .5)); new Size(rect.Width, rect.Height));
var s2 = new Rect(new Point(s1.X, s1.Y - rect.Height),
new Size(rect.Width, rect.Height + .5));
var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale); var clip = layerModel.LayerRect();
c.PushClip(new RectangleGeometry(clip)); c.PushClip(new RectangleGeometry(clip));
c.DrawRectangle(applied.Brush, null, s1); c.DrawRectangle(layerModel.Brush, null, s1);
c.DrawRectangle(applied.Brush, null, s2); c.DrawRectangle(layerModel.Brush, null, s2);
c.Pop(); c.Pop();
} }
public bool MustExpire(LayerModel layer) public bool MustExpire(LayerModel layer)
{ {
return layer.Properties.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Height*4; return layer.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Height*4;
} }
} }
} }

View File

@ -7,46 +7,46 @@ namespace Artemis.Profiles.Layers.Animations
{ {
public class SlideLeftAnimation : ILayerAnimation public class SlideLeftAnimation : ILayerAnimation
{ {
public string Name { get; } = "Slide left"; public string Name => "Slide left";
public void Update(LayerModel layerModel, bool updateAnimations) public void Update(LayerModel layerModel, bool updateAnimations)
{ {
var progress = layerModel.Properties.AnimationProgress; var progress = layerModel.AnimationProgress;
if (MustExpire(layerModel)) if (MustExpire(layerModel))
progress = 0; progress = 0;
progress = progress + layerModel.Properties.AnimationSpeed*2; progress = progress + layerModel.Properties.AnimationSpeed*2;
// If not previewing, store the animation progress in the actual model for the next frame // If not previewing, store the animation progress in the actual model for the next frame
if (updateAnimations) if (updateAnimations)
layerModel.Properties.AnimationProgress = progress; layerModel.AnimationProgress = progress;
} }
public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
if (applied.Brush == null) if (layerModel.Brush == null)
return; return;
const int scale = 4;
// Set up variables for this frame // Set up variables for this frame
var rect = applied.Contain var rect = layerModel.Properties.Contain
? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale) ? layerModel.LayerRect()
: new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale); : layerModel.Properties.PropertiesRect();
var s1 = new Rect(new Point(rect.X - props.AnimationProgress, rect.Y), var s1 = new Rect(new Point(rect.X - layerModel.AnimationProgress, rect.Y),
new Size(rect.Width + .5, rect.Height)); new Size(rect.Width + .5, rect.Height));
var s2 = new Rect(new Point(s1.X + rect.Width, rect.Y), new Size(rect.Width, rect.Height)); var s2 = new Rect(new Point(s1.X + rect.Width, rect.Y),
new Size(rect.Width, rect.Height));
var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale); var clip = layerModel.LayerRect();
c.PushClip(new RectangleGeometry(clip)); c.PushClip(new RectangleGeometry(clip));
c.DrawRectangle(applied.Brush, null, s1); c.DrawRectangle(layerModel.Brush, null, s1);
c.DrawRectangle(applied.Brush, null, s2); c.DrawRectangle(layerModel.Brush, null, s2);
c.Pop(); c.Pop();
} }
public bool MustExpire(LayerModel layer) public bool MustExpire(LayerModel layer)
{ {
return layer.Properties.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Width*4; return layer.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Width*4;
} }
} }
} }

View File

@ -7,45 +7,46 @@ namespace Artemis.Profiles.Layers.Animations
{ {
public class SlideRightAnimation : ILayerAnimation public class SlideRightAnimation : ILayerAnimation
{ {
public string Name { get; } = "Slide right"; public string Name => "Slide right";
public void Update(LayerModel layerModel, bool updateAnimations) public void Update(LayerModel layerModel, bool updateAnimations)
{ {
var progress = layerModel.Properties.AnimationProgress; var progress = layerModel.AnimationProgress;
if (MustExpire(layerModel)) if (MustExpire(layerModel))
progress = 0; progress = 0;
progress = progress + layerModel.Properties.AnimationSpeed*2; progress = progress + layerModel.Properties.AnimationSpeed*2;
// If not previewing, store the animation progress in the actual model for the next frame // If not previewing, store the animation progress in the actual model for the next frame
if (updateAnimations) if (updateAnimations)
layerModel.Properties.AnimationProgress = progress; layerModel.AnimationProgress = progress;
} }
public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
if (applied.Brush == null) if (layerModel.Brush == null)
return; return;
const int scale = 4;
// Set up variables for this frame // Set up variables for this frame
var rect = applied.Contain var rect = layerModel.Properties.Contain
? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale) ? layerModel.LayerRect()
: new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale); : layerModel.Properties.PropertiesRect();
var s1 = new Rect(new Point(rect.X + props.AnimationProgress, rect.Y), new Size(rect.Width, rect.Height)); var s1 = new Rect(new Point(rect.X + layerModel.AnimationProgress, rect.Y),
var s2 = new Rect(new Point(s1.X - rect.Width, rect.Y), new Size(rect.Width + .5, rect.Height)); new Size(rect.Width, rect.Height));
var s2 = new Rect(new Point(s1.X - rect.Width, rect.Y),
new Size(rect.Width + .5, rect.Height));
var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale); var clip = layerModel.LayerRect();
c.PushClip(new RectangleGeometry(clip)); c.PushClip(new RectangleGeometry(clip));
c.DrawRectangle(applied.Brush, null, s1); c.DrawRectangle(layerModel.Brush, null, s1);
c.DrawRectangle(applied.Brush, null, s2); c.DrawRectangle(layerModel.Brush, null, s2);
c.Pop(); c.Pop();
} }
public bool MustExpire(LayerModel layer) public bool MustExpire(LayerModel layer)
{ {
return layer.Properties.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Width*4; return layer.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Width*4;
} }
} }
} }

View File

@ -7,46 +7,45 @@ namespace Artemis.Profiles.Layers.Animations
{ {
public class SlideUpAnimation : ILayerAnimation public class SlideUpAnimation : ILayerAnimation
{ {
public string Name { get; } = "Slide up"; public string Name => "Slide up";
public void Update(LayerModel layerModel, bool updateAnimations) public void Update(LayerModel layerModel, bool updateAnimations)
{ {
var progress = layerModel.Properties.AnimationProgress; var progress = layerModel.AnimationProgress;
if (MustExpire(layerModel)) if (MustExpire(layerModel))
progress = 0; progress = 0;
progress = progress + layerModel.Properties.AnimationSpeed*2; progress = progress + layerModel.Properties.AnimationSpeed*2;
// If not previewing, store the animation progress in the actual model for the next frame // If not previewing, store the animation progress in the actual model for the next frame
if (updateAnimations) if (updateAnimations)
layerModel.Properties.AnimationProgress = progress; layerModel.AnimationProgress = progress;
} }
public void Draw(LayerPropertiesModel props, LayerPropertiesModel applied, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
if (applied.Brush == null) if (layerModel.Brush == null)
return; return;
const int scale = 4;
// Set up variables for this frame // Set up variables for this frame
var rect = applied.Contain var rect = layerModel.Properties.Contain
? new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale) ? layerModel.LayerRect()
: new Rect(props.X*scale, props.Y*scale, props.Width*scale, props.Height*scale); : layerModel.Properties.PropertiesRect();
var s1 = new Rect(new Point(rect.X, rect.Y - props.AnimationProgress), var s1 = new Rect(new Point(rect.X, rect.Y - layerModel.AnimationProgress),
new Size(rect.Width, rect.Height + .5)); new Size(rect.Width, rect.Height + .5));
var s2 = new Rect(new Point(s1.X, s1.Y + rect.Height), new Size(rect.Width, rect.Height)); var s2 = new Rect(new Point(s1.X, s1.Y + rect.Height), new Size(rect.Width, rect.Height));
var clip = new Rect(applied.X*scale, applied.Y*scale, applied.Width*scale, applied.Height*scale); var clip = layerModel.LayerRect();
c.PushClip(new RectangleGeometry(clip)); c.PushClip(new RectangleGeometry(clip));
c.DrawRectangle(applied.Brush, null, s1); c.DrawRectangle(layerModel.Brush, null, s1);
c.DrawRectangle(applied.Brush, null, s2); c.DrawRectangle(layerModel.Brush, null, s2);
c.Pop(); c.Pop();
} }
public bool MustExpire(LayerModel layer) public bool MustExpire(LayerModel layer)
{ {
return layer.Properties.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Height*4; return layer.AnimationProgress + layer.Properties.AnimationSpeed*2 >= layer.Properties.Height*4;
} }
} }
} }

View File

@ -7,11 +7,11 @@ namespace Artemis.Profiles.Layers.Conditions
{ {
public class DataModelCondition : ILayerCondition public class DataModelCondition : ILayerCondition
{ {
public bool ConditionsMet(LayerModel layer, IDataModel dataModel) public bool ConditionsMet(LayerModel layerModel, IDataModel dataModel)
{ {
lock (layer.Properties.Conditions) lock (layerModel.Properties.Conditions)
{ {
return layer.Properties.Conditions.All(cm => cm.ConditionMet(dataModel)); return layerModel.Properties.Conditions.All(cm => cm.ConditionMet(dataModel));
} }
} }
} }

View File

@ -7,17 +7,17 @@ namespace Artemis.Profiles.Layers.Conditions
{ {
public class EventCondition : ILayerCondition public class EventCondition : ILayerCondition
{ {
public bool ConditionsMet(LayerModel layer, IDataModel dataModel) public bool ConditionsMet(LayerModel layerModel, IDataModel dataModel)
{ {
lock (layer.Properties.Conditions) lock (layerModel.Properties.Conditions)
{ {
var conditionsMet = layer.Properties.Conditions.All(cm => cm.ConditionMet(dataModel)); var conditionsMet = layerModel.Properties.Conditions.All(cm => cm.ConditionMet(dataModel));
layer.EventProperties.Update(layer, conditionsMet); layerModel.EventProperties.Update(layerModel, conditionsMet);
if (conditionsMet && layer.EventProperties.CanTrigger) if (conditionsMet && layerModel.EventProperties.CanTrigger)
layer.EventProperties.TriggerEvent(layer); layerModel.EventProperties.TriggerEvent(layerModel);
return layer.EventProperties.MustDraw; return layerModel.EventProperties.MustDraw;
} }
} }
} }

View File

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

View File

@ -5,6 +5,6 @@ namespace Artemis.Profiles.Layers.Interfaces
{ {
public interface ILayerCondition public interface ILayerCondition
{ {
bool ConditionsMet(LayerModel layer, IDataModel dataModel); bool ConditionsMet(LayerModel layerModel, IDataModel dataModel);
} }
} }

View File

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Windows.Media;
using System.Windows.Media;
using Artemis.Models.Interfaces; using Artemis.Models.Interfaces;
using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Abstract;
using Artemis.Profiles.Layers.Models; using Artemis.Profiles.Layers.Models;
@ -38,9 +37,9 @@ namespace Artemis.Profiles.Layers.Interfaces
/// <summary> /// <summary>
/// Draws the layer /// Draws the layer
/// </summary> /// </summary>
/// <param name="layer">The layer to draw</param> /// <param name="layerModel">The layer to draw</param>
/// <param name="c">The drawing context to draw with</param> /// <param name="c">The drawing context to draw with</param>
void Draw(LayerModel layer, DrawingContext c); void Draw(LayerModel layerModel, DrawingContext c);
/// <summary> /// <summary>
/// Updates the provided layer layerModel according to this type /// Updates the provided layer layerModel according to this type
@ -61,7 +60,8 @@ namespace Artemis.Profiles.Layers.Interfaces
/// </summary> /// </summary>
/// <param name="layerEditorViewModel">The layer editor VM this type resides in</param> /// <param name="layerEditorViewModel">The layer editor VM this type resides in</param>
/// <param name="layerPropertiesViewModel">The current viewmodel</param> /// <param name="layerPropertiesViewModel">The current viewmodel</param>
LayerPropertiesViewModel SetupViewModel(LayerEditorViewModel layerEditorViewModel, LayerPropertiesViewModel layerPropertiesViewModel); LayerPropertiesViewModel SetupViewModel(LayerEditorViewModel layerEditorViewModel,
LayerPropertiesViewModel layerPropertiesViewModel);
} }
public enum DrawType public enum DrawType

View File

@ -37,15 +37,15 @@ namespace Artemis.Profiles.Layers.Models
/// </summary> /// </summary>
public LayerPropertyOptions LayerPropertyOptions { get; set; } public LayerPropertyOptions LayerPropertyOptions { get; set; }
internal void ApplyProperty(IDataModel dataModel, LayerPropertiesModel properties) internal void ApplyProperty(IDataModel dataModel, LayerModel layerModel)
{ {
if (LayerPropertyType == LayerPropertyType.PercentageOf) if (LayerPropertyType == LayerPropertyType.PercentageOf)
ApplyPercentageOf(dataModel, properties, PercentageSource); ApplyPercentageOf(dataModel, layerModel, PercentageSource);
if (LayerPropertyType == LayerPropertyType.PercentageOfProperty) if (LayerPropertyType == LayerPropertyType.PercentageOfProperty)
ApplyPercentageOfProperty(dataModel, properties); ApplyPercentageOfProperty(dataModel, layerModel);
} }
private void ApplyPercentageOf(IDataModel dataModel, LayerPropertiesModel properties, float src) private void ApplyPercentageOf(IDataModel dataModel, LayerModel layerModel, float src)
{ {
if (GameProperty == null) if (GameProperty == null)
return; return;
@ -54,61 +54,61 @@ namespace Artemis.Profiles.Layers.Models
var percentage = gameProperty/src; var percentage = gameProperty/src;
if (LayerProperty == "Width") if (LayerProperty == "Width")
ApplyWidth(properties, percentage); ApplyWidth(layerModel, percentage);
else if (LayerProperty == "Height") else if (LayerProperty == "Height")
ApplyHeight(properties, percentage); ApplyHeight(layerModel, percentage);
else if (LayerProperty == "Opacity") else if (LayerProperty == "Opacity")
ApplyOpacity(properties, percentage); ApplyOpacity(layerModel, percentage);
} }
private void ApplyWidth(LayerPropertiesModel properties, float percentage) private void ApplyWidth(LayerModel layerModel, float percentage)
{ {
var newWidth = Math.Round(percentage*(float) properties.Width, 2); var newWidth = Math.Round(percentage*(float) layerModel.Width, 2);
var difference = properties.Width - newWidth; var difference = layerModel.Width - newWidth;
if (newWidth < 0) if (newWidth < 0)
newWidth = 0; newWidth = 0;
properties.Width = newWidth; layerModel.Width = newWidth;
// Apply the right to left option // Apply the right to left option
if (LayerPropertyOptions == LayerPropertyOptions.RightToLeft) if (LayerPropertyOptions == LayerPropertyOptions.RightToLeft)
properties.X = properties.X + difference; layerModel.X = layerModel.X + difference;
} }
private void ApplyHeight(LayerPropertiesModel properties, float percentage) private void ApplyHeight(LayerModel layerModel, float percentage)
{ {
var newHeight = Math.Round(percentage*(float) properties.Height, 2); var newHeight = Math.Round(percentage*(float) layerModel.Height, 2);
var difference = properties.Height - newHeight; var difference = layerModel.Height - newHeight;
if (newHeight < 0) if (newHeight < 0)
newHeight = 0; newHeight = 0;
properties.Height = newHeight; layerModel.Height = newHeight;
if (LayerPropertyOptions == LayerPropertyOptions.Downwards) if (LayerPropertyOptions == LayerPropertyOptions.Downwards)
properties.Y = properties.Y + difference; layerModel.Y = layerModel.Y + difference;
} }
private void ApplyOpacity(LayerPropertiesModel properties, float percentage) private void ApplyOpacity(LayerModel layerModel, float percentage)
{ {
properties.Opacity = percentage*(float) properties.Opacity; layerModel.Opacity = percentage*(float) layerModel.Opacity;
if (properties.Opacity < 0.0) if (layerModel.Opacity < 0.0)
properties.Opacity = 0.0; layerModel.Opacity = 0.0;
if (properties.Opacity > 1.0) if (layerModel.Opacity > 1.0)
properties.Opacity = 1.0; layerModel.Opacity = 1.0;
// Apply the inverse/decrease option // Apply the inverse/decrease option
if (LayerPropertyOptions == LayerPropertyOptions.Decrease) if (LayerPropertyOptions == LayerPropertyOptions.Decrease)
properties.Opacity = 1.0 - properties.Opacity; layerModel.Opacity = 1.0 - layerModel.Opacity;
var brush = properties.Brush.Clone(); var brush = layerModel.Brush.Clone();
brush.Opacity = properties.Opacity; brush.Opacity = layerModel.Opacity;
properties.Brush = brush; layerModel.Brush = brush;
} }
private void ApplyPercentageOfProperty(IDataModel dataModel, LayerPropertiesModel properties) private void ApplyPercentageOfProperty(IDataModel dataModel, LayerModel layerModel)
{ {
var value = dataModel.GetPropValue<float>(PercentageProperty); var value = dataModel.GetPropValue<float>(PercentageProperty);
ApplyPercentageOf(dataModel, properties, value); ApplyPercentageOf(dataModel, layerModel, value);
} }
} }

View File

@ -1,6 +1,4 @@
using System; using System;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Artemis.Profiles.Layers.Models namespace Artemis.Profiles.Layers.Models
@ -20,6 +18,8 @@ namespace Artemis.Profiles.Layers.Models
[JsonIgnore] [JsonIgnore]
public bool MustDraw { get; set; } public bool MustDraw { get; set; }
public DateTime EventCanTriggerTime { get; set; }
/// <summary> /// <summary>
/// Resets the event's properties and triggers it /// Resets the event's properties and triggers it
/// </summary> /// </summary>
@ -42,11 +42,9 @@ namespace Artemis.Profiles.Layers.Models
CanTrigger = false; CanTrigger = false;
MustDraw = true; MustDraw = true;
EventTriggerTime = DateTime.Now; EventTriggerTime = DateTime.Now;
layer.Properties.AnimationProgress = 0.0; layer.AnimationProgress = 0.0;
} }
public DateTime EventCanTriggerTime { get; set; }
/// <summary> /// <summary>
/// Gets whether the event should stop /// Gets whether the event should stop

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using Artemis.Models.Interfaces; using Artemis.Models.Interfaces;
using Artemis.Profiles.Layers.Animations; using Artemis.Profiles.Layers.Animations;
@ -24,38 +25,9 @@ namespace Artemis.Profiles.Layers.Models
GifImage = new GifImage(model.GifFile); GifImage = new GifImage(model.GifFile);
} }
public ILayerType LayerType { get; set; }
public ILayerCondition LayerCondition { get; set; }
public ILayerAnimation LayerAnimation { get; set; }
public string Name { get; set; }
public int Order { get; set; }
public bool Enabled { get; set; }
public bool Expanded { get; set; }
public bool IsEvent { get; set; }
public LayerPropertiesModel Properties { get; set; }
public EventPropertiesModel EventProperties { get; set; }
public ChildItemCollection<LayerModel, LayerModel> Children { get; }
[JsonIgnore]
public LayerPropertiesModel AppliedProperties { get; set; }
[JsonIgnore] [JsonIgnore]
public ImageSource LayerImage => LayerType.DrawThumbnail(this); public ImageSource LayerImage => LayerType.DrawThumbnail(this);
[JsonIgnore]
public LayerModel Parent { get; internal set; }
[JsonIgnore]
public ProfileModel Profile { get; internal set; }
[JsonIgnore]
public GifImage GifImage { get; set; }
[JsonIgnore]
public DateTime LastRender { get; set; }
/// <summary> /// <summary>
/// Checks whether this layers conditions are met. /// Checks whether this layers conditions are met.
/// If they are met and this layer is an event, this also triggers that event. /// If they are met and this layer is an event, this also triggers that event.
@ -68,6 +40,12 @@ namespace Artemis.Profiles.Layers.Models
return Enabled && LayerCondition.ConditionsMet(this, dataModel); 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(IDataModel dataModel, bool preview, bool updateAnimations) public void Update(IDataModel dataModel, bool preview, bool updateAnimations)
{ {
LayerType.Update(this, dataModel, preview); LayerType.Update(this, dataModel, preview);
@ -76,11 +54,39 @@ namespace Artemis.Profiles.Layers.Models
LastRender = DateTime.Now; 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(IDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations) public void Draw(IDataModel dataModel, DrawingContext c, bool preview, bool updateAnimations)
{ {
LayerType.Draw(this, c); LayerType.Draw(this, c);
} }
/// <summary>
/// Tells the current layer type to setup the layer's LayerProperties
/// </summary>
public void SetupProperties() public void SetupProperties()
{ {
LayerType.SetupProperties(this); LayerType.SetupProperties(this);
@ -97,6 +103,9 @@ namespace Artemis.Profiles.Layers.Models
} }
} }
/// <summary>
/// Ensures all child layers have a unique order
/// </summary>
public void FixOrder() public void FixOrder()
{ {
Children.Sort(l => l.Order); Children.Sort(l => l.Order);
@ -163,18 +172,30 @@ namespace Artemis.Profiles.Layers.Models
}; };
} }
/// <summary>
/// Insert this layer before the given layer
/// </summary>
/// <param name="source"></param>
public void InsertBefore(LayerModel source) public void InsertBefore(LayerModel source)
{ {
source.Order = Order; source.Order = Order;
Insert(source); Insert(source);
} }
/// <summary>
/// Insert this layer after the given layer
/// </summary>
/// <param name="source"></param>
public void InsertAfter(LayerModel source) public void InsertAfter(LayerModel source)
{ {
source.Order = Order + 1; source.Order = Order + 1;
Insert(source); Insert(source);
} }
/// <summary>
/// Insert the layer as a sibling
/// </summary>
/// <param name="source"></param>
private void Insert(LayerModel source) private void Insert(LayerModel source)
{ {
if (Parent != null) if (Parent != null)
@ -197,11 +218,15 @@ namespace Artemis.Profiles.Layers.Models
} }
} }
public Rect LayerRect(int scale = 4)
{
return new Rect(X* scale, Y* scale, Width*scale, Height*scale);
}
/// <summary> /// <summary>
/// Generates a flat list containing all layers that must be rendered on the keyboard, /// 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 /// the first mouse layer to be rendered and the first headset layer to be rendered
/// </summary> /// </summary>
/// <typeparam name="T">The game data model to base the conditions on</typeparam>
/// <param name="dataModel">Instance of said game data model</param> /// <param name="dataModel">Instance of said game data model</param>
/// <param name="keyboardOnly">Whether or not to ignore anything but keyboards</param> /// <param name="keyboardOnly">Whether or not to ignore anything but keyboards</param>
/// <param name="ignoreConditions"></param> /// <param name="ignoreConditions"></param>
@ -227,6 +252,105 @@ namespace Artemis.Profiles.Layers.Models
return layers; return layers;
} }
public void SetupCondition()
{
if (IsEvent && !(LayerCondition is EventCondition))
LayerCondition = new EventCondition();
else if (!IsEvent && !(LayerCondition is DataModelCondition))
LayerCondition = new DataModelCondition();
}
#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 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 #region IChildItem<Parent> Members
LayerModel IChildItem<LayerModel>.Parent LayerModel IChildItem<LayerModel>.Parent
@ -242,13 +366,5 @@ namespace Artemis.Profiles.Layers.Models
} }
#endregion #endregion
public void SetupCondition()
{
if (IsEvent && !(LayerCondition is EventCondition))
LayerCondition = new EventCondition();
else if (!IsEvent && !(LayerCondition is DataModelCondition))
LayerCondition = new DataModelCondition();
}
} }
} }

View File

@ -38,9 +38,6 @@ namespace Artemis.Profiles.Layers.Models
public List<LayerConditionModel> Conditions { get; set; } = new List<LayerConditionModel>(); public List<LayerConditionModel> Conditions { get; set; } = new List<LayerConditionModel>();
public List<DynamicPropertiesModel> DynamicProperties { get; set; } = new List<DynamicPropertiesModel>(); public List<DynamicPropertiesModel> DynamicProperties { get; set; } = new List<DynamicPropertiesModel>();
[JsonIgnore]
public double AnimationProgress { get; set; }
[JsonConverter(typeof(BrushJsonConverter))] [JsonConverter(typeof(BrushJsonConverter))]
public Brush Brush public Brush Brush
{ {
@ -66,7 +63,7 @@ namespace Artemis.Profiles.Layers.Models
} }
} }
public Rect GetRect(int scale = 4) public Rect PropertiesRect(int scale = 4)
{ {
return new Rect(X*scale, Y*scale, Width*scale, Height*scale); return new Rect(X*scale, Y*scale, Width*scale, Height*scale);
} }

View File

@ -71,14 +71,14 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight
(BitmapSource.Create(width, height, 96, 96, ScreenCaptureManager.LastCapturePixelFormat, null, _lastData, stride), new Rect(0, 0, width, height))); (BitmapSource.Create(width, height, 96, 96, ScreenCaptureManager.LastCapturePixelFormat, null, _lastData, stride), new Rect(0, 0, width, height)));
} }
public void Draw(LayerModel layer, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
Rect rect = new Rect(layer.Properties.X * 4, Rect rect = new Rect(layerModel.Properties.X * 4,
layer.Properties.Y * 4, layerModel.Properties.Y * 4,
layer.Properties.Width * 4, layerModel.Properties.Width * 4,
layer.Properties.Height * 4); layerModel.Properties.Height * 4);
c.DrawRectangle(((AmbientLightPropertiesModel)layer.Properties).AmbientLightBrush, null, rect); c.DrawRectangle(((AmbientLightPropertiesModel)layerModel.Properties).AmbientLightBrush, null, rect);
} }
public ImageSource DrawThumbnail(LayerModel layer) public ImageSource DrawThumbnail(LayerModel layer)

View File

@ -72,7 +72,7 @@ namespace Artemis.Profiles.Layers.Types.Audio
return image; return image;
} }
public void Draw(LayerModel layer, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
lock (SpectrumData) lock (SpectrumData)
{ {
@ -84,10 +84,10 @@ namespace Artemis.Profiles.Layers.Types.Audio
var oldX = audioLayer.Properties.X; var oldX = audioLayer.Properties.X;
var oldY = audioLayer.Properties.Y; var oldY = audioLayer.Properties.Y;
audioLayer.Properties.Width = layer.Properties.Width; audioLayer.Properties.Width = layerModel.Properties.Width;
audioLayer.Properties.Height = layer.Properties.Height; audioLayer.Properties.Height = layerModel.Properties.Height;
audioLayer.Properties.X = layer.Properties.X; audioLayer.Properties.X = layerModel.Properties.X;
audioLayer.Properties.Y = layer.Properties.Y; audioLayer.Properties.Y = layerModel.Properties.Y;
audioLayer.LayerType.Draw(audioLayer, c); audioLayer.LayerType.Draw(audioLayer, c);
audioLayer.Properties.Width = oldWidth; audioLayer.Properties.Width = oldWidth;

View File

@ -29,7 +29,7 @@ namespace Artemis.Profiles.Layers.Types.Folder
return image; return image;
} }
public void Draw(LayerModel layer, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
} }

View File

@ -32,24 +32,21 @@ namespace Artemis.Profiles.Layers.Types.Generic
return image; return image;
} }
public void Draw(LayerModel layer, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
// If an animation is present, let it handle the drawing // If an animation is present, let it handle the drawing
if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation)) if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{ {
layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, c); layerModel.LayerAnimation.Draw(layerModel, c);
return; return;
} }
// Otherwise draw the rectangle with its applied dimensions and brush // Otherwise draw the rectangle with its applied dimensions and brush
var rect = new Rect(layer.AppliedProperties.X*4, var rect = layerModel.LayerRect();
layer.AppliedProperties.Y*4,
layer.AppliedProperties.Width*4,
layer.AppliedProperties.Height*4);
// Can't meddle with the original brush because it's frozen. // Can't meddle with the original brush because it's frozen.
var brush = layer.AppliedProperties.Brush.Clone(); var brush = layerModel.Brush.Clone();
brush.Opacity = layer.AppliedProperties.Opacity; brush.Opacity = layerModel.Opacity;
c.PushClip(new RectangleGeometry(rect)); c.PushClip(new RectangleGeometry(rect));
c.DrawRectangle(brush, null, rect); c.DrawRectangle(brush, null, rect);
@ -65,15 +62,14 @@ namespace Artemis.Profiles.Layers.Types.Generic
layerModel.Properties.Y = 0; layerModel.Properties.Y = 0;
layerModel.Properties.Contain = true; layerModel.Properties.Contain = true;
layerModel.AppliedProperties = new SimplePropertiesModel(layerModel.Properties); layerModel.ApplyProperties(false);
if (isPreview || dataModel == null) if (isPreview || dataModel == null)
return; return;
// If not previewing, apply dynamic properties according to datamodel // If not previewing, apply dynamic properties according to datamodel
var props = (SimplePropertiesModel) layerModel.AppliedProperties; foreach (var dynamicProperty in layerModel.Properties.DynamicProperties)
foreach (var dynamicProperty in props.DynamicProperties) dynamicProperty.ApplyProperty(dataModel, layerModel);
dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties);
} }
public void SetupProperties(LayerModel layerModel) public void SetupProperties(LayerModel layerModel)

View File

@ -30,24 +30,21 @@ namespace Artemis.Profiles.Layers.Types.Headset
return image; return image;
} }
public void Draw(LayerModel layer, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
// If an animation is present, let it handle the drawing // If an animation is present, let it handle the drawing
if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation)) if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{ {
layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, c); layerModel.LayerAnimation.Draw(layerModel, c);
return; return;
} }
// Otherwise draw the rectangle with its applied dimensions and brush // Otherwise draw the rectangle with its applied dimensions and brush
var rect = new Rect(layer.AppliedProperties.X*4, var rect = layerModel.LayerRect();
layer.AppliedProperties.Y*4,
layer.AppliedProperties.Width*4,
layer.AppliedProperties.Height*4);
// Can't meddle with the original brush because it's frozen. // Can't meddle with the original brush because it's frozen.
var brush = layer.AppliedProperties.Brush.Clone(); var brush = layerModel.Brush.Clone();
brush.Opacity = layer.AppliedProperties.Opacity; brush.Opacity = layerModel.Opacity;
c.PushClip(new RectangleGeometry(rect)); c.PushClip(new RectangleGeometry(rect));
c.DrawRectangle(brush, null, rect); c.DrawRectangle(brush, null, rect);
@ -63,15 +60,14 @@ namespace Artemis.Profiles.Layers.Types.Headset
layerModel.Properties.Y = 0; layerModel.Properties.Y = 0;
layerModel.Properties.Contain = true; layerModel.Properties.Contain = true;
layerModel.AppliedProperties = new SimplePropertiesModel(layerModel.Properties); layerModel.ApplyProperties(true);
if (isPreview || dataModel == null) if (isPreview || dataModel == null)
return; return;
// If not previewing, apply dynamic properties according to datamodel // If not previewing, apply dynamic properties according to datamodel
var props = (SimplePropertiesModel) layerModel.AppliedProperties; foreach (var dynamicProperty in layerModel.Properties.DynamicProperties)
foreach (var dynamicProperty in props.DynamicProperties) dynamicProperty.ApplyProperty(dataModel, layerModel);
dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties);
} }
public void SetupProperties(LayerModel layerModel) public void SetupProperties(LayerModel layerModel)

View File

@ -49,7 +49,7 @@ namespace Artemis.Profiles.Layers.Types.KeyPress
return image; return image;
} }
public void Draw(LayerModel layer, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
lock (_keyPressLayers) lock (_keyPressLayers)
{ {
@ -67,7 +67,7 @@ namespace Artemis.Profiles.Layers.Types.KeyPress
layerModel.Properties.Y = 0; layerModel.Properties.Y = 0;
layerModel.Properties.Contain = true; layerModel.Properties.Contain = true;
layerModel.AppliedProperties = new KeyPressPropertiesModel(layerModel.Properties); layerModel.ApplyProperties(true);
_layerModel = layerModel; _layerModel = layerModel;

View File

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Windows;
using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using Artemis.Models.Interfaces; using Artemis.Models.Interfaces;
using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Abstract;
@ -34,32 +33,26 @@ namespace Artemis.Profiles.Layers.Types.Keyboard
return image; return image;
} }
public void Draw(LayerModel layer, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
// If an animation is present, let it handle the drawing // If an animation is present, let it handle the drawing
if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation)) if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{ {
layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, c); layerModel.LayerAnimation.Draw(layerModel, c);
return; return;
} }
// Otherwise draw the rectangle with its layer.AppliedProperties dimensions and brush // Otherwise draw the rectangle with its layer.AppliedProperties dimensions and brush
var rect = layer.AppliedProperties.Contain var rect = layerModel.Properties.Contain
? new Rect(layer.AppliedProperties.X*4, ? layerModel.LayerRect()
layer.AppliedProperties.Y*4, : new Rect(layerModel.Properties.X*4, layerModel.Properties.Y*4,
layer.AppliedProperties.Width*4, layerModel.Properties.Width*4, layerModel.Properties.Height*4);
layer.AppliedProperties.Height*4)
: new Rect(layer.Properties.X*4,
layer.Properties.Y*4,
layer.Properties.Width*4,
layer.Properties.Height*4);
var clip = new Rect(layer.AppliedProperties.X*4, layer.AppliedProperties.Y*4, var clip = layerModel.LayerRect();
layer.AppliedProperties.Width*4, layer.AppliedProperties.Height*4);
// Can't meddle with the original brush because it's frozen. // Can't meddle with the original brush because it's frozen.
var brush = layer.AppliedProperties.Brush.Clone(); var brush = layerModel.Brush.Clone();
brush.Opacity = layer.AppliedProperties.Opacity; brush.Opacity = layerModel.Opacity;
c.PushClip(new RectangleGeometry(clip)); c.PushClip(new RectangleGeometry(clip));
c.DrawRectangle(brush, null, rect); c.DrawRectangle(brush, null, rect);
@ -68,14 +61,13 @@ namespace Artemis.Profiles.Layers.Types.Keyboard
public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false)
{ {
layerModel.AppliedProperties = new KeyboardPropertiesModel(layerModel.Properties); layerModel.ApplyProperties(true);
if (isPreview || dataModel == null) if (isPreview || dataModel == null)
return; return;
// If not previewing, apply dynamic properties according to datamodel // If not previewing, apply dynamic properties according to datamodel
var keyboardProps = (KeyboardPropertiesModel) layerModel.AppliedProperties; foreach (var dynamicProperty in layerModel.Properties.DynamicProperties)
foreach (var dynamicProperty in keyboardProps.DynamicProperties) dynamicProperty.ApplyProperty(dataModel, layerModel);
dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties);
} }
public void SetupProperties(LayerModel layerModel) public void SetupProperties(LayerModel layerModel)

View File

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Drawing;
using System.Drawing;
using System.IO; using System.IO;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
@ -31,28 +30,25 @@ namespace Artemis.Profiles.Layers.Types.KeyboardGif
return image; return image;
} }
public void Draw(LayerModel layer, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
var props = (KeyboardPropertiesModel) layer.Properties; var props = (KeyboardPropertiesModel) layerModel.Properties;
if (string.IsNullOrEmpty(props.GifFile)) if (string.IsNullOrEmpty(props.GifFile))
return; return;
if (!File.Exists(props.GifFile)) if (!File.Exists(props.GifFile))
return; return;
// Only reconstruct GifImage if the underlying source has changed // Only reconstruct GifImage if the underlying source has changed
if (layer.GifImage == null) if (layerModel.GifImage == null)
layer.GifImage = new GifImage(props.GifFile); layerModel.GifImage = new GifImage(props.GifFile);
if (layer.GifImage.Source != props.GifFile) if (layerModel.GifImage.Source != props.GifFile)
layer.GifImage = new GifImage(props.GifFile); layerModel.GifImage = new GifImage(props.GifFile);
var rect = new Rect(layer.AppliedProperties.X*4, var rect = new Rect(layerModel.X*4, layerModel.Y*4, layerModel.Width*4, layerModel.Height*4);
layer.AppliedProperties.Y*4,
layer.AppliedProperties.Width*4,
layer.AppliedProperties.Height*4);
lock (layer.GifImage) lock (layerModel.GifImage)
{ {
var draw = layer.GifImage.GetNextFrame(); var draw = layerModel.GifImage.GetNextFrame();
using (var drawBitmap = new Bitmap(draw)) using (var drawBitmap = new Bitmap(draw))
{ {
c.DrawImage(ImageUtilities.BitmapToBitmapImage(drawBitmap), rect); c.DrawImage(ImageUtilities.BitmapToBitmapImage(drawBitmap), rect);
@ -62,14 +58,13 @@ namespace Artemis.Profiles.Layers.Types.KeyboardGif
public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false) public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false)
{ {
layerModel.AppliedProperties = new KeyboardPropertiesModel(layerModel.Properties); layerModel.ApplyProperties(true);
if (isPreview) if (isPreview)
return; return;
// If not previewing, apply dynamic properties according to datamodel // If not previewing, apply dynamic properties according to datamodel
var keyboardProps = (KeyboardPropertiesModel) layerModel.AppliedProperties; foreach (var dynamicProperty in layerModel.Properties.DynamicProperties)
foreach (var dynamicProperty in keyboardProps.DynamicProperties) dynamicProperty.ApplyProperty(dataModel, layerModel);
dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties);
} }
public void SetupProperties(LayerModel layerModel) public void SetupProperties(LayerModel layerModel)

View File

@ -32,24 +32,21 @@ namespace Artemis.Profiles.Layers.Types.Mouse
return image; return image;
} }
public void Draw(LayerModel layer, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
// If an animation is present, let it handle the drawing // If an animation is present, let it handle the drawing
if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation)) if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{ {
layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, c); layerModel.LayerAnimation.Draw(layerModel, c);
return; return;
} }
// Otherwise draw the rectangle with its applied dimensions and brush // Otherwise draw the rectangle with its applied dimensions and brush
var rect = new Rect(layer.AppliedProperties.X*4, var rect = layerModel.LayerRect();
layer.AppliedProperties.Y*4,
layer.AppliedProperties.Width*4,
layer.AppliedProperties.Height*4);
// Can't meddle with the original brush because it's frozen. // Can't meddle with the original brush because it's frozen.
var brush = layer.AppliedProperties.Brush.Clone(); var brush = layerModel.Brush.Clone();
brush.Opacity = layer.AppliedProperties.Opacity; brush.Opacity = layerModel.Opacity;
c.PushClip(new RectangleGeometry(rect)); c.PushClip(new RectangleGeometry(rect));
c.DrawRectangle(brush, null, rect); c.DrawRectangle(brush, null, rect);
@ -65,15 +62,14 @@ namespace Artemis.Profiles.Layers.Types.Mouse
layerModel.Properties.Y = 0; layerModel.Properties.Y = 0;
layerModel.Properties.Contain = true; layerModel.Properties.Contain = true;
layerModel.AppliedProperties = new SimplePropertiesModel(layerModel.Properties); layerModel.ApplyProperties(true);
if (isPreview || dataModel == null) if (isPreview || dataModel == null)
return; return;
// If not previewing, apply dynamic properties according to datamodel // If not previewing, apply dynamic properties according to datamodel
var props = (SimplePropertiesModel) layerModel.AppliedProperties; foreach (var dynamicProperty in layerModel.Properties.DynamicProperties)
foreach (var dynamicProperty in props.DynamicProperties) dynamicProperty.ApplyProperty(dataModel, layerModel);
dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties);
} }
public void SetupProperties(LayerModel layerModel) public void SetupProperties(LayerModel layerModel)

View File

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Linq;
using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using Artemis.Models.Interfaces; using Artemis.Models.Interfaces;
@ -30,24 +29,21 @@ namespace Artemis.Profiles.Layers.Types.Mousemat
return image; return image;
} }
public void Draw(LayerModel layer, DrawingContext c) public void Draw(LayerModel layerModel, DrawingContext c)
{ {
// If an animation is present, let it handle the drawing // If an animation is present, let it handle the drawing
if (layer.LayerAnimation != null && !(layer.LayerAnimation is NoneAnimation)) if (layerModel.LayerAnimation != null && !(layerModel.LayerAnimation is NoneAnimation))
{ {
layer.LayerAnimation.Draw(layer.Properties, layer.AppliedProperties, c); layerModel.LayerAnimation.Draw(layerModel, c);
return; return;
} }
// Otherwise draw the rectangle with its applied dimensions and brush // Otherwise draw the rectangle with its applied dimensions and brush
var rect = new Rect(layer.AppliedProperties.X*4, var rect = layerModel.LayerRect();
layer.AppliedProperties.Y*4,
layer.AppliedProperties.Width*4,
layer.AppliedProperties.Height*4);
// Can't meddle with the original brush because it's frozen. // Can't meddle with the original brush because it's frozen.
var brush = layer.AppliedProperties.Brush.Clone(); var brush = layerModel.Brush.Clone();
brush.Opacity = layer.AppliedProperties.Opacity; brush.Opacity = layerModel.Opacity;
c.PushClip(new RectangleGeometry(rect)); c.PushClip(new RectangleGeometry(rect));
c.DrawRectangle(brush, null, rect); c.DrawRectangle(brush, null, rect);
@ -63,15 +59,14 @@ namespace Artemis.Profiles.Layers.Types.Mousemat
layerModel.Properties.Y = 0; layerModel.Properties.Y = 0;
layerModel.Properties.Contain = true; layerModel.Properties.Contain = true;
layerModel.AppliedProperties = new SimplePropertiesModel(layerModel.Properties); layerModel.ApplyProperties(true);
if (isPreview || dataModel == null) if (isPreview || dataModel == null)
return; return;
// If not previewing, apply dynamic properties according to datamodel // If not previewing, apply dynamic properties according to datamodel
var props = (SimplePropertiesModel) layerModel.AppliedProperties; foreach (var dynamicProperty in layerModel.Properties.DynamicProperties)
foreach (var dynamicProperty in props.DynamicProperties) dynamicProperty.ApplyProperty(dataModel, layerModel);
dynamicProperty.ApplyProperty(dataModel, layerModel.AppliedProperties);
} }
public void SetupProperties(LayerModel layerModel) public void SetupProperties(LayerModel layerModel)

View File

@ -19,8 +19,9 @@ namespace Artemis.Profiles.Lua
public LuaLayerWrapper(LayerModel layerModel) public LuaLayerWrapper(LayerModel layerModel)
{ {
_layerModel = layerModel; _layerModel = layerModel;
SavedProperties = new LuaLayerProperties(layerModel);
// Triger an update to fill up the AppliedProperties // Triger an update to fill up the Properties
_layerModel.Update(new ProfilePreviewDataModel(), true, false); _layerModel.Update(new ProfilePreviewDataModel(), true, false);
} }
@ -63,73 +64,120 @@ namespace Artemis.Profiles.Lua
#endregion #endregion
#region Advanced layer properties #region Render layer properties
public double X public double X
{ {
get { return _layerModel.AppliedProperties.X; } get { return _layerModel.X; }
set { _layerModel.AppliedProperties.X = value; } set { _layerModel.X = value; }
} }
public double Y public double Y
{ {
get { return _layerModel.AppliedProperties.Y; } get { return _layerModel.Y; }
set { _layerModel.AppliedProperties.Y = value; } set { _layerModel.Y = value; }
} }
public double Width public double Width
{ {
get { return _layerModel.AppliedProperties.Width; } get { return _layerModel.Width; }
set { _layerModel.AppliedProperties.Width = value; } set { _layerModel.Width = value; }
} }
public double Height public double Height
{ {
get { return _layerModel.AppliedProperties.Height; } get { return _layerModel.Height; }
set { _layerModel.AppliedProperties.Height = value; } set { _layerModel.Height = value; }
}
public bool Contain
{
get { return _layerModel.AppliedProperties.Contain; }
set { _layerModel.AppliedProperties.Contain = value; }
} }
public double Opacity public double Opacity
{ {
get { return _layerModel.AppliedProperties.Opacity; } get { return _layerModel.Opacity; }
set { _layerModel.AppliedProperties.Opacity = value; } set { _layerModel.Opacity = value; }
}
public double AnimationSpeed
{
get { return _layerModel.AppliedProperties.AnimationSpeed; }
set { _layerModel.AppliedProperties.AnimationSpeed = value; }
} }
public double AnimationProgress public double AnimationProgress
{ {
get { return _layerModel.AppliedProperties.AnimationProgress; } get { return _layerModel.AnimationProgress; }
set { _layerModel.AppliedProperties.AnimationProgress = value; } set { _layerModel.AnimationProgress = value; }
} }
public string BrushType => _layerModel.AppliedProperties.Brush?.GetType().Name; #endregion
#region Advanced layer properties
public LuaLayerProperties SavedProperties { get; set; }
public string BrushType => _layerModel.Properties.Brush?.GetType().Name;
public LuaBrush Brush public LuaBrush Brush
{ {
get get
{ {
if (_layerModel.AppliedProperties.Brush is SolidColorBrush) if (_layerModel.Properties.Brush is SolidColorBrush)
return new LuaSolidColorBrush(_layerModel.AppliedProperties.Brush); return new LuaSolidColorBrush(_layerModel.Properties.Brush);
if (_layerModel.AppliedProperties.Brush is LinearGradientBrush) if (_layerModel.Properties.Brush is LinearGradientBrush)
return new LuaLinearGradientBrush(_layerModel.AppliedProperties.Brush); return new LuaLinearGradientBrush(_layerModel.Properties.Brush);
if (_layerModel.AppliedProperties.Brush is RadialGradientBrush) if (_layerModel.Properties.Brush is RadialGradientBrush)
return new LuaRadialGradientBrush(_layerModel.AppliedProperties.Brush); return new LuaRadialGradientBrush(_layerModel.Properties.Brush);
return null; return null;
} }
set { _layerModel.AppliedProperties.Brush = value?.Brush; } set { _layerModel.Properties.Brush = value?.Brush; }
} }
#endregion #endregion
} }
[MoonSharpUserData]
public class LuaLayerProperties
{
private readonly LayerModel _layerModel;
public LuaLayerProperties(LayerModel layerModel)
{
_layerModel = layerModel;
}
public double X
{
get { return _layerModel.Properties.X; }
set { _layerModel.Properties.X = value; }
}
public double Y
{
get { return _layerModel.Properties.Y; }
set { _layerModel.Properties.Y = value; }
}
public double Width
{
get { return _layerModel.Properties.Width; }
set { _layerModel.Properties.Width = value; }
}
public double Height
{
get { return _layerModel.Properties.Height; }
set { _layerModel.Properties.Height = value; }
}
public bool Contain
{
get { return _layerModel.Properties.Contain; }
set { _layerModel.Properties.Contain = value; }
}
public double Opacity
{
get { return _layerModel.Properties.Opacity; }
set { _layerModel.Properties.Opacity = value; }
}
public double AnimationSpeed
{
get { return _layerModel.Properties.AnimationSpeed; }
set { _layerModel.Properties.AnimationSpeed = value; }
}
}
} }

View File

@ -97,7 +97,7 @@ namespace Artemis.ViewModels.Profiles
// Draw the selection outline and resize indicator // Draw the selection outline and resize indicator
if (SelectedLayer != null && SelectedLayer.MustDraw()) if (SelectedLayer != null && SelectedLayer.MustDraw())
{ {
var layerRect = SelectedLayer.Properties.GetRect(); var layerRect = SelectedLayer.Properties.PropertiesRect();
// Deflate the rect so that the border is drawn on the inside // Deflate the rect so that the border is drawn on the inside
layerRect.Inflate(-0.2, -0.2); layerRect.Inflate(-0.2, -0.2);
@ -227,7 +227,7 @@ namespace Artemis.ViewModels.Profiles
var y = pos.Y/((double) keyboard.PreviewSettings.Height/keyboard.Height); var y = pos.Y/((double) keyboard.PreviewSettings.Height/keyboard.Height);
var hoverLayer = GetLayers().Where(l => l.MustDraw()) var hoverLayer = GetLayers().Where(l => l.MustDraw())
.FirstOrDefault(l => l.Properties.GetRect(1).Contains(x, y)); .FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(x, y));
if (hoverLayer != null) if (hoverLayer != null)
SelectedLayer = hoverLayer; SelectedLayer = hoverLayer;
@ -247,7 +247,7 @@ namespace Artemis.ViewModels.Profiles
var x = pos.X/((double) keyboard.PreviewSettings.Width/keyboard.Width); var x = pos.X/((double) keyboard.PreviewSettings.Width/keyboard.Width);
var y = pos.Y/((double) keyboard.PreviewSettings.Height/keyboard.Height); var y = pos.Y/((double) keyboard.PreviewSettings.Height/keyboard.Height);
var hoverLayer = GetLayers().Where(l => l.MustDraw()) var hoverLayer = GetLayers().Where(l => l.MustDraw())
.FirstOrDefault(l => l.Properties.GetRect(1).Contains(x, y)); .FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(x, y));
HandleDragging(e, x, y, hoverLayer); HandleDragging(e, x, y, hoverLayer);
@ -260,7 +260,7 @@ namespace Artemis.ViewModels.Profiles
// Turn the mouse pointer into a hand if hovering over an active layer // Turn the mouse pointer into a hand if hovering over an active layer
if (hoverLayer == SelectedLayer) if (hoverLayer == SelectedLayer)
{ {
var rect = hoverLayer.Properties.GetRect(1); var rect = hoverLayer.Properties.PropertiesRect(1);
KeyboardPreviewCursor = KeyboardPreviewCursor =
Math.Sqrt(Math.Pow(x - rect.BottomRight.X, 2) + Math.Pow(y - rect.BottomRight.Y, 2)) < 0.6 Math.Sqrt(Math.Pow(x - rect.BottomRight.X, 2) + Math.Pow(y - rect.BottomRight.Y, 2)) < 0.6
? Cursors.SizeNWSE ? Cursors.SizeNWSE
@ -305,7 +305,7 @@ namespace Artemis.ViewModels.Profiles
// Setup the dragging state on mouse press // Setup the dragging state on mouse press
if (_draggingLayerOffset == null && hoverLayer != null && e.LeftButton == MouseButtonState.Pressed) if (_draggingLayerOffset == null && hoverLayer != null && e.LeftButton == MouseButtonState.Pressed)
{ {
var layerRect = hoverLayer.Properties.GetRect(1); var layerRect = hoverLayer.Properties.PropertiesRect(1);
_draggingLayerOffset = new Point(x - SelectedLayer.Properties.X, y - SelectedLayer.Properties.Y); _draggingLayerOffset = new Point(x - SelectedLayer.Properties.X, y - SelectedLayer.Properties.Y);
_draggingLayer = hoverLayer; _draggingLayer = hoverLayer;