mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Core - Refactored effects
Profile editor - Added effect creation
This commit is contained in:
parent
e5ba48c7f4
commit
2bf36fbf20
7
src/.idea/.idea.Artemis/.idea/avalonia.xml
generated
7
src/.idea/.idea.Artemis/.idea/avalonia.xml
generated
@ -14,6 +14,13 @@
|
|||||||
<entry key="Artemis.UI.Avalonia/Screens/Sidebar/Views/SidebarProfileConfigurationView.axaml" value="Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj" />
|
<entry key="Artemis.UI.Avalonia/Screens/Sidebar/Views/SidebarProfileConfigurationView.axaml" value="Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj" />
|
||||||
<entry key="Artemis.UI.Avalonia/Screens/SidebarView.axaml" value="Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj" />
|
<entry key="Artemis.UI.Avalonia/Screens/SidebarView.axaml" value="Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj" />
|
||||||
<entry key="Artemis.UI.Avalonia/Views/MainWindow.axaml" value="Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj" />
|
<entry key="Artemis.UI.Avalonia/Views/MainWindow.axaml" value="Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj" />
|
||||||
|
<entry key="Artemis.UI.Windows/App.axaml" value="Artemis.UI.Windows/Artemis.UI.Windows.csproj" />
|
||||||
|
<entry key="Artemis.UI/DefaultTypes/PropertyInput/ColorGradientPropertyInputView.axaml" value="Artemis.UI.Windows/Artemis.UI.Windows.csproj" />
|
||||||
|
<entry key="Artemis.UI/Screens/ProfileEditor/Panels/Properties/Dialogs/AddEffectView.axaml" value="Artemis.UI.Windows/Artemis.UI.Windows.csproj" />
|
||||||
|
<entry key="Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertiesView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
|
||||||
|
<entry key="Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupView.axaml" value="Artemis.UI.Windows/Artemis.UI.Windows.csproj" />
|
||||||
|
<entry key="Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
|
||||||
|
<entry key="Artemis.UI/Screens/Settings/Tabs/GeneralTabView.axaml" value="Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
|
||||||
<entry key="Avalonia/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml" value="Avalonia/Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
|
<entry key="Avalonia/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml" value="Avalonia/Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
|
||||||
<entry key="Avalonia/Artemis.UI/Styles/Artemis.axaml" value="Avalonia/Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
|
<entry key="Avalonia/Artemis.UI/Styles/Artemis.axaml" value="Avalonia/Artemis.UI.Linux/Artemis.UI.Linux.csproj" />
|
||||||
</map>
|
</map>
|
||||||
|
|||||||
8
src/.idea/.idea.Artemis/.idea/misc.xml
generated
Normal file
8
src/.idea/.idea.Artemis/.idea/misc.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="SwUserDefinedSpecifications">
|
||||||
|
<option name="specTypeByUrl">
|
||||||
|
<map />
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@ -230,7 +230,7 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (genericType.IsInterface)
|
if (genericType.IsInterface)
|
||||||
foreach (var i in typeToCheck.GetInterfaces())
|
foreach (Type i in typeToCheck.GetInterfaces())
|
||||||
if (i.IsOfGenericType(genericType, out concreteGenericType))
|
if (i.IsOfGenericType(genericType, out concreteGenericType))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|||||||
@ -227,19 +227,29 @@ namespace Artemis.Core
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Enable()
|
public override void Enable()
|
||||||
{
|
{
|
||||||
if (Enabled)
|
// No checks here, effects will do their own checks to ensure they never enable twice
|
||||||
return;
|
// Also not enabling children, they'll enable themselves during their own Update
|
||||||
|
|
||||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects)
|
foreach (BaseLayerEffect baseLayerEffect in LayerEffects)
|
||||||
baseLayerEffect.InternalEnable();
|
baseLayerEffect.InternalEnable();
|
||||||
|
|
||||||
foreach (ProfileElement profileElement in Children)
|
Enabled = true;
|
||||||
{
|
|
||||||
if (profileElement is RenderProfileElement renderProfileElement && renderProfileElement.ShouldBeEnabled)
|
|
||||||
renderProfileElement.Enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Enabled = true;
|
/// <inheritdoc />
|
||||||
|
public override void Disable()
|
||||||
|
{
|
||||||
|
// No checks here, effects will do their own checks to ensure they never disable twice
|
||||||
|
foreach (BaseLayerEffect baseLayerEffect in LayerEffects)
|
||||||
|
baseLayerEffect.InternalDisable();
|
||||||
|
|
||||||
|
// Disabling children since their Update won't get called with their parent disabled
|
||||||
|
foreach (ProfileElement profileElement in Children)
|
||||||
|
{
|
||||||
|
if (profileElement is RenderProfileElement renderProfileElement)
|
||||||
|
renderProfileElement.Disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
Enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -250,24 +260,6 @@ namespace Artemis.Core
|
|||||||
baseLayerEffect.InternalUpdate(Timeline); ;
|
baseLayerEffect.InternalUpdate(Timeline); ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void Disable()
|
|
||||||
{
|
|
||||||
if (!Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects)
|
|
||||||
baseLayerEffect.InternalDisable();
|
|
||||||
|
|
||||||
foreach (ProfileElement profileElement in Children)
|
|
||||||
{
|
|
||||||
if (profileElement is RenderProfileElement renderProfileElement)
|
|
||||||
renderProfileElement.Disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
Enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when a property affecting the rendering properties of this folder has been updated
|
/// Occurs when a property affecting the rendering properties of this folder has been updated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -308,7 +300,6 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
internal override void Load()
|
internal override void Load()
|
||||||
{
|
{
|
||||||
ExpandedPropertyGroups.AddRange(FolderEntity.ExpandedPropertyGroups);
|
|
||||||
Reset();
|
Reset();
|
||||||
|
|
||||||
// Load child folders
|
// Load child folders
|
||||||
@ -340,8 +331,6 @@ namespace Artemis.Core
|
|||||||
FolderEntity.Suspended = Suspended;
|
FolderEntity.Suspended = Suspended;
|
||||||
|
|
||||||
FolderEntity.ProfileId = Profile.EntityId;
|
FolderEntity.ProfileId = Profile.EntityId;
|
||||||
FolderEntity.ExpandedPropertyGroups.Clear();
|
|
||||||
FolderEntity.ExpandedPropertyGroups.AddRange(ExpandedPropertyGroups);
|
|
||||||
|
|
||||||
SaveRenderElement();
|
SaveRenderElement();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -296,7 +296,6 @@ namespace Artemis.Core
|
|||||||
Suspended = LayerEntity.Suspended;
|
Suspended = LayerEntity.Suspended;
|
||||||
Order = LayerEntity.Order;
|
Order = LayerEntity.Order;
|
||||||
|
|
||||||
ExpandedPropertyGroups.AddRange(LayerEntity.ExpandedPropertyGroups);
|
|
||||||
LoadRenderElement();
|
LoadRenderElement();
|
||||||
Adapter.Load();
|
Adapter.Load();
|
||||||
}
|
}
|
||||||
@ -313,8 +312,6 @@ namespace Artemis.Core
|
|||||||
LayerEntity.Suspended = Suspended;
|
LayerEntity.Suspended = Suspended;
|
||||||
LayerEntity.Name = Name;
|
LayerEntity.Name = Name;
|
||||||
LayerEntity.ProfileId = Profile.EntityId;
|
LayerEntity.ProfileId = Profile.EntityId;
|
||||||
LayerEntity.ExpandedPropertyGroups.Clear();
|
|
||||||
LayerEntity.ExpandedPropertyGroups.AddRange(ExpandedPropertyGroups);
|
|
||||||
|
|
||||||
General.ApplyToEntity();
|
General.ApplyToEntity();
|
||||||
Transform.ApplyToEntity();
|
Transform.ApplyToEntity();
|
||||||
@ -505,9 +502,7 @@ namespace Artemis.Core
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Enable()
|
public override void Enable()
|
||||||
{
|
{
|
||||||
if (Enabled)
|
// No checks here, the brush and effects will do their own checks to ensure they never enable twice
|
||||||
return;
|
|
||||||
|
|
||||||
bool tryOrBreak = TryOrBreak(() => LayerBrush?.InternalEnable(), "Failed to enable layer brush");
|
bool tryOrBreak = TryOrBreak(() => LayerBrush?.InternalEnable(), "Failed to enable layer brush");
|
||||||
if (!tryOrBreak)
|
if (!tryOrBreak)
|
||||||
return;
|
return;
|
||||||
@ -523,6 +518,17 @@ namespace Artemis.Core
|
|||||||
Enabled = true;
|
Enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Disable()
|
||||||
|
{
|
||||||
|
// No checks here, the brush and effects will do their own checks to ensure they never disable twice
|
||||||
|
LayerBrush?.InternalDisable();
|
||||||
|
foreach (BaseLayerEffect baseLayerEffect in LayerEffects)
|
||||||
|
baseLayerEffect.InternalDisable();
|
||||||
|
|
||||||
|
Enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OverrideTimelineAndApply(TimeSpan position)
|
public override void OverrideTimelineAndApply(TimeSpan position)
|
||||||
{
|
{
|
||||||
@ -536,19 +542,6 @@ namespace Artemis.Core
|
|||||||
baseLayerEffect.InternalUpdate(Timeline);
|
baseLayerEffect.InternalUpdate(Timeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void Disable()
|
|
||||||
{
|
|
||||||
if (!Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
LayerBrush?.InternalDisable();
|
|
||||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects)
|
|
||||||
baseLayerEffect.InternalDisable();
|
|
||||||
|
|
||||||
Enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Reset()
|
public override void Reset()
|
||||||
{
|
{
|
||||||
@ -822,6 +815,7 @@ namespace Artemis.Core
|
|||||||
General.ShapeType.IsHidden = LayerBrush != null && !LayerBrush.SupportsTransformation;
|
General.ShapeType.IsHidden = LayerBrush != null && !LayerBrush.SupportsTransformation;
|
||||||
General.BlendMode.IsHidden = LayerBrush != null && !LayerBrush.SupportsTransformation;
|
General.BlendMode.IsHidden = LayerBrush != null && !LayerBrush.SupportsTransformation;
|
||||||
Transform.IsHidden = LayerBrush != null && !LayerBrush.SupportsTransformation;
|
Transform.IsHidden = LayerBrush != null && !LayerBrush.SupportsTransformation;
|
||||||
|
LayerBrush?.Update(0);
|
||||||
|
|
||||||
OnLayerBrushUpdated();
|
OnLayerBrushUpdated();
|
||||||
ClearBrokenState("Failed to initialize layer brush");
|
ClearBrokenState("Failed to initialize layer brush");
|
||||||
|
|||||||
25
src/Artemis.Core/Models/Profile/LayerEffectPropertyGroup.cs
Normal file
25
src/Artemis.Core/Models/Profile/LayerEffectPropertyGroup.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a property group on a layer
|
||||||
|
/// <para>
|
||||||
|
/// Note: You cannot initialize property groups yourself. If properly placed and annotated, the Artemis core will
|
||||||
|
/// initialize these for you.
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
public abstract class LayerEffectPropertyGroup : LayerPropertyGroup
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Whether or not this layer effect is enabled
|
||||||
|
/// </summary>
|
||||||
|
[PropertyDescription(Name = "Enabled", Description = "Whether or not this layer effect is enabled")]
|
||||||
|
public BoolLayerProperty IsEnabled { get; set; } = null!;
|
||||||
|
|
||||||
|
internal void InitializeIsEnabled()
|
||||||
|
{
|
||||||
|
IsEnabled.DefaultValue = true;
|
||||||
|
if (!IsEnabled.IsLoadedFromStorage)
|
||||||
|
IsEnabled.SetCurrentValue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -203,7 +203,7 @@ namespace Artemis.Core
|
|||||||
/// or existing keyframe.
|
/// or existing keyframe.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns>The keyframe if one was created or updated.</returns>
|
/// <returns>The keyframe if one was created or updated.</returns>
|
||||||
public LayerPropertyKeyframe<T>? SetCurrentValue(T value, TimeSpan? time)
|
public LayerPropertyKeyframe<T>? SetCurrentValue(T value, TimeSpan? time = null)
|
||||||
{
|
{
|
||||||
if (_disposed)
|
if (_disposed)
|
||||||
throw new ObjectDisposedException("LayerProperty");
|
throw new ObjectDisposedException("LayerProperty");
|
||||||
|
|||||||
@ -249,6 +249,15 @@ namespace Artemis.Core
|
|||||||
layerPropertyGroup.Update(timeline);
|
layerPropertyGroup.Update(timeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void MoveLayerProperty(ILayerProperty layerProperty, int index)
|
||||||
|
{
|
||||||
|
if (!_layerProperties.Contains(layerProperty))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_layerProperties.Remove(layerProperty);
|
||||||
|
_layerProperties.Insert(index, layerProperty);
|
||||||
|
}
|
||||||
|
|
||||||
internal virtual void OnVisibilityChanged()
|
internal virtual void OnVisibilityChanged()
|
||||||
{
|
{
|
||||||
VisibilityChanged?.Invoke(this, EventArgs.Empty);
|
VisibilityChanged?.Invoke(this, EventArgs.Empty);
|
||||||
|
|||||||
@ -4,30 +4,28 @@ using System.Collections.ObjectModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Core.LayerEffects;
|
using Artemis.Core.LayerEffects;
|
||||||
using Artemis.Core.LayerEffects.Placeholder;
|
using Artemis.Core.LayerEffects.Placeholder;
|
||||||
using Artemis.Core.Properties;
|
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using Artemis.Storage.Entities.Profile.Abstract;
|
using Artemis.Storage.Entities.Profile.Abstract;
|
||||||
using Artemis.Storage.Entities.Profile.Conditions;
|
using Artemis.Storage.Entities.Profile.Conditions;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an element of a <see cref="Profile" /> that has advanced rendering capabilities
|
||||||
|
/// </summary>
|
||||||
|
public abstract class RenderProfileElement : ProfileElement
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Represents an element of a <see cref="Profile" /> that has advanced rendering capabilities
|
|
||||||
/// </summary>
|
|
||||||
public abstract class RenderProfileElement : ProfileElement
|
|
||||||
{
|
|
||||||
private SKRectI _bounds;
|
private SKRectI _bounds;
|
||||||
private SKPath? _path;
|
private SKPath? _path;
|
||||||
|
|
||||||
internal RenderProfileElement(ProfileElement parent, Profile profile) : base(profile)
|
internal RenderProfileElement(ProfileElement parent, Profile profile) : base(profile)
|
||||||
{
|
{
|
||||||
Timeline = new Timeline();
|
_layerEffects = new List<BaseLayerEffect>();
|
||||||
ExpandedPropertyGroups = new List<string>();
|
|
||||||
LayerEffectsList = new List<BaseLayerEffect>();
|
|
||||||
LayerEffects = new ReadOnlyCollection<BaseLayerEffect>(LayerEffectsList);
|
|
||||||
Parent = parent ?? throw new ArgumentNullException(nameof(parent));
|
|
||||||
_displayCondition = new AlwaysOnCondition(this);
|
_displayCondition = new AlwaysOnCondition(this);
|
||||||
|
Timeline = new Timeline();
|
||||||
|
LayerEffects = new ReadOnlyCollection<BaseLayerEffect>(_layerEffects);
|
||||||
|
Parent = parent ?? throw new ArgumentNullException(nameof(parent));
|
||||||
|
|
||||||
LayerEffectStore.LayerEffectAdded += LayerEffectStoreOnLayerEffectAdded;
|
LayerEffectStore.LayerEffectAdded += LayerEffectStoreOnLayerEffectAdded;
|
||||||
LayerEffectStore.LayerEffectRemoved += LayerEffectStoreOnLayerEffectRemoved;
|
LayerEffectStore.LayerEffectRemoved += LayerEffectStoreOnLayerEffectRemoved;
|
||||||
@ -54,6 +52,12 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler? LayerEffectsUpdated;
|
public event EventHandler? LayerEffectsUpdated;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overrides the main timeline to the specified time and clears any extra time lines
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="position">The position to set the timeline to</param>
|
||||||
|
public abstract void OverrideTimelineAndApply(TimeSpan position);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
@ -84,7 +88,7 @@ namespace Artemis.Core
|
|||||||
_ => DisplayCondition
|
_ => DisplayCondition
|
||||||
};
|
};
|
||||||
|
|
||||||
ActivateEffects();
|
LoadLayerEffects();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void SaveRenderElement()
|
internal void SaveRenderElement()
|
||||||
@ -114,7 +118,7 @@ namespace Artemis.Core
|
|||||||
layerProperty.BaseDataBinding.LoadNodeScript();
|
layerProperty.BaseDataBinding.LoadNodeScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OnLayerEffectsUpdated()
|
private void OnLayerEffectsUpdated()
|
||||||
{
|
{
|
||||||
LayerEffectsUpdated?.Invoke(this, EventArgs.Empty);
|
LayerEffectsUpdated?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
@ -127,7 +131,8 @@ namespace Artemis.Core
|
|||||||
public Timeline Timeline { get; private set; }
|
public Timeline Timeline { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the <see cref="Timeline" /> according to the provided <paramref name="deltaTime" /> and current display condition
|
/// Updates the <see cref="Timeline" /> according to the provided <paramref name="deltaTime" /> and current display
|
||||||
|
/// condition
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected void UpdateTimeline(double deltaTime)
|
protected void UpdateTimeline(double deltaTime)
|
||||||
{
|
{
|
||||||
@ -178,36 +183,6 @@ namespace Artemis.Core
|
|||||||
private set => SetAndNotify(ref _bounds, value);
|
private set => SetAndNotify(ref _bounds, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region Property group expansion
|
|
||||||
|
|
||||||
internal List<string> ExpandedPropertyGroups;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines whether the provided property group is expanded
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="layerPropertyGroup">The property group to check</param>
|
|
||||||
/// <returns>A boolean indicating whether the provided property group is expanded</returns>
|
|
||||||
public bool IsPropertyGroupExpanded(LayerPropertyGroup layerPropertyGroup)
|
|
||||||
{
|
|
||||||
return ExpandedPropertyGroups.Contains(layerPropertyGroup.Path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Expands or collapses the provided property group
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="layerPropertyGroup">The group to expand or collapse</param>
|
|
||||||
/// <param name="expanded">Whether to expand or collapse the property group</param>
|
|
||||||
public void SetPropertyGroupExpanded(LayerPropertyGroup layerPropertyGroup, bool expanded)
|
|
||||||
{
|
|
||||||
if (!expanded && IsPropertyGroupExpanded(layerPropertyGroup))
|
|
||||||
ExpandedPropertyGroups.Remove(layerPropertyGroup.Path);
|
|
||||||
else if (expanded && !IsPropertyGroupExpanded(layerPropertyGroup))
|
|
||||||
ExpandedPropertyGroups.Add(layerPropertyGroup.Path);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region State
|
#region State
|
||||||
@ -226,7 +201,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
#region Effect management
|
#region Effect management
|
||||||
|
|
||||||
internal readonly List<BaseLayerEffect> LayerEffectsList;
|
private readonly List<BaseLayerEffect> _layerEffects;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read-only collection of the layer effects on this entity
|
/// Gets a read-only collection of the layer effects on this entity
|
||||||
@ -234,42 +209,106 @@ namespace Artemis.Core
|
|||||||
public ReadOnlyCollection<BaseLayerEffect> LayerEffects { get; }
|
public ReadOnlyCollection<BaseLayerEffect> LayerEffects { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a the layer effect described inthe provided <paramref name="descriptor" />
|
/// Adds a the provided layer effect to the render profile element
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void AddLayerEffect(LayerEffectDescriptor descriptor)
|
/// <param name="layerEffect">The effect to add.</param>
|
||||||
|
public void AddLayerEffect(BaseLayerEffect layerEffect)
|
||||||
{
|
{
|
||||||
if (descriptor == null)
|
if (layerEffect == null)
|
||||||
throw new ArgumentNullException(nameof(descriptor));
|
throw new ArgumentNullException(nameof(layerEffect));
|
||||||
|
|
||||||
LayerEffectEntity entity = new()
|
// Ensure something needs to be done
|
||||||
{
|
if (_layerEffects.Contains(layerEffect))
|
||||||
Id = Guid.NewGuid(),
|
return;
|
||||||
Suspended = false,
|
|
||||||
Order = LayerEffects.Count + 1
|
|
||||||
};
|
|
||||||
descriptor.CreateInstance(this, entity);
|
|
||||||
|
|
||||||
|
// Make sure the layer effect is tied to this element
|
||||||
|
layerEffect.ProfileElement = this;
|
||||||
|
_layerEffects.Add(layerEffect);
|
||||||
|
|
||||||
|
// Update the order on the effects
|
||||||
OrderEffects();
|
OrderEffects();
|
||||||
OnLayerEffectsUpdated();
|
OnLayerEffectsUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes the provided layer
|
/// Removes the provided layer effect.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="effect"></param>
|
/// <param name="layerEffect">The effect to remove.</param>
|
||||||
public void RemoveLayerEffect([NotNull] BaseLayerEffect effect)
|
public void RemoveLayerEffect(BaseLayerEffect layerEffect)
|
||||||
{
|
{
|
||||||
if (effect == null) throw new ArgumentNullException(nameof(effect));
|
if (layerEffect == null)
|
||||||
|
throw new ArgumentNullException(nameof(layerEffect));
|
||||||
|
|
||||||
// Remove the effect from the layer and dispose it
|
// Ensure something needs to be done
|
||||||
LayerEffectsList.Remove(effect);
|
if (!_layerEffects.Contains(layerEffect))
|
||||||
effect.Dispose();
|
return;
|
||||||
|
|
||||||
|
// Remove the effect from the layer
|
||||||
|
_layerEffects.Remove(layerEffect);
|
||||||
|
|
||||||
// Update the order on the remaining effects
|
// Update the order on the remaining effects
|
||||||
OrderEffects();
|
OrderEffects();
|
||||||
OnLayerEffectsUpdated();
|
OnLayerEffectsUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void LoadLayerEffects()
|
||||||
|
{
|
||||||
|
foreach (BaseLayerEffect baseLayerEffect in _layerEffects)
|
||||||
|
baseLayerEffect.Dispose();
|
||||||
|
_layerEffects.Clear();
|
||||||
|
|
||||||
|
foreach (LayerEffectEntity layerEffectEntity in RenderElementEntity.LayerEffects.OrderBy(e => e.Order))
|
||||||
|
LoadLayerEffect(layerEffectEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadLayerEffect(LayerEffectEntity layerEffectEntity)
|
||||||
|
{
|
||||||
|
LayerEffectDescriptor? descriptor = LayerEffectStore.Get(layerEffectEntity.ProviderId, layerEffectEntity.EffectType)?.LayerEffectDescriptor;
|
||||||
|
BaseLayerEffect layerEffect;
|
||||||
|
// Create an instance with the descriptor
|
||||||
|
if (descriptor != null)
|
||||||
|
{
|
||||||
|
layerEffect = descriptor.CreateInstance(this, layerEffectEntity);
|
||||||
|
}
|
||||||
|
// If no descriptor was found and there was no existing placeholder, create a placeholder
|
||||||
|
else
|
||||||
|
{
|
||||||
|
descriptor = PlaceholderLayerEffectDescriptor.Create(layerEffectEntity.ProviderId);
|
||||||
|
layerEffect = descriptor.CreateInstance(this, layerEffectEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
_layerEffects.Add(layerEffect);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReplaceLayerEffectWithPlaceholder(BaseLayerEffect layerEffect)
|
||||||
|
{
|
||||||
|
int index = _layerEffects.IndexOf(layerEffect);
|
||||||
|
if (index == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LayerEffectDescriptor descriptor = PlaceholderLayerEffectDescriptor.Create(layerEffect.ProviderId);
|
||||||
|
BaseLayerEffect placeholder = descriptor.CreateInstance(this, layerEffect.LayerEffectEntity);
|
||||||
|
_layerEffects[index] = placeholder;
|
||||||
|
layerEffect.Dispose();
|
||||||
|
OnLayerEffectsUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReplacePlaceholderWithLayerEffect(PlaceholderLayerEffect placeholder)
|
||||||
|
{
|
||||||
|
int index = _layerEffects.IndexOf(placeholder);
|
||||||
|
if (index == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LayerEffectDescriptor? descriptor = LayerEffectStore.Get(placeholder.OriginalEntity.ProviderId, placeholder.PlaceholderFor)?.LayerEffectDescriptor;
|
||||||
|
if (descriptor == null)
|
||||||
|
throw new ArtemisCoreException("Can't replace a placeholder effect because the real effect isn't available.");
|
||||||
|
|
||||||
|
BaseLayerEffect layerEffect = descriptor.CreateInstance(this, placeholder.OriginalEntity);
|
||||||
|
_layerEffects[index] = layerEffect;
|
||||||
|
placeholder.Dispose();
|
||||||
|
OnLayerEffectsUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
private void OrderEffects()
|
private void OrderEffects()
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@ -279,68 +318,36 @@ namespace Artemis.Core
|
|||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerEffectsList.Sort((a, b) => a.Order.CompareTo(b.Order));
|
_layerEffects.Sort((a, b) => a.Order.CompareTo(b.Order));
|
||||||
}
|
|
||||||
|
|
||||||
internal void ActivateEffects()
|
|
||||||
{
|
|
||||||
foreach (LayerEffectEntity layerEffectEntity in RenderElementEntity.LayerEffects)
|
|
||||||
{
|
|
||||||
// If there is a non-placeholder existing effect, skip this entity
|
|
||||||
BaseLayerEffect? existing = LayerEffectsList.FirstOrDefault(e => e.LayerEffectEntity.Id == layerEffectEntity.Id);
|
|
||||||
if (existing != null && existing.Descriptor.PlaceholderFor == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
LayerEffectDescriptor? descriptor = LayerEffectStore.Get(layerEffectEntity.ProviderId, layerEffectEntity.EffectType)?.LayerEffectDescriptor;
|
|
||||||
if (descriptor != null)
|
|
||||||
{
|
|
||||||
// If a descriptor is found but there is an existing placeholder, remove the placeholder
|
|
||||||
if (existing != null)
|
|
||||||
{
|
|
||||||
LayerEffectsList.Remove(existing);
|
|
||||||
existing.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an instance with the descriptor
|
|
||||||
descriptor.CreateInstance(this, layerEffectEntity);
|
|
||||||
}
|
|
||||||
else if (existing == null)
|
|
||||||
{
|
|
||||||
// If no descriptor was found and there was no existing placeholder, create a placeholder
|
|
||||||
descriptor = PlaceholderLayerEffectDescriptor.Create(layerEffectEntity.ProviderId);
|
|
||||||
descriptor.CreateInstance(this, layerEffectEntity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OrderEffects();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
internal void ActivateLayerEffect(BaseLayerEffect layerEffect)
|
|
||||||
{
|
|
||||||
LayerEffectsList.Add(layerEffect);
|
|
||||||
OnLayerEffectsUpdated();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LayerEffectStoreOnLayerEffectRemoved(object? sender, LayerEffectStoreEvent e)
|
private void LayerEffectStoreOnLayerEffectRemoved(object? sender, LayerEffectStoreEvent e)
|
||||||
{
|
{
|
||||||
// If effects provided by the plugin are on the element, replace them with placeholders
|
// Find effects that just got disabled and replace them with placeholders
|
||||||
List<BaseLayerEffect> pluginEffects = LayerEffectsList.Where(ef => ef.ProviderId == e.Registration.PluginFeature.Id).ToList();
|
List<BaseLayerEffect> affectedLayerEffects = _layerEffects.Where(ef => ef.ProviderId == e.Registration.PluginFeature.Id).ToList();
|
||||||
foreach (BaseLayerEffect pluginEffect in pluginEffects)
|
|
||||||
{
|
|
||||||
LayerEffectEntity entity = RenderElementEntity.LayerEffects.First(en => en.Id == pluginEffect.LayerEffectEntity.Id);
|
|
||||||
LayerEffectsList.Remove(pluginEffect);
|
|
||||||
pluginEffect.Dispose();
|
|
||||||
|
|
||||||
LayerEffectDescriptor descriptor = PlaceholderLayerEffectDescriptor.Create(pluginEffect.ProviderId);
|
if (!affectedLayerEffects.Any())
|
||||||
descriptor.CreateInstance(this, entity);
|
return;
|
||||||
}
|
|
||||||
|
foreach (BaseLayerEffect baseLayerEffect in affectedLayerEffects)
|
||||||
|
ReplaceLayerEffectWithPlaceholder(baseLayerEffect);
|
||||||
|
OnLayerEffectsUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LayerEffectStoreOnLayerEffectAdded(object? sender, LayerEffectStoreEvent e)
|
private void LayerEffectStoreOnLayerEffectAdded(object? sender, LayerEffectStoreEvent e)
|
||||||
{
|
{
|
||||||
if (RenderElementEntity.LayerEffects.Any(ef => ef.ProviderId == e.Registration.PluginFeature.Id))
|
// Find placeholders that just got enabled and replace them with real effects
|
||||||
ActivateEffects();
|
List<PlaceholderLayerEffect> affectedPlaceholders = LayerEffects
|
||||||
|
.Where(l => l is PlaceholderLayerEffect ph && ph.OriginalEntity.ProviderId == e.Registration.PluginFeature.Id)
|
||||||
|
.Cast<PlaceholderLayerEffect>()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (!affectedPlaceholders.Any())
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (PlaceholderLayerEffect placeholderLayerEffect in affectedPlaceholders)
|
||||||
|
ReplacePlaceholderWithLayerEffect(placeholderLayerEffect);
|
||||||
|
OnLayerEffectsUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -354,7 +361,7 @@ namespace Artemis.Core
|
|||||||
public bool DisplayConditionMet
|
public bool DisplayConditionMet
|
||||||
{
|
{
|
||||||
get => _displayConditionMet;
|
get => _displayConditionMet;
|
||||||
protected set => SetAndNotify(ref _displayConditionMet, value);
|
private set => SetAndNotify(ref _displayConditionMet, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _displayConditionMet;
|
private bool _displayConditionMet;
|
||||||
@ -386,11 +393,4 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Overrides the main timeline to the specified time and clears any extra time lines
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="position">The position to set the timeline to</param>
|
|
||||||
public abstract void OverrideTimelineAndApply(TimeSpan position);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -451,7 +451,7 @@ namespace Artemis.Core
|
|||||||
});
|
});
|
||||||
|
|
||||||
DeviceEntity.InputMappings.Clear();
|
DeviceEntity.InputMappings.Clear();
|
||||||
foreach (var (original, mapped) in InputMappings)
|
foreach ((ArtemisLed? original, ArtemisLed? mapped) in InputMappings)
|
||||||
DeviceEntity.InputMappings.Add(new InputMappingEntity {OriginalLedId = (int) original.RgbLed.Id, MappedLedId = (int) mapped.RgbLed.Id});
|
DeviceEntity.InputMappings.Add(new InputMappingEntity {OriginalLedId = (int) original.RgbLed.Id, MappedLedId = (int) mapped.RgbLed.Id});
|
||||||
|
|
||||||
DeviceEntity.Categories.Clear();
|
DeviceEntity.Categories.Clear();
|
||||||
|
|||||||
@ -6,7 +6,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// For internal use only, please use <see cref="LayerBrush{T}" /> or <see cref="PerLedLayerBrush{T}" /> or instead
|
/// For internal use only, please use <see cref="LayerBrush{T}" /> or <see cref="PerLedLayerBrush{T}" /> or instead
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class PropertiesLayerBrush<T> : BaseLayerBrush where T : LayerPropertyGroup
|
public abstract class PropertiesLayerBrush<T> : BaseLayerBrush where T : LayerPropertyGroup, new()
|
||||||
{
|
{
|
||||||
private T _properties = null!;
|
private T _properties = null!;
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
|
|
||||||
internal void InitializeProperties(PropertyGroupEntity? propertyGroupEntity)
|
internal void InitializeProperties(PropertyGroupEntity? propertyGroupEntity)
|
||||||
{
|
{
|
||||||
Properties = Activator.CreateInstance<T>();
|
Properties = new T();
|
||||||
PropertyGroupDescriptionAttribute groupDescription = new() {Identifier = "Brush", Name = Descriptor.DisplayName, Description = Descriptor.Description};
|
PropertyGroupDescriptionAttribute groupDescription = new() {Identifier = "Brush", Name = Descriptor.DisplayName, Description = Descriptor.Description};
|
||||||
Properties.Initialize(Layer, null, groupDescription, propertyGroupEntity);
|
Properties.Initialize(Layer, null, groupDescription, propertyGroupEntity);
|
||||||
PropertiesInitialized = true;
|
PropertiesInitialized = true;
|
||||||
|
|||||||
@ -6,7 +6,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
/// Represents a brush that renders on a layer
|
/// Represents a brush that renders on a layer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of brush properties</typeparam>
|
/// <typeparam name="T">The type of brush properties</typeparam>
|
||||||
public abstract class LayerBrush<T> : PropertiesLayerBrush<T> where T : LayerPropertyGroup
|
public abstract class LayerBrush<T> : PropertiesLayerBrush<T> where T : LayerPropertyGroup, new()
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of the <see cref="LayerBrush{T}" /> class
|
/// Creates a new instance of the <see cref="LayerBrush{T}" /> class
|
||||||
|
|||||||
@ -69,8 +69,6 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
brush.LayerBrushEntity = entity ?? new LayerBrushEntity { ProviderId = Provider.Id, BrushType = LayerBrushType.FullName };
|
brush.LayerBrushEntity = entity ?? new LayerBrushEntity { ProviderId = Provider.Id, BrushType = LayerBrushType.FullName };
|
||||||
|
|
||||||
brush.Initialize();
|
brush.Initialize();
|
||||||
brush.Update(0);
|
|
||||||
|
|
||||||
return brush;
|
return brush;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
/// Represents a brush that renders on a per-layer basis
|
/// Represents a brush that renders on a per-layer basis
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of brush properties</typeparam>
|
/// <typeparam name="T">The type of brush properties</typeparam>
|
||||||
public abstract class PerLedLayerBrush<T> : PropertiesLayerBrush<T> where T : LayerPropertyGroup
|
public abstract class PerLedLayerBrush<T> : PropertiesLayerBrush<T> where T : LayerPropertyGroup, new()
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of the <see cref="PerLedLayerBrush{T}" /> class
|
/// Creates a new instance of the <see cref="PerLedLayerBrush{T}" /> class
|
||||||
|
|||||||
@ -7,12 +7,11 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// For internal use only, please use <see cref="LayerEffect{T}" /> instead
|
/// For internal use only, please use <see cref="LayerEffect{T}" /> instead
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class BaseLayerEffect : BreakableModel, IDisposable
|
public abstract class BaseLayerEffect : BreakableModel, IDisposable, IStorageModel
|
||||||
{
|
{
|
||||||
private ILayerEffectConfigurationDialog? _configurationDialog;
|
private ILayerEffectConfigurationDialog? _configurationDialog;
|
||||||
private LayerEffectDescriptor _descriptor;
|
private LayerEffectDescriptor _descriptor;
|
||||||
private bool _suspended;
|
private bool _suspended;
|
||||||
private Guid _entityId;
|
|
||||||
private bool _hasBeenRenamed;
|
private bool _hasBeenRenamed;
|
||||||
private string _name;
|
private string _name;
|
||||||
private int _order;
|
private int _order;
|
||||||
@ -51,15 +50,6 @@ namespace Artemis.Core.LayerEffects
|
|||||||
set => SetAndNotify(ref _name, value);
|
set => SetAndNotify(ref _name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the suspended state, if suspended the effect is skipped in render and update
|
|
||||||
/// </summary>
|
|
||||||
public bool Suspended
|
|
||||||
{
|
|
||||||
get => _suspended;
|
|
||||||
set => SetAndNotify(ref _suspended, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets whether the effect has been renamed by the user, if true consider refraining from changing the name
|
/// Gets or sets whether the effect has been renamed by the user, if true consider refraining from changing the name
|
||||||
/// programatically
|
/// programatically
|
||||||
@ -105,13 +95,18 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a reference to the layer property group without knowing it's type
|
/// Gets a reference to the layer property group without knowing it's type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual LayerPropertyGroup? BaseProperties => null;
|
public virtual LayerEffectPropertyGroup? BaseProperties => null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a boolean indicating whether the layer effect is enabled or not
|
/// Gets a boolean indicating whether the layer effect is enabled or not
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Enabled { get; private set; }
|
public bool Enabled { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a boolean indicating whether the layer effect is suspended or not
|
||||||
|
/// </summary>
|
||||||
|
public bool Suspended => BaseProperties is not {PropertiesInitialized: true} || !BaseProperties.IsEnabled;
|
||||||
|
|
||||||
#region IDisposable
|
#region IDisposable
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -224,11 +219,20 @@ namespace Artemis.Core.LayerEffects
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Load()
|
||||||
|
{
|
||||||
|
Name = LayerEffectEntity.Name;
|
||||||
|
HasBeenRenamed = LayerEffectEntity.HasBeenRenamed;
|
||||||
|
Order = LayerEffectEntity.Order;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
// No need to update the ID, type and provider ID. They're set once by the LayerBrushDescriptors CreateInstance and can't change
|
LayerEffectEntity.ProviderId = Descriptor.Provider.Id;
|
||||||
|
LayerEffectEntity.EffectType = GetType().FullName;
|
||||||
LayerEffectEntity.Name = Name;
|
LayerEffectEntity.Name = Name;
|
||||||
LayerEffectEntity.Suspended = Suspended;
|
|
||||||
LayerEffectEntity.HasBeenRenamed = HasBeenRenamed;
|
LayerEffectEntity.HasBeenRenamed = HasBeenRenamed;
|
||||||
LayerEffectEntity.Order = Order;
|
LayerEffectEntity.Order = Order;
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// Represents an effect that applies preprocessing and/or postprocessing to a layer
|
/// Represents an effect that applies preprocessing and/or postprocessing to a layer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
public abstract class LayerEffect<T> : BaseLayerEffect where T : LayerPropertyGroup
|
public abstract class LayerEffect<T> : BaseLayerEffect where T : LayerEffectPropertyGroup, new()
|
||||||
{
|
{
|
||||||
private T _properties = null!;
|
private T _properties = null!;
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ namespace Artemis.Core.LayerEffects
|
|||||||
public bool PropertiesInitialized { get; internal set; }
|
public bool PropertiesInitialized { get; internal set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override LayerPropertyGroup BaseProperties => Properties;
|
public override LayerEffectPropertyGroup BaseProperties => Properties;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the properties of this effect.
|
/// Gets the properties of this effect.
|
||||||
@ -33,18 +33,21 @@ namespace Artemis.Core.LayerEffects
|
|||||||
internal set => _properties = value;
|
internal set => _properties = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void InitializeProperties()
|
|
||||||
{
|
|
||||||
Properties = Activator.CreateInstance<T>();
|
|
||||||
Properties.Initialize(ProfileElement, null, new PropertyGroupDescriptionAttribute(){Identifier = "LayerEffect"}, LayerEffectEntity.PropertyGroup);
|
|
||||||
PropertiesInitialized = true;
|
|
||||||
|
|
||||||
EnableLayerEffect();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal override void Initialize()
|
internal override void Initialize()
|
||||||
{
|
{
|
||||||
InitializeProperties();
|
InitializeProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InitializeProperties()
|
||||||
|
{
|
||||||
|
Properties = new T();
|
||||||
|
Properties.Initialize(ProfileElement, null, new PropertyGroupDescriptionAttribute {Identifier = "LayerEffect"}, LayerEffectEntity.PropertyGroup);
|
||||||
|
|
||||||
|
// Initialize will call PopulateDefaults but that is for plugin developers so can't rely on that to default IsEnabled to true
|
||||||
|
Properties.InitializeIsEnabled();
|
||||||
|
PropertiesInitialized = true;
|
||||||
|
|
||||||
|
EnableLayerEffect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,23 +1,31 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using Artemis.Core.LayerEffects.Placeholder;
|
using Artemis.Core.LayerEffects.Placeholder;
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using Ninject;
|
using Ninject;
|
||||||
|
|
||||||
namespace Artemis.Core.LayerEffects
|
namespace Artemis.Core.LayerEffects;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A class that describes a layer effect
|
||||||
|
/// </summary>
|
||||||
|
public class LayerEffectDescriptor
|
||||||
{
|
{
|
||||||
/// <summary>
|
internal LayerEffectDescriptor(string displayName, string description, string icon, Type layerEffectType, LayerEffectProvider provider)
|
||||||
/// A class that describes a layer effect
|
|
||||||
/// </summary>
|
|
||||||
public class LayerEffectDescriptor
|
|
||||||
{
|
|
||||||
internal LayerEffectDescriptor(string displayName, string description, string icon, Type? layerEffectType, LayerEffectProvider provider)
|
|
||||||
{
|
{
|
||||||
DisplayName = displayName;
|
DisplayName = displayName;
|
||||||
Description = description;
|
Description = description;
|
||||||
Icon = icon;
|
Icon = icon;
|
||||||
LayerEffectType = layerEffectType;
|
LayerEffectType = layerEffectType ?? throw new ArgumentNullException(nameof(layerEffectType));
|
||||||
Provider = provider;
|
Provider = provider ?? throw new ArgumentNullException(nameof(provider));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal LayerEffectDescriptor(string placeholderFor, LayerEffectProvider provider)
|
||||||
|
{
|
||||||
|
PlaceholderFor = placeholderFor ?? throw new ArgumentNullException(nameof(placeholderFor));
|
||||||
|
Provider = provider ?? throw new ArgumentNullException(nameof(provider));
|
||||||
|
DisplayName = "Missing effect";
|
||||||
|
Description = "This effect could not be loaded";
|
||||||
|
Icon = "FileQuestion";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -49,68 +57,55 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the GUID this descriptor is acting as a placeholder for. If null, this descriptor is not a placeholder
|
/// Gets the GUID this descriptor is acting as a placeholder for. If null, this descriptor is not a placeholder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? PlaceholderFor { get; internal set; }
|
public string? PlaceholderFor { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an instance of the described effect and applies it to the render element
|
/// Creates an instance of the described effect and applies it to the render element
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal void CreateInstance(RenderProfileElement renderElement, LayerEffectEntity? entity)
|
public BaseLayerEffect CreateInstance(RenderProfileElement renderElement, LayerEffectEntity? entity)
|
||||||
{
|
{
|
||||||
|
if (PlaceholderFor != null)
|
||||||
|
{
|
||||||
|
if (entity == null)
|
||||||
|
throw new ArtemisCoreException("Cannot create a placeholder for a layer effect that wasn't loaded from an entity");
|
||||||
|
|
||||||
|
return CreatePlaceHolderInstance(renderElement, entity);
|
||||||
|
}
|
||||||
|
|
||||||
if (LayerEffectType == null)
|
if (LayerEffectType == null)
|
||||||
throw new ArtemisCoreException("Cannot create an instance of a layer effect because this descriptor is not a placeholder but is still missing its LayerEffectType");
|
throw new ArtemisCoreException("Cannot create an instance of a layer effect because this descriptor is not a placeholder but is still missing its LayerEffectType");
|
||||||
|
|
||||||
if (entity == null)
|
BaseLayerEffect effect = (BaseLayerEffect) Provider.Plugin.Kernel!.Get(LayerEffectType);
|
||||||
|
effect.ProfileElement = renderElement;
|
||||||
|
effect.Descriptor = this;
|
||||||
|
if (entity != null)
|
||||||
{
|
{
|
||||||
entity = new LayerEffectEntity
|
effect.LayerEffectEntity = entity;
|
||||||
{
|
effect.Load();
|
||||||
Id = Guid.NewGuid(),
|
effect.Initialize();
|
||||||
Suspended = false,
|
|
||||||
Order = renderElement.LayerEffects.Count + 1,
|
|
||||||
ProviderId = Provider.Id,
|
|
||||||
EffectType = LayerEffectType.FullName
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Skip effects already on the element
|
effect.LayerEffectEntity = new LayerEffectEntity();
|
||||||
if (renderElement.LayerEffects.Any(e => e.LayerEffectEntity.Id == entity.Id))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PlaceholderFor != null)
|
|
||||||
{
|
|
||||||
CreatePlaceHolderInstance(renderElement, entity);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseLayerEffect effect = (BaseLayerEffect) Provider.Plugin.Kernel!.Get(LayerEffectType);
|
|
||||||
effect.ProfileElement = renderElement;
|
|
||||||
effect.LayerEffectEntity = entity;
|
|
||||||
effect.Order = entity.Order;
|
|
||||||
effect.Name = entity.Name;
|
|
||||||
effect.Suspended = entity.Suspended;
|
|
||||||
effect.Descriptor = this;
|
|
||||||
|
|
||||||
effect.Initialize();
|
effect.Initialize();
|
||||||
effect.Update(0);
|
effect.Save();
|
||||||
|
|
||||||
renderElement.ActivateLayerEffect(effect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreatePlaceHolderInstance(RenderProfileElement renderElement, LayerEffectEntity entity)
|
return effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseLayerEffect CreatePlaceHolderInstance(RenderProfileElement renderElement, LayerEffectEntity entity)
|
||||||
{
|
{
|
||||||
if (PlaceholderFor == null)
|
if (PlaceholderFor == null)
|
||||||
throw new ArtemisCoreException("Cannot create a placeholder instance using a layer effect descriptor that is not a placeholder for anything");
|
throw new ArtemisCoreException("Cannot create a placeholder instance using a layer effect descriptor that is not a placeholder for anything");
|
||||||
|
|
||||||
PlaceholderLayerEffect effect = new(entity, PlaceholderFor)
|
PlaceholderLayerEffect effect = new(entity, PlaceholderFor)
|
||||||
{
|
{
|
||||||
ProfileElement = renderElement,
|
ProfileElement = renderElement,
|
||||||
Descriptor = this
|
Descriptor = this
|
||||||
};
|
};
|
||||||
effect.Initialize();
|
effect.Initialize();
|
||||||
renderElement.ActivateLayerEffect(effect);
|
|
||||||
|
|
||||||
if (renderElement.ShouldBeEnabled)
|
return effect;
|
||||||
effect.InternalEnable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -16,7 +16,6 @@ namespace Artemis.Core.LayerEffects.Placeholder
|
|||||||
LayerEffectEntity = originalEntity;
|
LayerEffectEntity = originalEntity;
|
||||||
Order = OriginalEntity.Order;
|
Order = OriginalEntity.Order;
|
||||||
Name = OriginalEntity.Name;
|
Name = OriginalEntity.Name;
|
||||||
Suspended = OriginalEntity.Suspended;
|
|
||||||
HasBeenRenamed = OriginalEntity.HasBeenRenamed;
|
HasBeenRenamed = OriginalEntity.HasBeenRenamed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +57,7 @@ namespace Artemis.Core.LayerEffects.Placeholder
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is in place so that the UI has something to show
|
/// This is in place so that the UI has something to show
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class PlaceholderProperties : LayerPropertyGroup
|
internal class PlaceholderProperties : LayerEffectPropertyGroup
|
||||||
{
|
{
|
||||||
protected override void PopulateDefaults()
|
protected override void PopulateDefaults()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4,11 +4,7 @@
|
|||||||
{
|
{
|
||||||
public static LayerEffectDescriptor Create(string missingProviderId)
|
public static LayerEffectDescriptor Create(string missingProviderId)
|
||||||
{
|
{
|
||||||
LayerEffectDescriptor descriptor = new("Missing effect", "This effect could not be loaded", "FileQuestion", null, Constants.EffectPlaceholderPlugin)
|
LayerEffectDescriptor descriptor = new(missingProviderId, Constants.EffectPlaceholderPlugin);
|
||||||
{
|
|
||||||
PlaceholderFor = missingProviderId
|
|
||||||
};
|
|
||||||
|
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ namespace Artemis.Core.Modules
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allows you to add new data to the Artemis data model
|
/// Allows you to add new data to the Artemis data model
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class Module<T> : Module where T : DataModel
|
public abstract class Module<T> : Module where T : DataModel, new()
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The data model driving this module
|
/// The data model driving this module
|
||||||
@ -79,7 +79,7 @@ namespace Artemis.Core.Modules
|
|||||||
|
|
||||||
internal override void InternalEnable()
|
internal override void InternalEnable()
|
||||||
{
|
{
|
||||||
DataModel = Activator.CreateInstance<T>();
|
DataModel = new T();
|
||||||
DataModel.Module = this;
|
DataModel.Module = this;
|
||||||
DataModel.DataModelDescription = GetDataModelDescription();
|
DataModel.DataModelDescription = GetDataModelDescription();
|
||||||
base.InternalEnable();
|
base.InternalEnable();
|
||||||
@ -310,7 +310,7 @@ namespace Artemis.Core.Modules
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
internal override void InternalEnable()
|
internal override void InternalEnable()
|
||||||
{
|
{
|
||||||
foreach ((DefaultCategoryName categoryName, var path) in _pendingDefaultProfilePaths)
|
foreach ((DefaultCategoryName categoryName, string? path) in _pendingDefaultProfilePaths)
|
||||||
AddDefaultProfile(categoryName, path);
|
AddDefaultProfile(categoryName, path);
|
||||||
_pendingDefaultProfilePaths.Clear();
|
_pendingDefaultProfilePaths.Clear();
|
||||||
|
|
||||||
|
|||||||
@ -71,7 +71,7 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void SaveAllSettings()
|
public void SaveAllSettings()
|
||||||
{
|
{
|
||||||
foreach (var (_, pluginSetting) in _settingEntities)
|
foreach ((string _, IPluginSetting? pluginSetting) in _settingEntities)
|
||||||
pluginSetting.Save();
|
pluginSetting.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -301,7 +301,7 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
public void ReleaseAll()
|
public void ReleaseAll()
|
||||||
{
|
{
|
||||||
foreach (var (device, keys) in _pressedKeys.ToList())
|
foreach ((ArtemisDevice? device, HashSet<KeyboardKey>? keys) in _pressedKeys.ToList())
|
||||||
{
|
{
|
||||||
foreach (KeyboardKey keyboardKey in keys)
|
foreach (KeyboardKey keyboardKey in keys)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -12,7 +12,7 @@ namespace Artemis.Core.Services
|
|||||||
/// <see cref="object" /> or <see langword="null" />.
|
/// <see cref="object" /> or <see langword="null" />.
|
||||||
/// <para>Note: Both will be deserialized and serialized respectively using JSON.</para>
|
/// <para>Note: Both will be deserialized and serialized respectively using JSON.</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DataModelJsonPluginEndPoint<T> : PluginEndPoint where T : DataModel
|
public class DataModelJsonPluginEndPoint<T> : PluginEndPoint where T : DataModel, new()
|
||||||
{
|
{
|
||||||
private readonly Module<T> _module;
|
private readonly Module<T> _module;
|
||||||
|
|
||||||
|
|||||||
@ -51,7 +51,7 @@ namespace Artemis.Core.Services
|
|||||||
/// <param name="module">The module whose datamodel to apply the received JSON to</param>
|
/// <param name="module">The module whose datamodel to apply the received JSON to</param>
|
||||||
/// <param name="endPointName">The name of the end point, must be unique</param>
|
/// <param name="endPointName">The name of the end point, must be unique</param>
|
||||||
/// <returns>The resulting end point</returns>
|
/// <returns>The resulting end point</returns>
|
||||||
DataModelJsonPluginEndPoint<T> AddDataModelJsonEndPoint<T>(Module<T> module, string endPointName) where T : DataModel;
|
DataModelJsonPluginEndPoint<T> AddDataModelJsonEndPoint<T>(Module<T> module, string endPointName) where T : DataModel, new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a new endpoint for the given plugin feature receiving an a <see cref="string" />.
|
/// Adds a new endpoint for the given plugin feature receiving an a <see cref="string" />.
|
||||||
|
|||||||
@ -50,7 +50,7 @@ namespace Artemis.Core.Services
|
|||||||
.WithModule(PluginsModule);
|
.WithModule(PluginsModule);
|
||||||
|
|
||||||
// Add registered modules
|
// Add registered modules
|
||||||
foreach (var webModule in _modules)
|
foreach (WebModuleRegistration? webModule in _modules)
|
||||||
server = server.WithModule(webModule.CreateInstance());
|
server = server.WithModule(webModule.CreateInstance());
|
||||||
|
|
||||||
server = server
|
server = server
|
||||||
@ -132,7 +132,7 @@ namespace Artemis.Core.Services
|
|||||||
return endPoint;
|
return endPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataModelJsonPluginEndPoint<T> AddDataModelJsonEndPoint<T>(Module<T> module, string endPointName) where T : DataModel
|
public DataModelJsonPluginEndPoint<T> AddDataModelJsonEndPoint<T>(Module<T> module, string endPointName) where T : DataModel, new()
|
||||||
{
|
{
|
||||||
if (module == null) throw new ArgumentNullException(nameof(module));
|
if (module == null) throw new ArgumentNullException(nameof(module));
|
||||||
if (endPointName == null) throw new ArgumentNullException(nameof(endPointName));
|
if (endPointName == null) throw new ArgumentNullException(nameof(endPointName));
|
||||||
@ -141,7 +141,7 @@ namespace Artemis.Core.Services
|
|||||||
return endPoint;
|
return endPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleDataModelRequest<T>(Module<T> module, T value) where T : DataModel
|
private void HandleDataModelRequest<T>(Module<T> module, T value) where T : DataModel, new()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ namespace Artemis.Core.Internal
|
|||||||
|
|
||||||
public override void Evaluate()
|
public override void Evaluate()
|
||||||
{
|
{
|
||||||
foreach (var (property, inputPin) in _propertyPins)
|
foreach ((IDataBindingProperty? property, InputPin? inputPin) in _propertyPins)
|
||||||
{
|
{
|
||||||
if (inputPin.ConnectedTo.Any())
|
if (inputPin.ConnectedTo.Any())
|
||||||
_propertyValues[property] = inputPin.Value!;
|
_propertyValues[property] = inputPin.Value!;
|
||||||
@ -35,7 +35,7 @@ namespace Artemis.Core.Internal
|
|||||||
|
|
||||||
public void ApplyToDataBinding()
|
public void ApplyToDataBinding()
|
||||||
{
|
{
|
||||||
foreach (var (property, pendingValue) in _propertyValues)
|
foreach ((IDataBindingProperty? property, object? pendingValue) in _propertyValues)
|
||||||
property.SetValue(pendingValue);
|
property.SetValue(pendingValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,11 +12,8 @@ namespace Artemis.Storage.Entities.Profile.Abstract
|
|||||||
|
|
||||||
public List<LayerEffectEntity> LayerEffects { get; set; }
|
public List<LayerEffectEntity> LayerEffects { get; set; }
|
||||||
public List<PropertyEntity> PropertyEntities { get; set; }
|
public List<PropertyEntity> PropertyEntities { get; set; }
|
||||||
public List<string> ExpandedPropertyGroups { get; set; }
|
|
||||||
|
|
||||||
public IConditionEntity DisplayCondition { get; set; }
|
public IConditionEntity DisplayCondition { get; set; }
|
||||||
public TimelineEntity Timeline { get; set; }
|
public TimelineEntity Timeline { get; set; }
|
||||||
|
|
||||||
public NodeScriptEntity NodeScript { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11,7 +11,6 @@ namespace Artemis.Storage.Entities.Profile
|
|||||||
{
|
{
|
||||||
PropertyEntities = new List<PropertyEntity>();
|
PropertyEntities = new List<PropertyEntity>();
|
||||||
LayerEffects = new List<LayerEffectEntity>();
|
LayerEffects = new List<LayerEffectEntity>();
|
||||||
ExpandedPropertyGroups = new List<string>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
|
|||||||
@ -5,11 +5,9 @@ namespace Artemis.Storage.Entities.Profile
|
|||||||
{
|
{
|
||||||
public class LayerEffectEntity
|
public class LayerEffectEntity
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
|
||||||
public string ProviderId { get; set; }
|
public string ProviderId { get; set; }
|
||||||
public string EffectType { get; set; }
|
public string EffectType { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public bool Suspended { get; set; }
|
|
||||||
public bool HasBeenRenamed { get; set; }
|
public bool HasBeenRenamed { get; set; }
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,6 @@ namespace Artemis.Storage.Entities.Profile
|
|||||||
AdaptionHints = new List<IAdaptionHintEntity>();
|
AdaptionHints = new List<IAdaptionHintEntity>();
|
||||||
PropertyEntities = new List<PropertyEntity>();
|
PropertyEntities = new List<PropertyEntity>();
|
||||||
LayerEffects = new List<LayerEffectEntity>();
|
LayerEffects = new List<LayerEffectEntity>();
|
||||||
ExpandedPropertyGroups = new List<string>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
|
|||||||
@ -17,15 +17,17 @@ namespace Artemis.Storage.Migrations
|
|||||||
foreach (FolderEntity profileEntityFolder in profileEntity.Folders)
|
foreach (FolderEntity profileEntityFolder in profileEntity.Folders)
|
||||||
{
|
{
|
||||||
profileEntityFolder.Suspended = false;
|
profileEntityFolder.Suspended = false;
|
||||||
foreach (LayerEffectEntity layerEffectEntity in profileEntityFolder.LayerEffects)
|
// Commented out during Avalonia port when Suspended was moved into the LayerEffect's LayerProperties
|
||||||
layerEffectEntity.Suspended = false;
|
// foreach (LayerEffectEntity layerEffectEntity in profileEntityFolder.LayerEffects)
|
||||||
|
// layerEffectEntity.Suspended = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (LayerEntity profileEntityLayer in profileEntity.Layers)
|
foreach (LayerEntity profileEntityLayer in profileEntity.Layers)
|
||||||
{
|
{
|
||||||
profileEntityLayer.Suspended = false;
|
profileEntityLayer.Suspended = false;
|
||||||
foreach (LayerEffectEntity layerEffectEntity in profileEntityLayer.LayerEffects)
|
// Commented out during Avalonia port when Suspended was moved into the LayerEffect's LayerProperties
|
||||||
layerEffectEntity.Suspended = false;
|
// foreach (LayerEffectEntity layerEffectEntity in profileEntityLayer.LayerEffects)
|
||||||
|
// layerEffectEntity.Suspended = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
repository.Upsert(profileEntity);
|
repository.Upsert(profileEntity);
|
||||||
|
|||||||
@ -222,8 +222,8 @@
|
|||||||
},
|
},
|
||||||
"FluentAvaloniaUI": {
|
"FluentAvaloniaUI": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "1.3.0",
|
"resolved": "1.3.4",
|
||||||
"contentHash": "xzcsuOswakMpz/EdA59NEOgaCtZ/9zsd5QWTB0YYQqSv1GF95Uk2aMVtO5gtfNrCT4lZvGNWVf3HGjYz9cHovQ==",
|
"contentHash": "INZBxCGyt4Dzm0IaNXoXuU08VUQ62FbeMHPH7MO5W1WeVdU5N8+1YTYfqYAA66twa5wba8MYqezXWhoU8Hq0DQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Avalonia": "0.10.13",
|
"Avalonia": "0.10.13",
|
||||||
"Avalonia.Desktop": "0.10.13",
|
"Avalonia.Desktop": "0.10.13",
|
||||||
@ -1780,7 +1780,7 @@
|
|||||||
"Avalonia.Svg.Skia": "0.10.12",
|
"Avalonia.Svg.Skia": "0.10.12",
|
||||||
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
||||||
"DynamicData": "7.5.4",
|
"DynamicData": "7.5.4",
|
||||||
"FluentAvaloniaUI": "1.3.0",
|
"FluentAvaloniaUI": "1.3.4",
|
||||||
"Flurl.Http": "3.2.0",
|
"Flurl.Http": "3.2.0",
|
||||||
"Live.Avalonia": "1.3.1",
|
"Live.Avalonia": "1.3.1",
|
||||||
"Material.Icons.Avalonia": "1.0.2",
|
"Material.Icons.Avalonia": "1.0.2",
|
||||||
@ -1801,7 +1801,7 @@
|
|||||||
"Avalonia.Svg.Skia": "0.10.12",
|
"Avalonia.Svg.Skia": "0.10.12",
|
||||||
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
||||||
"DynamicData": "7.5.4",
|
"DynamicData": "7.5.4",
|
||||||
"FluentAvaloniaUI": "1.3.0",
|
"FluentAvaloniaUI": "1.3.4",
|
||||||
"Material.Icons.Avalonia": "1.0.2",
|
"Material.Icons.Avalonia": "1.0.2",
|
||||||
"RGB.NET.Core": "1.0.0-prerelease7",
|
"RGB.NET.Core": "1.0.0-prerelease7",
|
||||||
"ReactiveUI": "17.1.50",
|
"ReactiveUI": "17.1.50",
|
||||||
|
|||||||
@ -222,8 +222,8 @@
|
|||||||
},
|
},
|
||||||
"FluentAvaloniaUI": {
|
"FluentAvaloniaUI": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "1.3.0",
|
"resolved": "1.3.4",
|
||||||
"contentHash": "xzcsuOswakMpz/EdA59NEOgaCtZ/9zsd5QWTB0YYQqSv1GF95Uk2aMVtO5gtfNrCT4lZvGNWVf3HGjYz9cHovQ==",
|
"contentHash": "INZBxCGyt4Dzm0IaNXoXuU08VUQ62FbeMHPH7MO5W1WeVdU5N8+1YTYfqYAA66twa5wba8MYqezXWhoU8Hq0DQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Avalonia": "0.10.13",
|
"Avalonia": "0.10.13",
|
||||||
"Avalonia.Desktop": "0.10.13",
|
"Avalonia.Desktop": "0.10.13",
|
||||||
@ -1780,7 +1780,7 @@
|
|||||||
"Avalonia.Svg.Skia": "0.10.12",
|
"Avalonia.Svg.Skia": "0.10.12",
|
||||||
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
||||||
"DynamicData": "7.5.4",
|
"DynamicData": "7.5.4",
|
||||||
"FluentAvaloniaUI": "1.3.0",
|
"FluentAvaloniaUI": "1.3.4",
|
||||||
"Flurl.Http": "3.2.0",
|
"Flurl.Http": "3.2.0",
|
||||||
"Live.Avalonia": "1.3.1",
|
"Live.Avalonia": "1.3.1",
|
||||||
"Material.Icons.Avalonia": "1.0.2",
|
"Material.Icons.Avalonia": "1.0.2",
|
||||||
@ -1801,7 +1801,7 @@
|
|||||||
"Avalonia.Svg.Skia": "0.10.12",
|
"Avalonia.Svg.Skia": "0.10.12",
|
||||||
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
||||||
"DynamicData": "7.5.4",
|
"DynamicData": "7.5.4",
|
||||||
"FluentAvaloniaUI": "1.3.0",
|
"FluentAvaloniaUI": "1.3.4",
|
||||||
"Material.Icons.Avalonia": "1.0.2",
|
"Material.Icons.Avalonia": "1.0.2",
|
||||||
"RGB.NET.Core": "1.0.0-prerelease7",
|
"RGB.NET.Core": "1.0.0-prerelease7",
|
||||||
"ReactiveUI": "17.1.50",
|
"ReactiveUI": "17.1.50",
|
||||||
|
|||||||
@ -23,19 +23,13 @@
|
|||||||
<PackageReference Include="Avalonia.Svg.Skia" Version="0.10.12" />
|
<PackageReference Include="Avalonia.Svg.Skia" Version="0.10.12" />
|
||||||
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="0.10.13.2" />
|
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="0.10.13.2" />
|
||||||
<PackageReference Include="DynamicData" Version="7.5.4" />
|
<PackageReference Include="DynamicData" Version="7.5.4" />
|
||||||
<PackageReference Include="FluentAvaloniaUI" Version="1.3.0" />
|
<PackageReference Include="FluentAvaloniaUI" Version="1.3.4" />
|
||||||
<PackageReference Include="Material.Icons.Avalonia" Version="1.0.2" />
|
<PackageReference Include="Material.Icons.Avalonia" Version="1.0.2" />
|
||||||
<PackageReference Include="ReactiveUI" Version="17.1.50" />
|
<PackageReference Include="ReactiveUI" Version="17.1.50" />
|
||||||
<PackageReference Include="ReactiveUI.Validation" Version="2.2.1" />
|
<PackageReference Include="ReactiveUI.Validation" Version="2.2.1" />
|
||||||
<PackageReference Include="RGB.NET.Core" Version="1.0.0-prerelease7" />
|
<PackageReference Include="RGB.NET.Core" Version="1.0.0-prerelease7" />
|
||||||
<PackageReference Include="SkiaSharp" Version="2.88.0-preview.178" />
|
<PackageReference Include="SkiaSharp" Version="2.88.0-preview.178" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<Page Include="DefaultTypes\DataModel\Display\DefaultDataModelDisplayView.xaml">
|
|
||||||
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
|
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
</Page>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@ -4,5 +4,4 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
x:Class="Artemis.UI.Shared.ArtemisIcon">
|
x:Class="Artemis.UI.Shared.ArtemisIcon">
|
||||||
Welcome to Avalonia!
|
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@ -53,7 +53,7 @@ namespace Artemis.UI.Shared
|
|||||||
{
|
{
|
||||||
SvgSource source = new();
|
SvgSource source = new();
|
||||||
source.Load(iconString);
|
source.Load(iconString);
|
||||||
Content = new SvgImage {Source = source};
|
Content = new Image {Source = new SvgImage {Source = source}};
|
||||||
}
|
}
|
||||||
// An URI pointing to a different kind of image
|
// An URI pointing to a different kind of image
|
||||||
else
|
else
|
||||||
@ -79,10 +79,8 @@ namespace Artemis.UI.Shared
|
|||||||
|
|
||||||
private void OnDetachedFromLogicalTree(object? sender, LogicalTreeAttachmentEventArgs e)
|
private void OnDetachedFromLogicalTree(object? sender, LogicalTreeAttachmentEventArgs e)
|
||||||
{
|
{
|
||||||
if (Content is SvgImage svgImage)
|
if (Content is Image image && image.Source is IDisposable disposable)
|
||||||
svgImage.Source?.Dispose();
|
disposable.Dispose();
|
||||||
else if (Content is Image image)
|
|
||||||
((Bitmap) image.Source).Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
|
|||||||
@ -1,47 +0,0 @@
|
|||||||
<UserControl x:Class="Artemis.UI.Shared.DefaultTypes.DataModel.Display.DefaultDataModelDisplayView"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:local="clr-namespace:Artemis.UI.Shared.DefaultTypes.DataModel.Display"
|
|
||||||
xmlns:s="https://github.com/canton7/Stylet"
|
|
||||||
xmlns:shared="clr-namespace:Artemis.UI.Shared"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
d:DesignHeight="450" d:DesignWidth="800"
|
|
||||||
d:DataContext="{d:DesignInstance local:DefaultDataModelDisplayViewModel}">
|
|
||||||
<UserControl.Resources>
|
|
||||||
<shared:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
|
||||||
</UserControl.Resources>
|
|
||||||
<Grid>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
|
|
||||||
<!-- Prefix -->
|
|
||||||
<TextBlock Grid.Column="0"
|
|
||||||
Text="{Binding PropertyDescription.Prefix}"
|
|
||||||
Visibility="{Binding PropertyDescription.Prefix, Converter={StaticResource NullToVisibilityConverter}}"
|
|
||||||
TextAlignment="Right"
|
|
||||||
Margin="0 0 5 0" />
|
|
||||||
|
|
||||||
<!-- Value -->
|
|
||||||
<TextBlock Grid.Column="1"
|
|
||||||
Text="{Binding DisplayValue, Mode=OneWay}"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Visibility="{Binding ShowToString, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}" />
|
|
||||||
<TextBlock Grid.Column="1"
|
|
||||||
Text="null"
|
|
||||||
FontFamily="Consolas"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Foreground="{DynamicResource MaterialDesignCheckBoxDisabled}"
|
|
||||||
Visibility="{Binding ShowNull, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}" />
|
|
||||||
|
|
||||||
<!-- Affix -->
|
|
||||||
<TextBlock Grid.Column="2"
|
|
||||||
Text="{Binding PropertyDescription.Affix}"
|
|
||||||
Visibility="{Binding PropertyDescription.Affix, Converter={StaticResource NullToVisibilityConverter}}"
|
|
||||||
Margin="5 0 0 0" />
|
|
||||||
</Grid>
|
|
||||||
</UserControl>
|
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.Core.LayerEffects;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Shared.Services.ProfileEditor.Commands;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a profile editor command that can be used to add a layer effect to a profile element.
|
||||||
|
/// </summary>
|
||||||
|
public class AddLayerEffect : IProfileEditorCommand, IDisposable
|
||||||
|
{
|
||||||
|
private readonly RenderProfileElement _renderProfileElement;
|
||||||
|
private readonly BaseLayerEffect _layerEffect;
|
||||||
|
private bool _executed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="AddLayerEffect"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public AddLayerEffect(RenderProfileElement renderProfileElement, BaseLayerEffect layerEffect)
|
||||||
|
{
|
||||||
|
_renderProfileElement = renderProfileElement;
|
||||||
|
_layerEffect = layerEffect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string DisplayName => "Add layer effect";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Execute()
|
||||||
|
{
|
||||||
|
_renderProfileElement.AddLayerEffect(_layerEffect);
|
||||||
|
_executed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Undo()
|
||||||
|
{
|
||||||
|
_renderProfileElement.RemoveLayerEffect(_layerEffect);
|
||||||
|
_executed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (!_executed)
|
||||||
|
_layerEffect.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -62,9 +62,9 @@
|
|||||||
},
|
},
|
||||||
"FluentAvaloniaUI": {
|
"FluentAvaloniaUI": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[1.3.0, )",
|
"requested": "[1.3.4, )",
|
||||||
"resolved": "1.3.0",
|
"resolved": "1.3.4",
|
||||||
"contentHash": "xzcsuOswakMpz/EdA59NEOgaCtZ/9zsd5QWTB0YYQqSv1GF95Uk2aMVtO5gtfNrCT4lZvGNWVf3HGjYz9cHovQ==",
|
"contentHash": "INZBxCGyt4Dzm0IaNXoXuU08VUQ62FbeMHPH7MO5W1WeVdU5N8+1YTYfqYAA66twa5wba8MYqezXWhoU8Hq0DQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Avalonia": "0.10.13",
|
"Avalonia": "0.10.13",
|
||||||
"Avalonia.Desktop": "0.10.13",
|
"Avalonia.Desktop": "0.10.13",
|
||||||
|
|||||||
@ -238,8 +238,8 @@
|
|||||||
},
|
},
|
||||||
"FluentAvaloniaUI": {
|
"FluentAvaloniaUI": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "1.3.0",
|
"resolved": "1.3.4",
|
||||||
"contentHash": "xzcsuOswakMpz/EdA59NEOgaCtZ/9zsd5QWTB0YYQqSv1GF95Uk2aMVtO5gtfNrCT4lZvGNWVf3HGjYz9cHovQ==",
|
"contentHash": "INZBxCGyt4Dzm0IaNXoXuU08VUQ62FbeMHPH7MO5W1WeVdU5N8+1YTYfqYAA66twa5wba8MYqezXWhoU8Hq0DQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Avalonia": "0.10.13",
|
"Avalonia": "0.10.13",
|
||||||
"Avalonia.Desktop": "0.10.13",
|
"Avalonia.Desktop": "0.10.13",
|
||||||
@ -1796,7 +1796,7 @@
|
|||||||
"Avalonia.Svg.Skia": "0.10.12",
|
"Avalonia.Svg.Skia": "0.10.12",
|
||||||
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
||||||
"DynamicData": "7.5.4",
|
"DynamicData": "7.5.4",
|
||||||
"FluentAvaloniaUI": "1.3.0",
|
"FluentAvaloniaUI": "1.3.4",
|
||||||
"Flurl.Http": "3.2.0",
|
"Flurl.Http": "3.2.0",
|
||||||
"Live.Avalonia": "1.3.1",
|
"Live.Avalonia": "1.3.1",
|
||||||
"Material.Icons.Avalonia": "1.0.2",
|
"Material.Icons.Avalonia": "1.0.2",
|
||||||
@ -1817,7 +1817,7 @@
|
|||||||
"Avalonia.Svg.Skia": "0.10.12",
|
"Avalonia.Svg.Skia": "0.10.12",
|
||||||
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
||||||
"DynamicData": "7.5.4",
|
"DynamicData": "7.5.4",
|
||||||
"FluentAvaloniaUI": "1.3.0",
|
"FluentAvaloniaUI": "1.3.4",
|
||||||
"Material.Icons.Avalonia": "1.0.2",
|
"Material.Icons.Avalonia": "1.0.2",
|
||||||
"RGB.NET.Core": "1.0.0-prerelease7",
|
"RGB.NET.Core": "1.0.0-prerelease7",
|
||||||
"ReactiveUI": "17.1.50",
|
"ReactiveUI": "17.1.50",
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
<PackageReference Include="Avalonia.Svg.Skia" Version="0.10.12" />
|
<PackageReference Include="Avalonia.Svg.Skia" Version="0.10.12" />
|
||||||
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="0.10.13.2" />
|
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="0.10.13.2" />
|
||||||
<PackageReference Include="DynamicData" Version="7.5.4" />
|
<PackageReference Include="DynamicData" Version="7.5.4" />
|
||||||
<PackageReference Include="FluentAvaloniaUI" Version="1.3.0" />
|
<PackageReference Include="FluentAvaloniaUI" Version="1.3.4" />
|
||||||
<PackageReference Include="Flurl.Http" Version="3.2.0" />
|
<PackageReference Include="Flurl.Http" Version="3.2.0" />
|
||||||
<PackageReference Include="Live.Avalonia" Version="1.3.1" />
|
<PackageReference Include="Live.Avalonia" Version="1.3.1" />
|
||||||
<PackageReference Include="Material.Icons.Avalonia" Version="1.0.2" />
|
<PackageReference Include="Material.Icons.Avalonia" Version="1.0.2" />
|
||||||
|
|||||||
@ -42,8 +42,6 @@ public static class ArtemisBootstrapper
|
|||||||
_kernel.Load(modules);
|
_kernel.Load(modules);
|
||||||
_kernel.UseNinjectDependencyResolver();
|
_kernel.UseNinjectDependencyResolver();
|
||||||
|
|
||||||
DataModelPicker.DataModelUIService = _kernel.Get<IDataModelUIService>();
|
|
||||||
|
|
||||||
return _kernel;
|
return _kernel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,6 +60,7 @@ public static class ArtemisBootstrapper
|
|||||||
_application.DataContext = rootViewModel;
|
_application.DataContext = rootViewModel;
|
||||||
|
|
||||||
RxApp.DefaultExceptionHandler = Observer.Create<Exception>(DisplayUnhandledException);
|
RxApp.DefaultExceptionHandler = Observer.Create<Exception>(DisplayUnhandledException);
|
||||||
|
DataModelPicker.DataModelUIService = _kernel.Get<IDataModelUIService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DisplayUnhandledException(Exception exception)
|
private static void DisplayUnhandledException(Exception exception)
|
||||||
|
|||||||
@ -1,11 +1,7 @@
|
|||||||
using System;
|
using Artemis.Core;
|
||||||
using System.Collections.Specialized;
|
|
||||||
using System.Linq;
|
|
||||||
using Artemis.Core;
|
|
||||||
using Artemis.UI.Shared.Services.ProfileEditor;
|
using Artemis.UI.Shared.Services.ProfileEditor;
|
||||||
using Artemis.UI.Shared.Services.ProfileEditor.Commands;
|
using Artemis.UI.Shared.Services.ProfileEditor.Commands;
|
||||||
using Artemis.UI.Shared.Services.PropertyInput;
|
using Artemis.UI.Shared.Services.PropertyInput;
|
||||||
using Avalonia.Media;
|
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace Artemis.UI.DefaultTypes.PropertyInput;
|
namespace Artemis.UI.DefaultTypes.PropertyInput;
|
||||||
@ -60,14 +56,10 @@ public class ColorGradientPropertyInputViewModel : PropertyInputViewModel<ColorG
|
|||||||
|
|
||||||
// Make sure something actually changed
|
// Make sure something actually changed
|
||||||
if (Equals(ColorGradient, _originalGradient))
|
if (Equals(ColorGradient, _originalGradient))
|
||||||
{
|
|
||||||
LayerProperty.CurrentValue = _originalGradient;
|
LayerProperty.CurrentValue = _originalGradient;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
// Update the gradient for realsies, giving the command a reference to the old gradient
|
// Update the gradient for realsies, giving the command a reference to the old gradient
|
||||||
ProfileEditorService.ExecuteCommand(new UpdateLayerProperty<ColorGradient>(LayerProperty, ColorGradient, _originalGradient, Time));
|
ProfileEditorService.ExecuteCommand(new UpdateLayerProperty<ColorGradient>(LayerProperty, ColorGradient, _originalGradient, Time));
|
||||||
}
|
|
||||||
|
|
||||||
_originalGradient = null;
|
_originalGradient = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using Artemis.Core;
|
using System;
|
||||||
|
using Artemis.Core;
|
||||||
using Artemis.UI.Shared.Services.ProfileEditor;
|
using Artemis.UI.Shared.Services.ProfileEditor;
|
||||||
using Artemis.UI.Shared.Services.PropertyInput;
|
using Artemis.UI.Shared.Services.PropertyInput;
|
||||||
using ReactiveUI.Validation.Extensions;
|
using ReactiveUI.Validation.Extensions;
|
||||||
@ -11,10 +12,10 @@ public class FloatPropertyInputViewModel : PropertyInputViewModel<float>
|
|||||||
: base(layerProperty, profileEditorService, propertyInputService)
|
: base(layerProperty, profileEditorService, propertyInputService)
|
||||||
{
|
{
|
||||||
if (LayerProperty.PropertyDescription.MinInputValue.IsNumber())
|
if (LayerProperty.PropertyDescription.MinInputValue.IsNumber())
|
||||||
this.ValidationRule(vm => vm.InputValue, i => i >= (float) LayerProperty.PropertyDescription.MinInputValue,
|
this.ValidationRule(vm => vm.InputValue, i => i >= Convert.ToSingle(LayerProperty.PropertyDescription.MinInputValue),
|
||||||
$"Value must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
|
$"Value must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
|
||||||
if (LayerProperty.PropertyDescription.MaxInputValue.IsNumber())
|
if (LayerProperty.PropertyDescription.MaxInputValue.IsNumber())
|
||||||
this.ValidationRule(vm => vm.InputValue, i => i <= (float) LayerProperty.PropertyDescription.MaxInputValue,
|
this.ValidationRule(vm => vm.InputValue, i => i <= Convert.ToSingle(LayerProperty.PropertyDescription.MaxInputValue),
|
||||||
$"Value must be smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
|
$"Value must be smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using Artemis.Core;
|
using System;
|
||||||
|
using Artemis.Core;
|
||||||
using Artemis.UI.Shared.Services.ProfileEditor;
|
using Artemis.UI.Shared.Services.ProfileEditor;
|
||||||
using Artemis.UI.Shared.Services.PropertyInput;
|
using Artemis.UI.Shared.Services.PropertyInput;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
@ -16,17 +17,17 @@ public class FloatRangePropertyInputViewModel : PropertyInputViewModel<FloatRang
|
|||||||
|
|
||||||
if (LayerProperty.PropertyDescription.MinInputValue.IsNumber())
|
if (LayerProperty.PropertyDescription.MinInputValue.IsNumber())
|
||||||
{
|
{
|
||||||
this.ValidationRule(vm => vm.Start, i => i >= (float) LayerProperty.PropertyDescription.MinInputValue,
|
this.ValidationRule(vm => vm.Start, i => i >= Convert.ToSingle(LayerProperty.PropertyDescription.MinInputValue),
|
||||||
$"Start value must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
|
$"Start value must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
|
||||||
this.ValidationRule(vm => vm.End, i => i >= (float) LayerProperty.PropertyDescription.MinInputValue,
|
this.ValidationRule(vm => vm.End, i => i >= Convert.ToSingle(LayerProperty.PropertyDescription.MinInputValue),
|
||||||
$"End value must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
|
$"End value must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LayerProperty.PropertyDescription.MaxInputValue.IsNumber())
|
if (LayerProperty.PropertyDescription.MaxInputValue.IsNumber())
|
||||||
{
|
{
|
||||||
this.ValidationRule(vm => vm.Start, i => i < (float) LayerProperty.PropertyDescription.MaxInputValue,
|
this.ValidationRule(vm => vm.Start, i => i < Convert.ToSingle(LayerProperty.PropertyDescription.MaxInputValue),
|
||||||
$"Start value must be smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
|
$"Start value must be smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
|
||||||
this.ValidationRule(vm => vm.End, i => i < (float) LayerProperty.PropertyDescription.MaxInputValue,
|
this.ValidationRule(vm => vm.End, i => i < Convert.ToSingle(LayerProperty.PropertyDescription.MaxInputValue),
|
||||||
$"End value must be smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
|
$"End value must be smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using Artemis.Core;
|
using System;
|
||||||
|
using Artemis.Core;
|
||||||
using Artemis.UI.Shared.Services.ProfileEditor;
|
using Artemis.UI.Shared.Services.ProfileEditor;
|
||||||
using Artemis.UI.Shared.Services.PropertyInput;
|
using Artemis.UI.Shared.Services.PropertyInput;
|
||||||
using ReactiveUI.Validation.Extensions;
|
using ReactiveUI.Validation.Extensions;
|
||||||
@ -11,10 +12,10 @@ public class IntPropertyInputViewModel : PropertyInputViewModel<int>
|
|||||||
: base(layerProperty, profileEditorService, propertyInputService)
|
: base(layerProperty, profileEditorService, propertyInputService)
|
||||||
{
|
{
|
||||||
if (LayerProperty.PropertyDescription.MinInputValue.IsNumber())
|
if (LayerProperty.PropertyDescription.MinInputValue.IsNumber())
|
||||||
this.ValidationRule(vm => vm.InputValue, i => i >= (int) LayerProperty.PropertyDescription.MinInputValue,
|
this.ValidationRule(vm => vm.InputValue, i => i >= Convert.ToInt32(LayerProperty.PropertyDescription.MinInputValue),
|
||||||
$"Value must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
|
$"Value must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
|
||||||
if (LayerProperty.PropertyDescription.MaxInputValue.IsNumber())
|
if (LayerProperty.PropertyDescription.MaxInputValue.IsNumber())
|
||||||
this.ValidationRule(vm => vm.InputValue, i => i < (int) LayerProperty.PropertyDescription.MaxInputValue,
|
this.ValidationRule(vm => vm.InputValue, i => i < Convert.ToInt32(LayerProperty.PropertyDescription.MaxInputValue),
|
||||||
$"Value must be smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
|
$"Value must be smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using Artemis.Core;
|
using System;
|
||||||
|
using Artemis.Core;
|
||||||
using Artemis.UI.Shared.Services.ProfileEditor;
|
using Artemis.UI.Shared.Services.ProfileEditor;
|
||||||
using Artemis.UI.Shared.Services.PropertyInput;
|
using Artemis.UI.Shared.Services.PropertyInput;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
@ -16,17 +17,17 @@ public class IntRangePropertyInputViewModel : PropertyInputViewModel<IntRange>
|
|||||||
|
|
||||||
if (LayerProperty.PropertyDescription.MinInputValue.IsNumber())
|
if (LayerProperty.PropertyDescription.MinInputValue.IsNumber())
|
||||||
{
|
{
|
||||||
this.ValidationRule(vm => vm.Start, i => i >= (int) LayerProperty.PropertyDescription.MinInputValue,
|
this.ValidationRule(vm => vm.Start, i => i >= Convert.ToInt32(LayerProperty.PropertyDescription.MinInputValue),
|
||||||
$"Start value must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
|
$"Start value must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
|
||||||
this.ValidationRule(vm => vm.End, i => i >= (int)LayerProperty.PropertyDescription.MinInputValue,
|
this.ValidationRule(vm => vm.End, i => i >= Convert.ToInt32(LayerProperty.PropertyDescription.MinInputValue),
|
||||||
$"End value must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
|
$"End value must be equal to or greater than {LayerProperty.PropertyDescription.MinInputValue}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LayerProperty.PropertyDescription.MaxInputValue.IsNumber())
|
if (LayerProperty.PropertyDescription.MaxInputValue.IsNumber())
|
||||||
{
|
{
|
||||||
this.ValidationRule(vm => vm.Start, i => i < (int)LayerProperty.PropertyDescription.MaxInputValue,
|
this.ValidationRule(vm => vm.Start, i => i < Convert.ToInt32(LayerProperty.PropertyDescription.MaxInputValue),
|
||||||
$"Start value must be smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
|
$"Start value must be smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
|
||||||
this.ValidationRule(vm => vm.End, i => i < (int) LayerProperty.PropertyDescription.MaxInputValue,
|
this.ValidationRule(vm => vm.End, i => i < Convert.ToInt32(LayerProperty.PropertyDescription.MaxInputValue),
|
||||||
$"End value must be smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
|
$"End value must be smaller than {LayerProperty.PropertyDescription.MaxInputValue}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -77,7 +77,7 @@ namespace Artemis.UI.Screens.Device
|
|||||||
|
|
||||||
await _windowService.CreateContentDialog()
|
await _windowService.CreateContentDialog()
|
||||||
.WithTitle($"{Device.RgbDevice.DeviceInfo.DeviceName} - Detect input")
|
.WithTitle($"{Device.RgbDevice.DeviceInfo.DeviceName} - Detect input")
|
||||||
.WithViewModel<DeviceDetectInputViewModel>(out var viewModel, ("device", Device))
|
.WithViewModel<DeviceDetectInputViewModel>(out DeviceDetectInputViewModel? viewModel, ("device", Device))
|
||||||
.WithCloseButtonText("Cancel")
|
.WithCloseButtonText("Cancel")
|
||||||
.ShowAsync();
|
.ShowAsync();
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,64 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
||||||
|
xmlns:layerEffects="clr-namespace:Artemis.Core.LayerEffects;assembly=Artemis.Core"
|
||||||
|
xmlns:dialogs="clr-namespace:Artemis.UI.Screens.ProfileEditor.Properties.Dialogs"
|
||||||
|
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
|
||||||
|
x:Class="Artemis.UI.Screens.ProfileEditor.Properties.Dialogs.AddEffectView"
|
||||||
|
x:DataType="dialogs:AddEffectViewModel"
|
||||||
|
Width="500">
|
||||||
|
<Grid RowDefinitions="Auto,*">
|
||||||
|
<TextBox Name="SearchBox" Text="{CompiledBinding SearchText}" Margin="0 0 0 15" Watermark="Search"></TextBox>
|
||||||
|
<ListBox Name="EffectDescriptorsList"
|
||||||
|
Grid.Row="1"
|
||||||
|
Items="{CompiledBinding LayerEffectDescriptors}"
|
||||||
|
IsVisible="{CompiledBinding LayerEffectDescriptors.Count}"
|
||||||
|
Height="300">
|
||||||
|
|
||||||
|
<ListBox.DataTemplates>
|
||||||
|
<DataTemplate DataType="{x:Type layerEffects:LayerEffectDescriptor}">
|
||||||
|
<Grid RowDefinitions="Auto,*"
|
||||||
|
ColumnDefinitions="Auto,Auto"
|
||||||
|
Background="Transparent"
|
||||||
|
PointerReleased="InputElement_OnPointerReleased"
|
||||||
|
Margin="0 4"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<shared:ArtemisIcon Grid.Column="0"
|
||||||
|
Grid.RowSpan="2"
|
||||||
|
Icon="{CompiledBinding Icon}"
|
||||||
|
Width="24"
|
||||||
|
Height="24"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="0 0 15 0" />
|
||||||
|
<TextBlock Grid.Column="1"
|
||||||
|
Grid.Row="0"
|
||||||
|
Classes="BodyStrongTextBlockStyle"
|
||||||
|
Text="{CompiledBinding DisplayName}"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
Width="450"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<TextBlock Grid.Column="1"
|
||||||
|
Grid.Row="1"
|
||||||
|
Foreground="{DynamicResource TextFillColorSecondary}"
|
||||||
|
Text="{CompiledBinding Description}"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Width="450"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.DataTemplates>
|
||||||
|
</ListBox>
|
||||||
|
<Grid Grid.Row="1" Height="300">
|
||||||
|
<StackPanel VerticalAlignment="Center"
|
||||||
|
Spacing="20"
|
||||||
|
IsVisible="{CompiledBinding !LayerEffectDescriptors.Count}">
|
||||||
|
<avalonia:MaterialIcon Kind="CloseCircle" Width="32" Height="32"></avalonia:MaterialIcon>
|
||||||
|
<TextBlock Classes="h5" TextAlignment="Center">None of the effects match your search</TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
using Artemis.Core.LayerEffects;
|
||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Input;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.ProfileEditor.Properties.Dialogs;
|
||||||
|
|
||||||
|
public class AddEffectView : ReactiveUserControl<AddEffectViewModel>
|
||||||
|
{
|
||||||
|
public AddEffectView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InputElement_OnPointerReleased(object? sender, PointerReleasedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is not IDataContextProvider {DataContext: LayerEffectDescriptor descriptor} || ViewModel == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ViewModel?.AddLayerEffect(descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.Core.LayerEffects;
|
||||||
|
using Artemis.Core.Services;
|
||||||
|
using Artemis.UI.Shared;
|
||||||
|
using Artemis.UI.Shared.Services.ProfileEditor;
|
||||||
|
using Artemis.UI.Shared.Services.ProfileEditor.Commands;
|
||||||
|
using DynamicData;
|
||||||
|
using ReactiveUI;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.ProfileEditor.Properties.Dialogs;
|
||||||
|
|
||||||
|
public class AddEffectViewModel : ContentDialogViewModelBase
|
||||||
|
{
|
||||||
|
private readonly RenderProfileElement _renderProfileElement;
|
||||||
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
|
private string? _searchText;
|
||||||
|
|
||||||
|
public AddEffectViewModel(RenderProfileElement renderProfileElement, IProfileEditorService profileEditorService, ILayerEffectService layerEffectService)
|
||||||
|
{
|
||||||
|
_renderProfileElement = renderProfileElement;
|
||||||
|
_profileEditorService = profileEditorService;
|
||||||
|
|
||||||
|
SourceList<LayerEffectDescriptor> layerEffectSourceList = new();
|
||||||
|
layerEffectSourceList.AddRange(layerEffectService.GetLayerEffects());
|
||||||
|
IObservable<Func<LayerEffectDescriptor, bool>> layerEffectFilter = this.WhenAnyValue(vm => vm.SearchText).Select(CreatePredicate);
|
||||||
|
|
||||||
|
layerEffectSourceList.Connect()
|
||||||
|
.Filter(layerEffectFilter)
|
||||||
|
.Bind(out ReadOnlyObservableCollection<LayerEffectDescriptor> layerEffectDescriptors)
|
||||||
|
.Subscribe();
|
||||||
|
LayerEffectDescriptors = layerEffectDescriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReadOnlyObservableCollection<LayerEffectDescriptor> LayerEffectDescriptors { get; }
|
||||||
|
|
||||||
|
public string? SearchText
|
||||||
|
{
|
||||||
|
get => _searchText;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _searchText, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddLayerEffect(LayerEffectDescriptor descriptor)
|
||||||
|
{
|
||||||
|
BaseLayerEffect layerEffect = descriptor.CreateInstance(_renderProfileElement, null);
|
||||||
|
_profileEditorService.ExecuteCommand(new AddLayerEffect(_renderProfileElement, layerEffect));
|
||||||
|
ContentDialog?.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Func<LayerEffectDescriptor, bool> CreatePredicate(string? search)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(search))
|
||||||
|
return _ => true;
|
||||||
|
|
||||||
|
search = search.Trim();
|
||||||
|
return data => data.DisplayName.Contains(search, StringComparison.InvariantCultureIgnoreCase) ||
|
||||||
|
data.Description.Contains(search, StringComparison.InvariantCultureIgnoreCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -29,6 +29,7 @@
|
|||||||
Name="TreeScrollViewer"
|
Name="TreeScrollViewer"
|
||||||
Offset="{CompiledBinding #TimelineScrollViewer.Offset, Mode=OneWay}"
|
Offset="{CompiledBinding #TimelineScrollViewer.Offset, Mode=OneWay}"
|
||||||
Background="{DynamicResource CardStrokeColorDefaultSolidBrush}">
|
Background="{DynamicResource CardStrokeColorDefaultSolidBrush}">
|
||||||
|
<Grid RowDefinitions="*,Auto">
|
||||||
<ItemsControl Items="{CompiledBinding PropertyGroupViewModels}" Padding="0 0 8 0">
|
<ItemsControl Items="{CompiledBinding PropertyGroupViewModels}" Padding="0 0 8 0">
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<TreeDataTemplate DataType="{x:Type local:PropertyGroupViewModel}" ItemsSource="{CompiledBinding Children}">
|
<TreeDataTemplate DataType="{x:Type local:PropertyGroupViewModel}" ItemsSource="{CompiledBinding Children}">
|
||||||
@ -36,6 +37,14 @@
|
|||||||
</TreeDataTemplate>
|
</TreeDataTemplate>
|
||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
|
<Button Grid.Row="1"
|
||||||
|
Command="{CompiledBinding AddEffect}"
|
||||||
|
Margin="4"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
HorizontalAlignment="Right">
|
||||||
|
Add new effect
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
@ -47,7 +56,7 @@
|
|||||||
|
|
||||||
<ContentControl Grid.Column="2"
|
<ContentControl Grid.Column="2"
|
||||||
IsVisible="{CompiledBinding DataBindingViewModel, Converter={x:Static ObjectConverters.IsNotNull}}"
|
IsVisible="{CompiledBinding DataBindingViewModel, Converter={x:Static ObjectConverters.IsNotNull}}"
|
||||||
Content="{CompiledBinding DataBindingViewModel}"/>
|
Content="{CompiledBinding DataBindingViewModel}" />
|
||||||
|
|
||||||
<!-- Horizontal scrolling -->
|
<!-- Horizontal scrolling -->
|
||||||
<ScrollViewer Grid.Column="2"
|
<ScrollViewer Grid.Column="2"
|
||||||
|
|||||||
@ -5,6 +5,7 @@ using System.Linq;
|
|||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.LayerBrushes;
|
using Artemis.Core.LayerBrushes;
|
||||||
using Artemis.Core.LayerEffects;
|
using Artemis.Core.LayerEffects;
|
||||||
@ -12,8 +13,12 @@ using Artemis.Core.Services;
|
|||||||
using Artemis.UI.Ninject.Factories;
|
using Artemis.UI.Ninject.Factories;
|
||||||
using Artemis.UI.Screens.ProfileEditor.Playback;
|
using Artemis.UI.Screens.ProfileEditor.Playback;
|
||||||
using Artemis.UI.Screens.ProfileEditor.Properties.DataBinding;
|
using Artemis.UI.Screens.ProfileEditor.Properties.DataBinding;
|
||||||
|
using Artemis.UI.Screens.ProfileEditor.Properties.Dialogs;
|
||||||
using Artemis.UI.Screens.ProfileEditor.Properties.Timeline;
|
using Artemis.UI.Screens.ProfileEditor.Properties.Timeline;
|
||||||
|
using Artemis.UI.Screens.Sidebar;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
|
using Artemis.UI.Shared.Services;
|
||||||
|
using Artemis.UI.Shared.Services.Builders;
|
||||||
using Artemis.UI.Shared.Services.ProfileEditor;
|
using Artemis.UI.Shared.Services.ProfileEditor;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
|
||||||
@ -23,6 +28,8 @@ public class PropertiesViewModel : ActivatableViewModelBase
|
|||||||
{
|
{
|
||||||
private readonly Dictionary<LayerPropertyGroup, PropertyGroupViewModel> _cachedPropertyViewModels;
|
private readonly Dictionary<LayerPropertyGroup, PropertyGroupViewModel> _cachedPropertyViewModels;
|
||||||
private readonly IDataBindingVmFactory _dataBindingVmFactory;
|
private readonly IDataBindingVmFactory _dataBindingVmFactory;
|
||||||
|
private readonly IWindowService _windowService;
|
||||||
|
private readonly ILayerEffectService _layerEffectService;
|
||||||
private readonly ILayerPropertyVmFactory _layerPropertyVmFactory;
|
private readonly ILayerPropertyVmFactory _layerPropertyVmFactory;
|
||||||
private readonly IProfileEditorService _profileEditorService;
|
private readonly IProfileEditorService _profileEditorService;
|
||||||
private readonly ISettingsService _settingsService;
|
private readonly ISettingsService _settingsService;
|
||||||
@ -38,18 +45,22 @@ public class PropertiesViewModel : ActivatableViewModelBase
|
|||||||
ISettingsService settingsService,
|
ISettingsService settingsService,
|
||||||
ILayerPropertyVmFactory layerPropertyVmFactory,
|
ILayerPropertyVmFactory layerPropertyVmFactory,
|
||||||
IDataBindingVmFactory dataBindingVmFactory,
|
IDataBindingVmFactory dataBindingVmFactory,
|
||||||
|
IWindowService windowService,
|
||||||
|
ILayerEffectService layerEffectService,
|
||||||
PlaybackViewModel playbackViewModel)
|
PlaybackViewModel playbackViewModel)
|
||||||
{
|
{
|
||||||
_profileEditorService = profileEditorService;
|
_profileEditorService = profileEditorService;
|
||||||
_settingsService = settingsService;
|
_settingsService = settingsService;
|
||||||
_layerPropertyVmFactory = layerPropertyVmFactory;
|
_layerPropertyVmFactory = layerPropertyVmFactory;
|
||||||
_dataBindingVmFactory = dataBindingVmFactory;
|
_dataBindingVmFactory = dataBindingVmFactory;
|
||||||
|
_windowService = windowService;
|
||||||
|
_layerEffectService = layerEffectService;
|
||||||
_cachedPropertyViewModels = new Dictionary<LayerPropertyGroup, PropertyGroupViewModel>();
|
_cachedPropertyViewModels = new Dictionary<LayerPropertyGroup, PropertyGroupViewModel>();
|
||||||
|
|
||||||
PropertyGroupViewModels = new ObservableCollection<PropertyGroupViewModel>();
|
PropertyGroupViewModels = new ObservableCollection<PropertyGroupViewModel>();
|
||||||
PlaybackViewModel = playbackViewModel;
|
PlaybackViewModel = playbackViewModel;
|
||||||
TimelineViewModel = layerPropertyVmFactory.TimelineViewModel(PropertyGroupViewModels);
|
TimelineViewModel = layerPropertyVmFactory.TimelineViewModel(PropertyGroupViewModels);
|
||||||
|
AddEffect = ReactiveCommand.CreateFromTask(ExecuteAddEffect);
|
||||||
// React to service profile element changes as long as the VM is active
|
// React to service profile element changes as long as the VM is active
|
||||||
this.WhenActivated(d =>
|
this.WhenActivated(d =>
|
||||||
{
|
{
|
||||||
@ -86,6 +97,7 @@ public class PropertiesViewModel : ActivatableViewModelBase
|
|||||||
public ObservableCollection<PropertyGroupViewModel> PropertyGroupViewModels { get; }
|
public ObservableCollection<PropertyGroupViewModel> PropertyGroupViewModels { get; }
|
||||||
public PlaybackViewModel PlaybackViewModel { get; }
|
public PlaybackViewModel PlaybackViewModel { get; }
|
||||||
public TimelineViewModel TimelineViewModel { get; }
|
public TimelineViewModel TimelineViewModel { get; }
|
||||||
|
public ReactiveCommand<Unit, Unit> AddEffect { get; }
|
||||||
|
|
||||||
public DataBindingViewModel? DataBindingViewModel
|
public DataBindingViewModel? DataBindingViewModel
|
||||||
{
|
{
|
||||||
@ -102,6 +114,17 @@ public class PropertiesViewModel : ActivatableViewModelBase
|
|||||||
public IObservable<bool> Playing => _profileEditorService.Playing;
|
public IObservable<bool> Playing => _profileEditorService.Playing;
|
||||||
public PluginSetting<double> PropertiesTreeWidth => _settingsService.GetSetting("ProfileEditor.PropertiesTreeWidth", 500.0);
|
public PluginSetting<double> PropertiesTreeWidth => _settingsService.GetSetting("ProfileEditor.PropertiesTreeWidth", 500.0);
|
||||||
|
|
||||||
|
private async Task ExecuteAddEffect()
|
||||||
|
{
|
||||||
|
if (ProfileElement == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await _windowService.CreateContentDialog()
|
||||||
|
.WithTitle("Add layer effect")
|
||||||
|
.WithViewModel(out AddEffectViewModel _, ("renderProfileElement", ProfileElement))
|
||||||
|
.WithCloseButtonText("Cancel")
|
||||||
|
.ShowAsync();
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdatePropertyGroups()
|
private void UpdatePropertyGroups()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -38,18 +38,36 @@ public class PropertyGroupViewModel : ViewModelBase, IDisposable
|
|||||||
PopulateChildren();
|
PopulateChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PropertyGroupViewModel(LayerPropertyGroup layerPropertyGroup, ILayerPropertyVmFactory layerPropertyVmFactory, IPropertyInputService propertyInputService,
|
public PropertyGroupViewModel(LayerPropertyGroup layerPropertyGroup, ILayerPropertyVmFactory layerPropertyVmFactory, IPropertyInputService propertyInputService, BaseLayerBrush layerBrush)
|
||||||
BaseLayerBrush layerBrush)
|
|
||||||
: this(layerPropertyGroup, layerPropertyVmFactory, propertyInputService)
|
|
||||||
{
|
{
|
||||||
|
_layerPropertyVmFactory = layerPropertyVmFactory;
|
||||||
|
_propertyInputService = propertyInputService;
|
||||||
LayerBrush = layerBrush;
|
LayerBrush = layerBrush;
|
||||||
|
Children = new ObservableCollection<ViewModelBase>();
|
||||||
|
LayerPropertyGroup = layerPropertyGroup;
|
||||||
|
TreeGroupViewModel = layerPropertyVmFactory.TreeGroupViewModel(this);
|
||||||
|
TimelineGroupViewModel = layerPropertyVmFactory.TimelineGroupViewModel(this);
|
||||||
|
|
||||||
|
LayerPropertyGroup.VisibilityChanged += LayerPropertyGroupOnVisibilityChanged;
|
||||||
|
_isVisible = !LayerPropertyGroup.IsHidden;
|
||||||
|
|
||||||
|
PopulateChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PropertyGroupViewModel(LayerPropertyGroup layerPropertyGroup, ILayerPropertyVmFactory layerPropertyVmFactory, IPropertyInputService propertyInputService,
|
public PropertyGroupViewModel(LayerPropertyGroup layerPropertyGroup, ILayerPropertyVmFactory layerPropertyVmFactory, IPropertyInputService propertyInputService, BaseLayerEffect layerEffect)
|
||||||
BaseLayerEffect layerEffect)
|
|
||||||
: this(layerPropertyGroup, layerPropertyVmFactory, propertyInputService)
|
|
||||||
{
|
{
|
||||||
|
_layerPropertyVmFactory = layerPropertyVmFactory;
|
||||||
|
_propertyInputService = propertyInputService;
|
||||||
LayerEffect = layerEffect;
|
LayerEffect = layerEffect;
|
||||||
|
Children = new ObservableCollection<ViewModelBase>();
|
||||||
|
LayerPropertyGroup = layerPropertyGroup;
|
||||||
|
TreeGroupViewModel = layerPropertyVmFactory.TreeGroupViewModel(this);
|
||||||
|
TimelineGroupViewModel = layerPropertyVmFactory.TimelineGroupViewModel(this);
|
||||||
|
|
||||||
|
LayerPropertyGroup.VisibilityChanged += LayerPropertyGroupOnVisibilityChanged;
|
||||||
|
_isVisible = !LayerPropertyGroup.IsHidden;
|
||||||
|
|
||||||
|
PopulateChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableCollection<ViewModelBase> Children { get; }
|
public ObservableCollection<ViewModelBase> Children { get; }
|
||||||
|
|||||||
@ -53,7 +53,7 @@
|
|||||||
<StackPanel Orientation="Horizontal"
|
<StackPanel Orientation="Horizontal"
|
||||||
Margin="0 5"
|
Margin="0 5"
|
||||||
IsVisible="{Binding GroupType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static viewModel:LayerPropertyGroupType.General}}">
|
IsVisible="{Binding GroupType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static viewModel:LayerPropertyGroupType.General}}">
|
||||||
<avalonia:MaterialIcon Kind="HammerWrench" Margin="0 -1 5 0" />
|
<avalonia:MaterialIcon Kind="HammerWrench" Margin="0 0 5 0" />
|
||||||
<TextBlock ToolTip.Tip="{Binding LayerPropertyGroup.GroupDescription.Description}">General</TextBlock>
|
<TextBlock ToolTip.Tip="{Binding LayerPropertyGroup.GroupDescription.Description}">General</TextBlock>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
@ -61,22 +61,23 @@
|
|||||||
<StackPanel Orientation="Horizontal"
|
<StackPanel Orientation="Horizontal"
|
||||||
Margin="0 5"
|
Margin="0 5"
|
||||||
IsVisible="{Binding GroupType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static viewModel:LayerPropertyGroupType.Transform}}">
|
IsVisible="{Binding GroupType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static viewModel:LayerPropertyGroupType.Transform}}">
|
||||||
<avalonia:MaterialIcon Kind="TransitConnectionVariant" Margin="0 -1 5 0" />
|
<avalonia:MaterialIcon Kind="TransitConnectionVariant" Margin="0 0 5 0" />
|
||||||
<TextBlock ToolTip.Tip="{Binding LayerPropertyGroup.GroupDescription.Description}">Transform</TextBlock>
|
<TextBlock ToolTip.Tip="{Binding LayerPropertyGroup.GroupDescription.Description}">Transform</TextBlock>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<!-- Type: LayerBrushRoot -->
|
<!-- Type: LayerBrushRoot -->
|
||||||
<Grid IsVisible="{Binding GroupType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static viewModel:LayerPropertyGroupType.LayerBrushRoot}}"
|
<Grid IsVisible="{Binding GroupType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static viewModel:LayerPropertyGroupType.LayerBrushRoot}}"
|
||||||
|
Height="29"
|
||||||
ColumnDefinitions="Auto,Auto,Auto,*">
|
ColumnDefinitions="Auto,Auto,Auto,*">
|
||||||
<shared:ArtemisIcon Grid.Column="0"
|
<shared:ArtemisIcon Grid.Column="0"
|
||||||
Icon="{Binding LayerBrush.Descriptor.Icon}"
|
Icon="{Binding LayerBrush.Descriptor.Icon}"
|
||||||
Width="16"
|
Width="16"
|
||||||
Height="16"
|
Height="16"
|
||||||
Margin="0 5 5 0" />
|
Margin="0 0 5 0" />
|
||||||
<TextBlock Grid.Column="1"
|
<TextBlock Grid.Column="1"
|
||||||
ToolTip.Tip="{Binding LayerBrush.Descriptor.Description}"
|
ToolTip.Tip="{Binding LayerBrush.Descriptor.Description}"
|
||||||
Margin="0 5 0 0">
|
Margin="0 5 5 0">
|
||||||
Brush - 
|
Brush -
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<TextBlock Grid.Column="2"
|
<TextBlock Grid.Column="2"
|
||||||
Text="{Binding LayerBrush.Descriptor.DisplayName}"
|
Text="{Binding LayerBrush.Descriptor.DisplayName}"
|
||||||
@ -101,8 +102,8 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<!-- Type: LayerEffectRoot -->
|
<!-- Type: LayerEffectRoot -->
|
||||||
<Grid Height="24"
|
<Grid IsVisible="{Binding GroupType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static viewModel:LayerPropertyGroupType.LayerEffectRoot}}"
|
||||||
IsVisible="{Binding GroupType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static viewModel:LayerPropertyGroupType.LayerEffectRoot}}"
|
Height="29"
|
||||||
ColumnDefinitions="Auto,Auto,Auto,Auto,*,Auto">
|
ColumnDefinitions="Auto,Auto,Auto,Auto,*,Auto">
|
||||||
<shared:ArtemisIcon
|
<shared:ArtemisIcon
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
@ -110,7 +111,7 @@
|
|||||||
Icon="{Binding LayerEffect.Descriptor.Icon}"
|
Icon="{Binding LayerEffect.Descriptor.Icon}"
|
||||||
Width="16"
|
Width="16"
|
||||||
Height="16"
|
Height="16"
|
||||||
Margin="0 5 5 0"
|
Margin="0 0 5 0"
|
||||||
Background="Transparent" />
|
Background="Transparent" />
|
||||||
<TextBlock Grid.Column="1" ToolTip.Tip="{Binding LayerEffect.Descriptor.Description}" Margin="0 5 0 0">
|
<TextBlock Grid.Column="1" ToolTip.Tip="{Binding LayerEffect.Descriptor.Description}" Margin="0 5 0 0">
|
||||||
Effect
|
Effect
|
||||||
@ -133,18 +134,23 @@
|
|||||||
Margin="0 5"
|
Margin="0 5"
|
||||||
IsVisible="{Binding LayerEffect.Name, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
|
IsVisible="{Binding LayerEffect.Name, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
|
||||||
|
|
||||||
<StackPanel Grid.Column="5" Orientation="Horizontal">
|
<StackPanel Grid.Column="5" Orientation="Horizontal" Spacing="2">
|
||||||
<ToggleButton
|
<Button Classes="icon-button"
|
||||||
Classes="icon-button"
|
|
||||||
ToolTip.Tip="Toggle suspended state"
|
ToolTip.Tip="Toggle suspended state"
|
||||||
Width="18"
|
Width="24"
|
||||||
Height="18"
|
Height="24"
|
||||||
IsChecked="{Binding !LayerEffect.Suspended}"
|
VerticalAlignment="Center"
|
||||||
VerticalAlignment="Center" Padding="-25"
|
|
||||||
Margin="5 0"
|
|
||||||
Command="{Binding SuspendedToggled}">
|
Command="{Binding SuspendedToggled}">
|
||||||
<avalonia:MaterialIcon Kind="Eye" Height="13" Width="13" />
|
<avalonia:MaterialIcon Kind="EyeOff" Height="16" Width="16" IsVisible="True" />
|
||||||
</ToggleButton>
|
</Button>
|
||||||
|
<Button Classes="icon-button"
|
||||||
|
ToolTip.Tip="Toggle suspended state"
|
||||||
|
Width="24"
|
||||||
|
Height="24"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Command="{Binding SuspendedToggled}">
|
||||||
|
<avalonia:MaterialIcon Kind="Eye" Height="16" Width="16" IsVisible="True" />
|
||||||
|
</Button>
|
||||||
<Button Classes="icon-button"
|
<Button Classes="icon-button"
|
||||||
ToolTip.Tip="Rename"
|
ToolTip.Tip="Rename"
|
||||||
Width="24"
|
Width="24"
|
||||||
|
|||||||
@ -268,7 +268,7 @@
|
|||||||
Items="{CompiledBinding RenderScales}">
|
Items="{CompiledBinding RenderScales}">
|
||||||
<ComboBox.ItemTemplate>
|
<ComboBox.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<TextBlock Text="{Binding [0]}" />
|
<TextBlock Text="{CompiledBinding Display}" />
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ComboBox.ItemTemplate>
|
</ComboBox.ItemTemplate>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
@ -294,7 +294,7 @@
|
|||||||
Items="{CompiledBinding TargetFrameRates}">
|
Items="{CompiledBinding TargetFrameRates}">
|
||||||
<ComboBox.ItemTemplate>
|
<ComboBox.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<TextBlock Text="{Binding [0]}" />
|
<TextBlock Text="{CompiledBinding Display}" />
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ComboBox.ItemTemplate>
|
</ComboBox.ItemTemplate>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
|
|||||||
@ -80,21 +80,21 @@ namespace Artemis.UI.Screens.Settings
|
|||||||
"Vulkan"
|
"Vulkan"
|
||||||
};
|
};
|
||||||
|
|
||||||
public ObservableCollection<(string, double)> RenderScales { get; } = new()
|
public ObservableCollection<RenderSettingViewModel> RenderScales { get; } = new()
|
||||||
{
|
{
|
||||||
new ValueTuple<string, double>("25%", 0.25),
|
new RenderSettingViewModel("25%", 0.25),
|
||||||
new ValueTuple<string, double>("50%", 0.5),
|
new RenderSettingViewModel("50%", 0.5),
|
||||||
new ValueTuple<string, double>("100%", 1)
|
new RenderSettingViewModel("100%", 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
public ObservableCollection<(string, int)> TargetFrameRates { get; } = new()
|
public ObservableCollection<RenderSettingViewModel> TargetFrameRates { get; } = new()
|
||||||
{
|
{
|
||||||
new ValueTuple<string, int>("10 FPS", 10),
|
new RenderSettingViewModel("10 FPS", 10),
|
||||||
new ValueTuple<string, int>("20 FPS", 20),
|
new RenderSettingViewModel("20 FPS", 20),
|
||||||
new ValueTuple<string, int>("30 FPS", 30),
|
new RenderSettingViewModel("30 FPS", 30),
|
||||||
new ValueTuple<string, int>("45 FPS", 45),
|
new RenderSettingViewModel("45 FPS", 45),
|
||||||
new ValueTuple<string, int>("60 FPS (lol)", 60),
|
new RenderSettingViewModel("60 FPS (lol)", 60),
|
||||||
new ValueTuple<string, int>("144 FPS (omegalol)", 144)
|
new RenderSettingViewModel("144 FPS (omegalol)", 144)
|
||||||
};
|
};
|
||||||
|
|
||||||
public LayerBrushDescriptor? SelectedLayerBrushDescriptor
|
public LayerBrushDescriptor? SelectedLayerBrushDescriptor
|
||||||
@ -106,21 +106,23 @@ namespace Artemis.UI.Screens.Settings
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public (string, double)? SelectedRenderScale
|
public RenderSettingViewModel? SelectedRenderScale
|
||||||
{
|
{
|
||||||
get => RenderScales.FirstOrDefault(s => Math.Abs(s.Item2 - CoreRenderScale.Value) < 0.01);
|
get => RenderScales.FirstOrDefault(s => Math.Abs(s.Value - CoreRenderScale.Value) < 0.01);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value != null) CoreRenderScale.Value = value.Value.Item2;
|
if (value != null)
|
||||||
|
CoreRenderScale.Value = value.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public (string, int)? SelectedTargetFrameRate
|
public RenderSettingViewModel? SelectedTargetFrameRate
|
||||||
{
|
{
|
||||||
get => TargetFrameRates.FirstOrDefault(s => s.Item2 == CoreTargetFrameRate.Value);
|
get => TargetFrameRates.FirstOrDefault(s => Math.Abs(s.Value - CoreTargetFrameRate.Value) < 0.01);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value != null) CoreTargetFrameRate.Value = value.Value.Item2;
|
if (value != null)
|
||||||
|
CoreTargetFrameRate.Value = (int) value.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
namespace Artemis.UI.Screens.Settings;
|
||||||
|
|
||||||
|
public class RenderSettingViewModel
|
||||||
|
{
|
||||||
|
public RenderSettingViewModel(string display, double value)
|
||||||
|
{
|
||||||
|
Display = display;
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Display { get; }
|
||||||
|
public double Value { get; }
|
||||||
|
}
|
||||||
@ -96,9 +96,9 @@
|
|||||||
},
|
},
|
||||||
"FluentAvaloniaUI": {
|
"FluentAvaloniaUI": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[1.3.0, )",
|
"requested": "[1.3.4, )",
|
||||||
"resolved": "1.3.0",
|
"resolved": "1.3.4",
|
||||||
"contentHash": "xzcsuOswakMpz/EdA59NEOgaCtZ/9zsd5QWTB0YYQqSv1GF95Uk2aMVtO5gtfNrCT4lZvGNWVf3HGjYz9cHovQ==",
|
"contentHash": "INZBxCGyt4Dzm0IaNXoXuU08VUQ62FbeMHPH7MO5W1WeVdU5N8+1YTYfqYAA66twa5wba8MYqezXWhoU8Hq0DQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Avalonia": "0.10.13",
|
"Avalonia": "0.10.13",
|
||||||
"Avalonia.Desktop": "0.10.13",
|
"Avalonia.Desktop": "0.10.13",
|
||||||
@ -1788,7 +1788,7 @@
|
|||||||
"Avalonia.Svg.Skia": "0.10.12",
|
"Avalonia.Svg.Skia": "0.10.12",
|
||||||
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
||||||
"DynamicData": "7.5.4",
|
"DynamicData": "7.5.4",
|
||||||
"FluentAvaloniaUI": "1.3.0",
|
"FluentAvaloniaUI": "1.3.4",
|
||||||
"Material.Icons.Avalonia": "1.0.2",
|
"Material.Icons.Avalonia": "1.0.2",
|
||||||
"RGB.NET.Core": "1.0.0-prerelease7",
|
"RGB.NET.Core": "1.0.0-prerelease7",
|
||||||
"ReactiveUI": "17.1.50",
|
"ReactiveUI": "17.1.50",
|
||||||
|
|||||||
@ -252,8 +252,8 @@
|
|||||||
},
|
},
|
||||||
"FluentAvaloniaUI": {
|
"FluentAvaloniaUI": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "1.3.0",
|
"resolved": "1.3.4",
|
||||||
"contentHash": "xzcsuOswakMpz/EdA59NEOgaCtZ/9zsd5QWTB0YYQqSv1GF95Uk2aMVtO5gtfNrCT4lZvGNWVf3HGjYz9cHovQ==",
|
"contentHash": "INZBxCGyt4Dzm0IaNXoXuU08VUQ62FbeMHPH7MO5W1WeVdU5N8+1YTYfqYAA66twa5wba8MYqezXWhoU8Hq0DQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Avalonia": "0.10.13",
|
"Avalonia": "0.10.13",
|
||||||
"Avalonia.Desktop": "0.10.13",
|
"Avalonia.Desktop": "0.10.13",
|
||||||
@ -1738,7 +1738,7 @@
|
|||||||
"Avalonia.Svg.Skia": "0.10.12",
|
"Avalonia.Svg.Skia": "0.10.12",
|
||||||
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
"Avalonia.Xaml.Behaviors": "0.10.13.2",
|
||||||
"DynamicData": "7.5.4",
|
"DynamicData": "7.5.4",
|
||||||
"FluentAvaloniaUI": "1.3.0",
|
"FluentAvaloniaUI": "1.3.4",
|
||||||
"Material.Icons.Avalonia": "1.0.2",
|
"Material.Icons.Avalonia": "1.0.2",
|
||||||
"RGB.NET.Core": "1.0.0-prerelease7",
|
"RGB.NET.Core": "1.0.0-prerelease7",
|
||||||
"ReactiveUI": "17.1.50",
|
"ReactiveUI": "17.1.50",
|
||||||
|
|||||||
@ -33,42 +33,50 @@ Global
|
|||||||
{E489E5E3-1A65-4AF5-A1EA-F9805FD19A65}.Release|Any CPU.ActiveCfg = Release|x64
|
{E489E5E3-1A65-4AF5-A1EA-F9805FD19A65}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
{E489E5E3-1A65-4AF5-A1EA-F9805FD19A65}.Release|x64.ActiveCfg = Release|x64
|
{E489E5E3-1A65-4AF5-A1EA-F9805FD19A65}.Release|x64.ActiveCfg = Release|x64
|
||||||
{E489E5E3-1A65-4AF5-A1EA-F9805FD19A65}.Release|x64.Build.0 = Release|x64
|
{E489E5E3-1A65-4AF5-A1EA-F9805FD19A65}.Release|x64.Build.0 = Release|x64
|
||||||
|
{E489E5E3-1A65-4AF5-A1EA-F9805FD19A65}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
{9B811F9B-86B9-4771-87AF-72BAE7078A36}.Debug|Any CPU.ActiveCfg = Debug|x64
|
{9B811F9B-86B9-4771-87AF-72BAE7078A36}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
{9B811F9B-86B9-4771-87AF-72BAE7078A36}.Debug|x64.ActiveCfg = Debug|x64
|
{9B811F9B-86B9-4771-87AF-72BAE7078A36}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{9B811F9B-86B9-4771-87AF-72BAE7078A36}.Debug|x64.Build.0 = Debug|x64
|
{9B811F9B-86B9-4771-87AF-72BAE7078A36}.Debug|x64.Build.0 = Debug|x64
|
||||||
{9B811F9B-86B9-4771-87AF-72BAE7078A36}.Release|Any CPU.ActiveCfg = Release|x64
|
{9B811F9B-86B9-4771-87AF-72BAE7078A36}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
{9B811F9B-86B9-4771-87AF-72BAE7078A36}.Release|x64.ActiveCfg = Release|x64
|
{9B811F9B-86B9-4771-87AF-72BAE7078A36}.Release|x64.ActiveCfg = Release|x64
|
||||||
{9B811F9B-86B9-4771-87AF-72BAE7078A36}.Release|x64.Build.0 = Release|x64
|
{9B811F9B-86B9-4771-87AF-72BAE7078A36}.Release|x64.Build.0 = Release|x64
|
||||||
|
{9B811F9B-86B9-4771-87AF-72BAE7078A36}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
{035CBB38-7B9E-4375-A39C-E9A5B01F23A5}.Debug|Any CPU.ActiveCfg = Debug|x64
|
{035CBB38-7B9E-4375-A39C-E9A5B01F23A5}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
{035CBB38-7B9E-4375-A39C-E9A5B01F23A5}.Debug|x64.ActiveCfg = Debug|x64
|
{035CBB38-7B9E-4375-A39C-E9A5B01F23A5}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{035CBB38-7B9E-4375-A39C-E9A5B01F23A5}.Debug|x64.Build.0 = Debug|x64
|
{035CBB38-7B9E-4375-A39C-E9A5B01F23A5}.Debug|x64.Build.0 = Debug|x64
|
||||||
{035CBB38-7B9E-4375-A39C-E9A5B01F23A5}.Release|Any CPU.ActiveCfg = Release|x64
|
{035CBB38-7B9E-4375-A39C-E9A5B01F23A5}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
{035CBB38-7B9E-4375-A39C-E9A5B01F23A5}.Release|x64.ActiveCfg = Release|x64
|
{035CBB38-7B9E-4375-A39C-E9A5B01F23A5}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{035CBB38-7B9E-4375-A39C-E9A5B01F23A5}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
{05A5AB0F-A303-4404-9623-4DB1C9AA1DA0}.Debug|Any CPU.ActiveCfg = Debug|x64
|
{05A5AB0F-A303-4404-9623-4DB1C9AA1DA0}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
{05A5AB0F-A303-4404-9623-4DB1C9AA1DA0}.Debug|x64.ActiveCfg = Debug|x64
|
{05A5AB0F-A303-4404-9623-4DB1C9AA1DA0}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{05A5AB0F-A303-4404-9623-4DB1C9AA1DA0}.Debug|x64.Build.0 = Debug|x64
|
{05A5AB0F-A303-4404-9623-4DB1C9AA1DA0}.Debug|x64.Build.0 = Debug|x64
|
||||||
{05A5AB0F-A303-4404-9623-4DB1C9AA1DA0}.Release|Any CPU.ActiveCfg = Release|x64
|
{05A5AB0F-A303-4404-9623-4DB1C9AA1DA0}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
{05A5AB0F-A303-4404-9623-4DB1C9AA1DA0}.Release|x64.ActiveCfg = Release|x64
|
{05A5AB0F-A303-4404-9623-4DB1C9AA1DA0}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{05A5AB0F-A303-4404-9623-4DB1C9AA1DA0}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
{DE45A288-9320-461F-BE2A-26DFE3817216}.Debug|Any CPU.ActiveCfg = Debug|x64
|
{DE45A288-9320-461F-BE2A-26DFE3817216}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
{DE45A288-9320-461F-BE2A-26DFE3817216}.Debug|x64.ActiveCfg = Debug|x64
|
{DE45A288-9320-461F-BE2A-26DFE3817216}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{DE45A288-9320-461F-BE2A-26DFE3817216}.Debug|x64.Build.0 = Debug|x64
|
{DE45A288-9320-461F-BE2A-26DFE3817216}.Debug|x64.Build.0 = Debug|x64
|
||||||
{DE45A288-9320-461F-BE2A-26DFE3817216}.Release|Any CPU.ActiveCfg = Release|x64
|
{DE45A288-9320-461F-BE2A-26DFE3817216}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
{DE45A288-9320-461F-BE2A-26DFE3817216}.Release|x64.ActiveCfg = Release|x64
|
{DE45A288-9320-461F-BE2A-26DFE3817216}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{DE45A288-9320-461F-BE2A-26DFE3817216}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
{9012C8E2-3BEC-42F5-8270-7352A5922B04}.Debug|Any CPU.ActiveCfg = Debug|x64
|
{9012C8E2-3BEC-42F5-8270-7352A5922B04}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
{9012C8E2-3BEC-42F5-8270-7352A5922B04}.Debug|x64.ActiveCfg = Debug|x64
|
{9012C8E2-3BEC-42F5-8270-7352A5922B04}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{9012C8E2-3BEC-42F5-8270-7352A5922B04}.Debug|x64.Build.0 = Debug|x64
|
{9012C8E2-3BEC-42F5-8270-7352A5922B04}.Debug|x64.Build.0 = Debug|x64
|
||||||
{9012C8E2-3BEC-42F5-8270-7352A5922B04}.Release|Any CPU.ActiveCfg = Release|x64
|
{9012C8E2-3BEC-42F5-8270-7352A5922B04}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
{9012C8E2-3BEC-42F5-8270-7352A5922B04}.Release|x64.ActiveCfg = Release|x64
|
{9012C8E2-3BEC-42F5-8270-7352A5922B04}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{9012C8E2-3BEC-42F5-8270-7352A5922B04}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
{2F5F16DC-FACF-4559-9882-37C2949814C7}.Debug|Any CPU.ActiveCfg = Debug|x64
|
{2F5F16DC-FACF-4559-9882-37C2949814C7}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
{2F5F16DC-FACF-4559-9882-37C2949814C7}.Debug|x64.ActiveCfg = Debug|x64
|
{2F5F16DC-FACF-4559-9882-37C2949814C7}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{2F5F16DC-FACF-4559-9882-37C2949814C7}.Debug|x64.Build.0 = Debug|x64
|
{2F5F16DC-FACF-4559-9882-37C2949814C7}.Debug|x64.Build.0 = Debug|x64
|
||||||
{2F5F16DC-FACF-4559-9882-37C2949814C7}.Release|Any CPU.ActiveCfg = Release|x64
|
{2F5F16DC-FACF-4559-9882-37C2949814C7}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
{2F5F16DC-FACF-4559-9882-37C2949814C7}.Release|x64.ActiveCfg = Release|x64
|
{2F5F16DC-FACF-4559-9882-37C2949814C7}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{2F5F16DC-FACF-4559-9882-37C2949814C7}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
{412B921A-26F5-4AE6-8B32-0C19BE54F421}.Debug|Any CPU.ActiveCfg = Debug|x64
|
{412B921A-26F5-4AE6-8B32-0C19BE54F421}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
{412B921A-26F5-4AE6-8B32-0C19BE54F421}.Debug|x64.ActiveCfg = Debug|x64
|
{412B921A-26F5-4AE6-8B32-0C19BE54F421}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{412B921A-26F5-4AE6-8B32-0C19BE54F421}.Debug|x64.Build.0 = Debug|x64
|
{412B921A-26F5-4AE6-8B32-0C19BE54F421}.Debug|x64.Build.0 = Debug|x64
|
||||||
{412B921A-26F5-4AE6-8B32-0C19BE54F421}.Release|Any CPU.ActiveCfg = Release|x64
|
{412B921A-26F5-4AE6-8B32-0C19BE54F421}.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
{412B921A-26F5-4AE6-8B32-0C19BE54F421}.Release|x64.ActiveCfg = Release|x64
|
{412B921A-26F5-4AE6-8B32-0C19BE54F421}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{412B921A-26F5-4AE6-8B32-0C19BE54F421}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user