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

Layers - Finished effects on layers, groups still missing

Effects - Added filter effect with different SkiaSharp image filters
This commit is contained in:
SpoinkyNL 2020-06-16 00:25:04 +02:00
parent 58a964b872
commit a62d5544cf
18 changed files with 264 additions and 55 deletions

View File

@ -166,6 +166,7 @@ namespace Artemis.Core.Models.Profile
{ {
var layerEffectEntity = new LayerEffectEntity var layerEffectEntity = new LayerEffectEntity
{ {
Id = layerEffect.EntityId,
PluginGuid = layerEffect.PluginInfo.Guid, PluginGuid = layerEffect.PluginInfo.Guid,
EffectType = layerEffect.GetType().Name, EffectType = layerEffect.GetType().Name,
Name = layerEffect.Name, Name = layerEffect.Name,
@ -524,7 +525,7 @@ namespace Artemis.Core.Models.Profile
var index = 0; var index = 0;
foreach (var baseLayerEffect in LayerEffects.OrderBy(e => e.Order)) foreach (var baseLayerEffect in LayerEffects.OrderBy(e => e.Order))
{ {
baseLayerEffect.UpdateOrder(index + 1); baseLayerEffect.Order = Order = index + 1;
index++; index++;
} }

View File

@ -78,6 +78,11 @@ namespace Artemis.Core.Models.Profile
} }
} }
/// <summary>
/// Gets or sets whether the group is expanded in the UI
/// </summary>
public bool IsExpanded { get; set; }
/// <summary> /// <summary>
/// A list of all layer properties in this group /// A list of all layer properties in this group
/// </summary> /// </summary>
@ -107,21 +112,6 @@ namespace Artemis.Core.Models.Profile
return _allLayerProperties; return _allLayerProperties;
} }
public void UpdateOrder(int oldOrder)
{
// Expanded state is tied to the path so save it before changing the path
var expanded = Layer.IsPropertyGroupExpanded(this);
Layer.SetPropertyGroupExpanded(this, false);
Path = Path.Replace($"LayerEffect.{oldOrder}.", $"LayerEffect.{LayerEffect.Order}.");
// Restore the expanded state with the new path
Layer.SetPropertyGroupExpanded(this, expanded);
// Update children
foreach (var layerPropertyGroup in LayerPropertyGroups)
layerPropertyGroup.UpdateOrder(oldOrder);
}
/// <summary> /// <summary>
/// Called before properties are fully initialized to allow you to populate /// Called before properties are fully initialized to allow you to populate
/// <see cref="LayerProperty{T}.DefaultValue" /> on the properties you want /// <see cref="LayerProperty{T}.DefaultValue" /> on the properties you want

View File

@ -12,6 +12,11 @@ namespace Artemis.Core.Plugins.LayerEffect.Abstract
/// </summary> /// </summary>
public abstract class BaseLayerEffect : PropertyChangedBase, IDisposable public abstract class BaseLayerEffect : PropertyChangedBase, IDisposable
{ {
/// <summary>
/// Gets the unique ID of this effect
/// </summary>
public Guid EntityId { get; internal set; }
/// <summary> /// <summary>
/// Gets the layer this effect is applied to /// Gets the layer this effect is applied to
/// </summary> /// </summary>
@ -36,7 +41,7 @@ namespace Artemis.Core.Plugins.LayerEffect.Abstract
/// <summary> /// <summary>
/// Gets the order in which this effect appears in the update loop and editor /// Gets the order in which this effect appears in the update loop and editor
/// </summary> /// </summary>
public int Order { get; internal set; } public int Order { get; set; }
/// <summary> /// <summary>
/// Gets the descriptor of this effect /// Gets the descriptor of this effect
@ -53,7 +58,7 @@ namespace Artemis.Core.Plugins.LayerEffect.Abstract
/// </summary> /// </summary>
public virtual LayerPropertyGroup BaseProperties => null; public virtual LayerPropertyGroup BaseProperties => null;
internal string PropertyRootPath => $"LayerEffect.{Order}.{GetType().Name}."; internal string PropertyRootPath => $"LayerEffect.{EntityId}.{GetType().Name}.";
public void Dispose() public void Dispose()
{ {
@ -85,17 +90,7 @@ namespace Artemis.Core.Plugins.LayerEffect.Abstract
/// Called after the layer of folder has been rendered /// Called after the layer of folder has been rendered
/// </summary> /// </summary>
public abstract void PostProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint); public abstract void PostProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint);
public void UpdateOrder(int newOrder)
{
if (newOrder == Order)
return;
var oldOrder = Order;
Order = newOrder;
BaseProperties.UpdateOrder(oldOrder);
}
internal void InternalPreProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint) internal void InternalPreProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint)
{ {
// Move the canvas to the top-left of the render path // Move the canvas to the top-left of the render path

View File

@ -17,6 +17,12 @@ namespace Artemis.Core.Services.Interfaces
/// <returns></returns> /// <returns></returns>
Layer CreateLayer(Profile profile, ProfileElement parent, string name); Layer CreateLayer(Profile profile, ProfileElement parent, string name);
/// <summary>
/// Removes the currently active layer brush from the <see cref="Layer" /> and deletes any settings
/// </summary>
/// <param name="layer">The layer to remove the active brush from</param>
void RemoveLayerBrush(Layer layer);
/// <summary> /// <summary>
/// Instantiates and adds the <see cref="BaseLayerBrush" /> described by the provided /// Instantiates and adds the <see cref="BaseLayerBrush" /> described by the provided
/// <see cref="LayerBrushDescriptor" /> /// <see cref="LayerBrushDescriptor" />

View File

@ -1,4 +1,5 @@
using System.Linq; using System;
using System.Linq;
using Artemis.Core.Exceptions; using Artemis.Core.Exceptions;
using Artemis.Core.Models.Profile; using Artemis.Core.Models.Profile;
using Artemis.Core.Plugins.Abstract; using Artemis.Core.Plugins.Abstract;
@ -40,6 +41,12 @@ namespace Artemis.Core.Services
return layer; return layer;
} }
public void RemoveLayerBrush(Layer layer)
{
layer.RemoveLayerBrush();
layer.OnLayerBrushUpdated();
}
public BaseLayerBrush InstantiateLayerBrush(Layer layer) public BaseLayerBrush InstantiateLayerBrush(Layer layer)
{ {
if (layer.LayerBrush != null) if (layer.LayerBrush != null)
@ -87,6 +94,7 @@ namespace Artemis.Core.Services
continue; continue;
var effect = (BaseLayerEffect) _kernel.Get(descriptor.LayerEffectType); var effect = (BaseLayerEffect) _kernel.Get(descriptor.LayerEffectType);
effect.EntityId = layerEntityLayerEffect.Id;
effect.Layer = layer; effect.Layer = layer;
effect.Order = layerEntityLayerEffect.Order; effect.Order = layerEntityLayerEffect.Order;
effect.Name = layerEntityLayerEffect.Name; effect.Name = layerEntityLayerEffect.Name;
@ -104,6 +112,7 @@ namespace Artemis.Core.Services
public BaseLayerEffect AddLayerEffect(Layer layer, LayerEffectDescriptor layerEffectDescriptor) public BaseLayerEffect AddLayerEffect(Layer layer, LayerEffectDescriptor layerEffectDescriptor)
{ {
var effect = (BaseLayerEffect) _kernel.Get(layerEffectDescriptor.LayerEffectType); var effect = (BaseLayerEffect) _kernel.Get(layerEffectDescriptor.LayerEffectType);
effect.EntityId = Guid.NewGuid();
effect.Layer = layer; effect.Layer = layer;
effect.Order = layer.LayerEffects.Count + 1; effect.Order = layer.LayerEffects.Count + 1;
effect.Descriptor = layerEffectDescriptor; effect.Descriptor = layerEffectDescriptor;
@ -113,7 +122,7 @@ namespace Artemis.Core.Services
layer.AddLayerEffect(effect); layer.AddLayerEffect(effect);
_logger.Debug("Added layer effect with root path {rootPath}", effect.PropertyRootPath); _logger.Debug("Added layer effect with root path {rootPath}", effect.PropertyRootPath);
layer.OnLayerEffectsUpdated(); layer.OnLayerEffectsUpdated();
return effect; return effect;
} }

View File

@ -4,6 +4,7 @@ namespace Artemis.Storage.Entities.Profile
{ {
public class LayerEffectEntity public class LayerEffectEntity
{ {
public Guid Id { get; set; }
public Guid PluginGuid { get; set; } public Guid PluginGuid { get; set; }
public string EffectType { get; set; } public string EffectType { get; set; }
public string Name { get; set; } public string Name { get; set; }

View File

@ -80,6 +80,8 @@ namespace Artemis.UI.Shared.Controls
private void InputMouseDown(object sender, MouseButtonEventArgs e) private void InputMouseDown(object sender, MouseButtonEventArgs e)
{ {
e.Handled = true;
_startValue = Value; _startValue = Value;
((IInputElement) sender).CaptureMouse(); ((IInputElement) sender).CaptureMouse();
_mouseDragStartPoint = e.GetPosition((IInputElement) sender); _mouseDragStartPoint = e.GetPosition((IInputElement) sender);
@ -87,6 +89,8 @@ namespace Artemis.UI.Shared.Controls
private void InputMouseUp(object sender, MouseButtonEventArgs e) private void InputMouseUp(object sender, MouseButtonEventArgs e)
{ {
e.Handled = true;
var position = e.GetPosition((IInputElement) sender); var position = e.GetPosition((IInputElement) sender);
if (position == _mouseDragStartPoint) if (position == _mouseDragStartPoint)
DisplayInput(); DisplayInput();
@ -104,6 +108,8 @@ namespace Artemis.UI.Shared.Controls
if (e.LeftButton != MouseButtonState.Pressed) if (e.LeftButton != MouseButtonState.Pressed)
return; return;
e.Handled = true;
if (!_calledDragStarted) if (!_calledDragStarted)
{ {
OnDragStarted(); OnDragStarted();

View File

@ -28,6 +28,11 @@ namespace Artemis.UI.Shared.Utilities
return Enum.GetValues(t).Cast<Enum>().Select(e => new ValueDescription {Value = e, Description = e.Humanize()}).ToList(); return Enum.GetValues(t).Cast<Enum>().Select(e => new ValueDescription {Value = e, Description = e.Humanize()}).ToList();
} }
public static string HumanizeValue(Enum value)
{
return value.Humanize();
}
} }
public class ValueDescription public class ValueDescription

View File

@ -52,6 +52,7 @@ namespace Artemis.UI.PropertyInput
protected override void OnInputValueApplied() protected override void OnInputValueApplied()
{ {
_layerService.RemoveLayerBrush(LayerProperty.Layer);
_layerService.InstantiateLayerBrush(LayerProperty.Layer); _layerService.InstantiateLayerBrush(LayerProperty.Layer);
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
@ -14,13 +15,17 @@ using Artemis.UI.Ninject.Factories;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.LayerEffects; using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.LayerEffects;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline; using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Timeline;
using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree; using Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree;
using Artemis.UI.Screens.Module.ProfileEditor.ProfileTree;
using Artemis.UI.Screens.Module.ProfileEditor.ProfileTree.TreeItem;
using Artemis.UI.Shared.Events; using Artemis.UI.Shared.Events;
using Artemis.UI.Shared.Services.Interfaces; using Artemis.UI.Shared.Services.Interfaces;
using GongSolutions.Wpf.DragDrop;
using Stylet; using Stylet;
using static Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.LayerPropertyGroupViewModel.ViewModelType;
namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
{ {
public class LayerPropertiesViewModel : ProfileEditorPanelViewModel public class LayerPropertiesViewModel : ProfileEditorPanelViewModel, IDropTarget
{ {
private readonly ILayerPropertyVmFactory _layerPropertyVmFactory; private readonly ILayerPropertyVmFactory _layerPropertyVmFactory;
private LayerPropertyGroupViewModel _brushPropertyGroup; private LayerPropertyGroupViewModel _brushPropertyGroup;
@ -215,6 +220,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
LayerPropertyGroups.Add(_brushPropertyGroup); LayerPropertyGroups.Add(_brushPropertyGroup);
} }
SortProperties();
TimelineViewModel.UpdateKeyframes(); TimelineViewModel.UpdateKeyframes();
} }
@ -244,9 +250,100 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
LayerPropertyGroups.Add(_layerPropertyVmFactory.LayerPropertyGroupViewModel(layerEffect.BaseProperties, brushDescription)); LayerPropertyGroups.Add(_layerPropertyVmFactory.LayerPropertyGroupViewModel(layerEffect.BaseProperties, brushDescription));
} }
SortProperties();
TimelineViewModel.UpdateKeyframes(); TimelineViewModel.UpdateKeyframes();
} }
private void SortProperties()
{
// Get all non-effect properties
var nonEffectProperties = LayerPropertyGroups.Where(l => l.GroupType != LayerEffectRoot).ToList();
// Order the effects
var effectProperties = LayerPropertyGroups.Where(l => l.GroupType == LayerEffectRoot).OrderBy(l => l.LayerPropertyGroup.LayerEffect.Order).ToList();
// Put the non-effect properties in front
for (var index = 0; index < nonEffectProperties.Count; index++)
{
var layerPropertyGroupViewModel = nonEffectProperties[index];
LayerPropertyGroups.Move(LayerPropertyGroups.IndexOf(layerPropertyGroupViewModel), index);
}
// Put the effect properties after, sorted by their order
for (var index = 0; index < effectProperties.Count; index++)
{
var layerPropertyGroupViewModel = effectProperties[index];
LayerPropertyGroups.Move(LayerPropertyGroups.IndexOf(layerPropertyGroupViewModel), index + nonEffectProperties.Count);
}
}
#endregion
#region Drag and drop
public void DragOver(IDropInfo dropInfo)
{
// Workaround for https://github.com/punker76/gong-wpf-dragdrop/issues/344
// Luckily we know the index can never be 1 so it's an easy enough fix
if (dropInfo.InsertIndex == 1)
return;
var source = dropInfo.Data as LayerPropertyGroupViewModel;
var target = dropInfo.TargetItem as LayerPropertyGroupViewModel;
if (source == target || target?.GroupType != LayerEffectRoot || source?.GroupType != LayerEffectRoot)
return;
dropInfo.DropTargetAdorner = DropTargetAdorners.Insert;
dropInfo.Effects = DragDropEffects.Move;
}
public void Drop(IDropInfo dropInfo)
{
// Workaround for https://github.com/punker76/gong-wpf-dragdrop/issues/344
// Luckily we know the index can never be 1 so it's an easy enough fix
if (dropInfo.InsertIndex == 1)
return;
var source = dropInfo.Data as LayerPropertyGroupViewModel;
var target = dropInfo.TargetItem as LayerPropertyGroupViewModel;
if (source == target || target?.GroupType != LayerEffectRoot || source?.GroupType != LayerEffectRoot)
return;
if (dropInfo.InsertPosition == RelativeInsertPosition.BeforeTargetItem)
MoveBefore(source, target);
else if (dropInfo.InsertPosition == RelativeInsertPosition.AfterTargetItem)
MoveAfter(source, target);
ApplyCurrentEffectsOrder();
ProfileEditorService.UpdateSelectedProfile(true);
}
private void MoveBefore(LayerPropertyGroupViewModel source, LayerPropertyGroupViewModel target)
{
if (LayerPropertyGroups.IndexOf(target) == LayerPropertyGroups.IndexOf(source) + 1)
return;
LayerPropertyGroups.Move(LayerPropertyGroups.IndexOf(source), LayerPropertyGroups.IndexOf(target));
}
private void MoveAfter(LayerPropertyGroupViewModel source, LayerPropertyGroupViewModel target)
{
LayerPropertyGroups.Remove(source);
LayerPropertyGroups.Insert(LayerPropertyGroups.IndexOf(target) + 1, source);
}
private void ApplyCurrentEffectsOrder()
{
var order = 1;
foreach (var groupViewModel in LayerPropertyGroups.Where(p => p.GroupType == LayerEffectRoot))
{
groupViewModel.UpdateOrder(order);
order++;
}
}
#endregion #endregion
#region Controls #region Controls

View File

@ -155,5 +155,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties
{ {
NotifyOfPropertyChange(nameof(IsVisible)); NotifyOfPropertyChange(nameof(IsVisible));
} }
public void UpdateOrder(int order)
{
LayerPropertyGroup.LayerEffect.Order = order;
NotifyOfPropertyChange(nameof(IsExpanded));
}
} }
} }

View File

@ -7,6 +7,7 @@
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet" xmlns:s="https://github.com/canton7/Stylet"
xmlns:converters="clr-namespace:Artemis.UI.Converters" xmlns:converters="clr-namespace:Artemis.UI.Converters"
xmlns:dd="urn:gong-wpf-dragdrop"
mc:Ignorable="d" mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:TreePropertyGroupViewModel}" d:DataContext="{d:DesignInstance local:TreePropertyGroupViewModel}"
d:DesignHeight="450" d:DesignWidth="800"> d:DesignHeight="450" d:DesignWidth="800">
@ -16,6 +17,7 @@
<StackPanel> <StackPanel>
<!-- Type: None --> <!-- Type: None -->
<TextBlock <TextBlock
dd:DragDrop.DragSourceIgnore="True"
Text="{Binding LayerPropertyGroupViewModel.PropertyGroupDescription.Name}" Text="{Binding LayerPropertyGroupViewModel.PropertyGroupDescription.Name}"
ToolTip="{Binding LayerPropertyGroupViewModel.PropertyGroupDescription.Description}" ToolTip="{Binding LayerPropertyGroupViewModel.PropertyGroupDescription.Description}"
VerticalAlignment="Center" VerticalAlignment="Center"
@ -33,7 +35,7 @@
</TextBlock> </TextBlock>
<!-- Type: General --> <!-- Type: General -->
<StackPanel Orientation="Horizontal" Margin="0 5"> <StackPanel Orientation="Horizontal" Margin="0 5" dd:DragDrop.DragSourceIgnore="True">
<StackPanel.Style> <StackPanel.Style>
<Style TargetType="{x:Type StackPanel}"> <Style TargetType="{x:Type StackPanel}">
<Setter Property="Visibility" Value="Collapsed" /> <Setter Property="Visibility" Value="Collapsed" />
@ -49,7 +51,7 @@
</StackPanel> </StackPanel>
<!-- Type: Transform --> <!-- Type: Transform -->
<StackPanel Orientation="Horizontal" Margin="0 5"> <StackPanel Orientation="Horizontal" Margin="0 5" dd:DragDrop.DragSourceIgnore="True">
<StackPanel.Style> <StackPanel.Style>
<Style TargetType="{x:Type StackPanel}"> <Style TargetType="{x:Type StackPanel}">
<Setter Property="Visibility" Value="Collapsed" /> <Setter Property="Visibility" Value="Collapsed" />
@ -65,7 +67,7 @@
</StackPanel> </StackPanel>
<!-- Type: LayerBrushRoot --> <!-- Type: LayerBrushRoot -->
<StackPanel Orientation="Horizontal" Margin="0 5"> <StackPanel Orientation="Horizontal" Margin="0 5" dd:DragDrop.DragSourceIgnore="True">
<StackPanel.Style> <StackPanel.Style>
<Style TargetType="{x:Type StackPanel}"> <Style TargetType="{x:Type StackPanel}">
<Setter Property="Visibility" Value="Collapsed" /> <Setter Property="Visibility" Value="Collapsed" />
@ -83,7 +85,7 @@
</StackPanel> </StackPanel>
<!-- Type: LayerEffectRoot --> <!-- Type: LayerEffectRoot -->
<Grid Height="24"> <Grid Height="24" Cursor="SizeNS">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />

View File

@ -44,17 +44,14 @@
</Style> </Style>
</ContentControl.Resources> </ContentControl.Resources>
</ContentControl> </ContentControl>
<Button Grid.Column="3" <Button Grid.Column="3"
Style="{StaticResource MaterialDesignOutlinedButton}" Style="{StaticResource MaterialDesignIconButton}"
Margin="0,1,0,1.2"
Padding="0"
Width="80"
Height="20"
ToolTip="Change the property's data binding" ToolTip="Change the property's data binding"
VerticalAlignment="Center" Width="24"
IsEnabled="False"> Height="24"
<TextBlock FontSize="10">DATA BINDING</TextBlock> VerticalAlignment="Center">
<materialDesign:PackIcon Kind="VectorLink" Height="16" Width="16" />
</Button> </Button>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -8,6 +8,7 @@
xmlns:converters="clr-namespace:Artemis.UI.Converters" xmlns:converters="clr-namespace:Artemis.UI.Converters"
xmlns:abstract="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract" xmlns:abstract="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Abstract"
xmlns:layerProperties="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties" xmlns:layerProperties="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.LayerProperties"
xmlns:dd="urn:gong-wpf-dragdrop"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance {x:Type local:TreeViewModel}}"> d:DataContext="{d:DesignInstance {x:Type local:TreeViewModel}}">
@ -87,6 +88,9 @@
HorizontalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"
Background="{DynamicResource MaterialDesignToolBarBackground}" Background="{DynamicResource MaterialDesignToolBarBackground}"
PreviewMouseWheel="{s:Action PropertyTreePreviewMouseWheel}" PreviewMouseWheel="{s:Action PropertyTreePreviewMouseWheel}"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.DropHandler="{Binding LayerPropertiesViewModel}"
Margin="0 -1"> Margin="0 -1">
<TreeView.ItemContainerStyle> <TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem" BasedOn="{StaticResource PropertyTreeStyle}"> <Style TargetType="TreeViewItem" BasedOn="{StaticResource PropertyTreeStyle}">
@ -99,7 +103,7 @@
<ContentControl s:View.Model="{Binding TreePropertyGroupViewModel}" /> <ContentControl s:View.Model="{Binding TreePropertyGroupViewModel}" />
</HierarchicalDataTemplate> </HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type layerProperties:LayerPropertyViewModel}"> <DataTemplate DataType="{x:Type layerProperties:LayerPropertyViewModel}">
<ContentControl s:View.Model="{Binding TreePropertyBaseViewModel}" /> <ContentControl s:View.Model="{Binding TreePropertyBaseViewModel}" dd:DragDrop.DragSourceIgnore="True" />
</DataTemplate> </DataTemplate>
</TreeView.Resources> </TreeView.Resources>
</TreeView> </TreeView>

View File

@ -7,14 +7,14 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.LayerProperties.Tree
{ {
public class TreeViewModel : PropertyChangedBase public class TreeViewModel : PropertyChangedBase
{ {
private readonly LayerPropertiesViewModel _layerPropertiesViewModel;
public TreeViewModel(LayerPropertiesViewModel layerPropertiesViewModel, BindableCollection<LayerPropertyGroupViewModel> layerPropertyGroups) public TreeViewModel(LayerPropertiesViewModel layerPropertiesViewModel, BindableCollection<LayerPropertyGroupViewModel> layerPropertyGroups)
{ {
_layerPropertiesViewModel = layerPropertiesViewModel; LayerPropertiesViewModel = layerPropertiesViewModel;
LayerPropertyGroups = layerPropertyGroups; LayerPropertyGroups = layerPropertyGroups;
} }
public LayerPropertiesViewModel LayerPropertiesViewModel { get; }
public BindableCollection<LayerPropertyGroupViewModel> LayerPropertyGroups { get; } public BindableCollection<LayerPropertyGroupViewModel> LayerPropertyGroups { get; }
public void PropertyTreePreviewMouseWheel(object sender, MouseWheelEventArgs e) public void PropertyTreePreviewMouseWheel(object sender, MouseWheelEventArgs e)

View File

@ -33,6 +33,7 @@
<ProjectReference Include="..\..\Artemis.Core\Artemis.Core.csproj"> <ProjectReference Include="..\..\Artemis.Core\Artemis.Core.csproj">
<Private>false</Private> <Private>false</Private>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\Artemis.UI.Shared\Artemis.UI.Shared.csproj" />
</ItemGroup> </ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(BuildingInsideVisualStudio)' == 'true'"> <Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(BuildingInsideVisualStudio)' == 'true'">
<Exec Command="echo Copying resources to plugin output directory&#xD;&#xA;XCOPY &quot;$(ProjectDir)Images&quot; &quot;$(TargetDir)Images&quot; /s /q /i /y&#xD;&#xA;XCOPY &quot;$(ProjectDir)Layouts&quot; &quot;$(TargetDir)Layouts&quot; /s /q /i /y&#xD;&#xA;echo Copying plugin to Artemis.UI output directory&#xD;&#xA;XCOPY &quot;$(TargetDir.TrimEnd('\'))&quot; &quot;$(SolutionDir)\Artemis.UI\$(OutDir)Plugins\$(ProjectName)&quot; /s /q /i /y" /> <Exec Command="echo Copying resources to plugin output directory&#xD;&#xA;XCOPY &quot;$(ProjectDir)Images&quot; &quot;$(TargetDir)Images&quot; /s /q /i /y&#xD;&#xA;XCOPY &quot;$(ProjectDir)Layouts&quot; &quot;$(TargetDir)Layouts&quot; /s /q /i /y&#xD;&#xA;echo Copying plugin to Artemis.UI output directory&#xD;&#xA;XCOPY &quot;$(TargetDir.TrimEnd('\'))&quot; &quot;$(SolutionDir)\Artemis.UI\$(OutDir)Plugins\$(ProjectName)&quot; /s /q /i /y" />

View File

@ -1,5 +1,6 @@
using System; using System;
using Artemis.Core.Plugins.LayerEffect.Abstract; using Artemis.Core.Plugins.LayerEffect.Abstract;
using Artemis.UI.Shared.Utilities;
using SkiaSharp; using SkiaSharp;
namespace Artemis.Plugins.LayerEffects.Filter namespace Artemis.Plugins.LayerEffects.Filter
@ -8,13 +9,17 @@ namespace Artemis.Plugins.LayerEffects.Filter
{ {
public override void EnableLayerEffect() public override void EnableLayerEffect()
{ {
Properties.BlurAmount.BaseValueChanged += BlurAmountOnBaseValueChanged; Properties.FilterType.BaseValueChanged += (sender, args) => UpdateFilterType();
UpdateFilterType();
} }
private void BlurAmountOnBaseValueChanged(object? sender, EventArgs e) private void UpdateFilterType()
{ {
if (!HasBeenRenamed) if (HasBeenRenamed)
Name = "Blur"; return;
Name = EnumUtilities.HumanizeValue(Properties.FilterType);
} }
public override void DisableLayerEffect() public override void DisableLayerEffect()
@ -27,8 +32,49 @@ namespace Artemis.Plugins.LayerEffects.Filter
public override void PreProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint) public override void PreProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint)
{ {
if (Properties.FilterType == FilterType.Blur)
paint.ImageFilter = SKImageFilter.CreateBlur(Properties.BlurAmount.CurrentValue.Width, Properties.BlurAmount.CurrentValue.Height, paint.ImageFilter); {
paint.ImageFilter = SKImageFilter.CreateBlur(
Properties.BlurAmount.CurrentValue.Width,
Properties.BlurAmount.CurrentValue.Height,
paint.ImageFilter
);
}
else if (Properties.FilterType == FilterType.Dilate)
{
paint.ImageFilter = SKImageFilter.CreateDilate(
(int) Properties.DilateRadius.CurrentValue.Width,
(int) Properties.DilateRadius.CurrentValue.Height,
paint.ImageFilter
);
}
else if (Properties.FilterType == FilterType.Erode)
{
paint.ImageFilter = SKImageFilter.CreateErode(
(int) Properties.ErodeRadius.CurrentValue.Width,
(int) Properties.ErodeRadius.CurrentValue.Height,
paint.ImageFilter
);
}
else if (Properties.FilterType == FilterType.Erode)
{
paint.ImageFilter = SKImageFilter.CreateErode(
(int) Properties.ErodeRadius.CurrentValue.Width,
(int) Properties.ErodeRadius.CurrentValue.Height,
paint.ImageFilter
);
}
else if (Properties.FilterType == FilterType.DropShadow)
{
paint.ImageFilter = SKImageFilter.CreateDropShadow(
Properties.ShadowOffset.CurrentValue.X,
Properties.ShadowOffset.CurrentValue.Y,
Properties.ShadowBlurAmount.CurrentValue.Width,
Properties.ShadowBlurAmount.CurrentValue.Height, Properties.ShadowColor,
SKDropShadowImageFilterShadowMode.DrawShadowAndForeground,
paint.ImageFilter
);
}
} }
public override void PostProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint) public override void PostProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint)

View File

@ -1,20 +1,62 @@
using Artemis.Core.Models.Profile; using System;
using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Profile.LayerProperties.Attributes; using Artemis.Core.Models.Profile.LayerProperties.Attributes;
using Artemis.Core.Models.Profile.LayerProperties.Types; using Artemis.Core.Models.Profile.LayerProperties.Types;
using SkiaSharp;
namespace Artemis.Plugins.LayerEffects.Filter namespace Artemis.Plugins.LayerEffects.Filter
{ {
public class FilterEffectProperties : LayerPropertyGroup public class FilterEffectProperties : LayerPropertyGroup
{ {
[PropertyDescription]
public EnumLayerProperty<FilterType> FilterType { get; set; }
[PropertyDescription(Description = "The amount of blur to apply")] [PropertyDescription(Description = "The amount of blur to apply")]
public SKSizeLayerProperty BlurAmount { get; set; } public SKSizeLayerProperty BlurAmount { get; set; }
[PropertyDescription(Description = "The amount of dilation to apply")]
public SKSizeLayerProperty DilateRadius { get; set; }
[PropertyDescription(Description = "The amount of erode to apply")]
public SKSizeLayerProperty ErodeRadius { get; set; }
[PropertyDescription(Description = "The offset of the shadow")]
public SKPointLayerProperty ShadowOffset { get; set; }
[PropertyDescription(Description = "The amount of blur to apply to the shadow")]
public SKSizeLayerProperty ShadowBlurAmount { get; set; }
[PropertyDescription(Description = "The color of the shadow")]
public SKColorLayerProperty ShadowColor { get; set; }
protected override void PopulateDefaults() protected override void PopulateDefaults()
{ {
ShadowBlurAmount.DefaultValue = new SKSize(5, 5);
ShadowColor.DefaultValue = new SKColor(50, 50, 50);
} }
protected override void OnPropertiesInitialized() protected override void OnPropertiesInitialized()
{ {
FilterType.BaseValueChanged += (sender, args) => UpdateVisibility();
UpdateVisibility();
}
private void UpdateVisibility()
{
BlurAmount.IsHidden = FilterType != Filter.FilterType.Blur;
DilateRadius.IsHidden = FilterType != Filter.FilterType.Dilate;
ErodeRadius.IsHidden = FilterType != Filter.FilterType.Erode;
ShadowOffset.IsHidden = FilterType != Filter.FilterType.DropShadow;
ShadowBlurAmount.IsHidden = FilterType != Filter.FilterType.DropShadow;
ShadowColor.IsHidden = FilterType != Filter.FilterType.DropShadow;
} }
} }
public enum FilterType
{
Blur,
Dilate,
Erode,
DropShadow,
}
} }