mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Profile editor - Added unro/redo
Profile editor - Added adding layers and folders
This commit is contained in:
parent
34757716aa
commit
736324e45e
1271
src/Artemis.ConsoleUI/packages.lock.json
Normal file
1271
src/Artemis.ConsoleUI/packages.lock.json
Normal file
File diff suppressed because it is too large
Load Diff
20
src/Artemis.Core/Events/Profiles/ProfileElementEventArgs.cs
Normal file
20
src/Artemis.Core/Events/Profiles/ProfileElementEventArgs.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides data for profile element events.
|
||||
/// </summary>
|
||||
public class ProfileElementEventArgs : EventArgs
|
||||
{
|
||||
internal ProfileElementEventArgs(ProfileElement profileElement)
|
||||
{
|
||||
ProfileElement = profileElement;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the profile element this event is related to
|
||||
/// </summary>
|
||||
public ProfileElement ProfileElement { get; }
|
||||
}
|
||||
}
|
||||
@ -22,17 +22,13 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent of the folder</param>
|
||||
/// <param name="name">The name of the folder</param>
|
||||
/// <param name="order">The order where to place the child (0-based), defaults to the end of the collection</param>
|
||||
public Folder(ProfileElement parent, string name, int order) : base(parent.Profile)
|
||||
public Folder(ProfileElement parent, string name) : base(parent, parent.Profile)
|
||||
{
|
||||
FolderEntity = new FolderEntity();
|
||||
EntityId = Guid.NewGuid();
|
||||
|
||||
Parent = parent ?? throw new ArgumentNullException(nameof(parent));
|
||||
Profile = Parent.Profile;
|
||||
Name = name;
|
||||
|
||||
Parent.AddChild(this, order);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -41,13 +37,12 @@ namespace Artemis.Core
|
||||
/// <param name="profile">The profile the folder belongs to</param>
|
||||
/// <param name="parent">The parent of the folder</param>
|
||||
/// <param name="folderEntity">The entity of the folder</param>
|
||||
public Folder(Profile profile, ProfileElement parent, FolderEntity folderEntity) : base(parent.Profile)
|
||||
public Folder(Profile profile, ProfileElement parent, FolderEntity folderEntity) : base(parent, parent.Profile)
|
||||
{
|
||||
FolderEntity = folderEntity;
|
||||
EntityId = folderEntity.Id;
|
||||
|
||||
Profile = profile;
|
||||
Parent = parent;
|
||||
Name = folderEntity.Name;
|
||||
IsExpanded = folderEntity.IsExpanded;
|
||||
Suspended = folderEntity.Suspended;
|
||||
|
||||
@ -4,7 +4,6 @@ using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Artemis.Core.LayerBrushes;
|
||||
using Artemis.Core.LayerEffects;
|
||||
using Artemis.Core.ScriptingProviders;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
using Artemis.Storage.Entities.Profile.Abstract;
|
||||
using RGB.NET.Core;
|
||||
@ -29,13 +28,11 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent of the layer</param>
|
||||
/// <param name="name">The name of the layer</param>
|
||||
/// <param name="order">The order where to place the child (0-based), defaults to the end of the collection</param>
|
||||
public Layer(ProfileElement parent, string name, int order) : base(parent.Profile)
|
||||
public Layer(ProfileElement parent, string name) : base(parent, parent.Profile)
|
||||
{
|
||||
LayerEntity = new LayerEntity();
|
||||
EntityId = Guid.NewGuid();
|
||||
|
||||
Parent = parent ?? throw new ArgumentNullException(nameof(parent));
|
||||
Profile = Parent.Profile;
|
||||
Name = name;
|
||||
Suspended = false;
|
||||
@ -48,7 +45,6 @@ namespace Artemis.Core
|
||||
|
||||
Adapter = new LayerAdapter(this);
|
||||
Initialize();
|
||||
Parent.AddChild(this, order);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -57,7 +53,7 @@ namespace Artemis.Core
|
||||
/// <param name="profile">The profile the layer belongs to</param>
|
||||
/// <param name="parent">The parent of the layer</param>
|
||||
/// <param name="layerEntity">The entity of the layer</param>
|
||||
public Layer(Profile profile, ProfileElement parent, LayerEntity layerEntity) : base(parent.Profile)
|
||||
public Layer(Profile profile, ProfileElement parent, LayerEntity layerEntity) : base(parent, parent.Profile)
|
||||
{
|
||||
LayerEntity = layerEntity;
|
||||
EntityId = layerEntity.Id;
|
||||
@ -148,10 +144,8 @@ namespace Artemis.Core
|
||||
if (LayerBrush?.BaseProperties != null)
|
||||
result.AddRange(LayerBrush.BaseProperties.GetAllLayerProperties());
|
||||
foreach (BaseLayerEffect layerEffect in LayerEffects)
|
||||
{
|
||||
if (layerEffect.BaseProperties != null)
|
||||
result.AddRange(layerEffect.BaseProperties.GetAllLayerProperties());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -172,6 +166,19 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public event EventHandler? LayerBrushUpdated;
|
||||
|
||||
#region Overrides of BreakableModel
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<IBreakableModel> GetBrokenHierarchy()
|
||||
{
|
||||
if (LayerBrush?.BrokenState != null)
|
||||
yield return LayerBrush;
|
||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.BrokenState != null))
|
||||
yield return baseLayerEffect;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
@ -385,6 +392,18 @@ namespace Artemis.Core
|
||||
Enabled = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Activate()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Deactivate()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Disable()
|
||||
{
|
||||
@ -512,7 +531,9 @@ namespace Artemis.Core
|
||||
throw new ObjectDisposedException("Layer");
|
||||
|
||||
if (!Leds.Any())
|
||||
{
|
||||
Path = new SKPath();
|
||||
}
|
||||
else
|
||||
{
|
||||
SKPath path = new() {FillType = SKPathFillType.Winding};
|
||||
@ -761,19 +782,6 @@ namespace Artemis.Core
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides of BreakableModel
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<IBreakableModel> GetBrokenHierarchy()
|
||||
{
|
||||
if (LayerBrush?.BrokenState != null)
|
||||
yield return LayerBrush;
|
||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.BrokenState != null))
|
||||
yield return baseLayerEffect;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -197,13 +197,9 @@ namespace Artemis.Core
|
||||
// Populate the profile starting at the root, the rest is populated recursively
|
||||
FolderEntity? rootFolder = ProfileEntity.Folders.FirstOrDefault(f => f.ParentId == EntityId);
|
||||
if (rootFolder == null)
|
||||
{
|
||||
Folder _ = new(this, "Root folder", 0);
|
||||
}
|
||||
AddChild(new Folder(this, "Root folder"));
|
||||
else
|
||||
{
|
||||
AddChild(new Folder(this, this, rootFolder));
|
||||
}
|
||||
}
|
||||
|
||||
List<RenderProfileElement> renderElements = GetAllRenderElements();
|
||||
|
||||
@ -156,7 +156,7 @@ namespace Artemis.Core
|
||||
StreamlineOrder();
|
||||
}
|
||||
|
||||
OnChildAdded();
|
||||
OnChildAdded(child);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -176,7 +176,7 @@ namespace Artemis.Core
|
||||
child.Parent = null;
|
||||
}
|
||||
|
||||
OnChildRemoved();
|
||||
OnChildRemoved(child);
|
||||
}
|
||||
|
||||
private void StreamlineOrder()
|
||||
@ -262,27 +262,27 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Occurs when a child was added to the <see cref="Children" /> list
|
||||
/// </summary>
|
||||
public event EventHandler? ChildAdded;
|
||||
public event EventHandler<ProfileElementEventArgs>? ChildAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a child was removed from the <see cref="Children" /> list
|
||||
/// </summary>
|
||||
public event EventHandler? ChildRemoved;
|
||||
public event EventHandler<ProfileElementEventArgs>? ChildRemoved;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="ChildAdded" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnChildAdded()
|
||||
protected virtual void OnChildAdded(ProfileElement child)
|
||||
{
|
||||
ChildAdded?.Invoke(this, EventArgs.Empty);
|
||||
ChildAdded?.Invoke(this, new ProfileElementEventArgs(child));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="ChildRemoved" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnChildRemoved()
|
||||
protected virtual void OnChildRemoved(ProfileElement child)
|
||||
{
|
||||
ChildRemoved?.Invoke(this, EventArgs.Empty);
|
||||
ChildRemoved?.Invoke(this, new ProfileElementEventArgs(child));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -20,12 +20,13 @@ namespace Artemis.Core
|
||||
private SKRectI _bounds;
|
||||
private SKPath? _path;
|
||||
|
||||
internal RenderProfileElement(Profile profile) : base(profile)
|
||||
internal RenderProfileElement(ProfileElement parent, Profile profile) : base(profile)
|
||||
{
|
||||
Timeline = new Timeline();
|
||||
ExpandedPropertyGroups = new List<string>();
|
||||
LayerEffectsList = new List<BaseLayerEffect>();
|
||||
LayerEffects = new ReadOnlyCollection<BaseLayerEffect>(LayerEffectsList);
|
||||
Parent = parent ?? throw new ArgumentNullException(nameof(parent));
|
||||
|
||||
LayerEffectStore.LayerEffectAdded += LayerEffectStoreOnLayerEffectAdded;
|
||||
LayerEffectStore.LayerEffectRemoved += LayerEffectStoreOnLayerEffectRemoved;
|
||||
@ -52,6 +53,16 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public event EventHandler? LayerEffectsUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Activates the render profile element, loading required brushes, effects or anything else needed for rendering
|
||||
/// </summary>
|
||||
public abstract void Activate();
|
||||
|
||||
/// <summary>
|
||||
/// Deactivates the render profile element, disposing required brushes, effects or anything else needed for rendering
|
||||
/// </summary>
|
||||
public abstract void Deactivate();
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
@ -155,9 +166,9 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets the parent of this element
|
||||
/// </summary>
|
||||
public new ProfileElement? Parent
|
||||
public new ProfileElement Parent
|
||||
{
|
||||
get => base.Parent;
|
||||
get => base.Parent!;
|
||||
internal set
|
||||
{
|
||||
base.Parent = value;
|
||||
|
||||
@ -137,7 +137,8 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
|
||||
if (!SupportsChildren)
|
||||
throw new ArtemisUIException("Cannot add a folder to a profile element of type " + ProfileElement.GetType().Name);
|
||||
|
||||
Folder _ = new(ProfileElement, "New folder", 0);
|
||||
Folder folder = new(ProfileElement, "New folder");
|
||||
ProfileElement.AddChild(folder, 0);
|
||||
_profileEditorService.SaveSelectedProfileConfiguration();
|
||||
}
|
||||
|
||||
@ -146,8 +147,8 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem
|
||||
if (!SupportsChildren)
|
||||
throw new ArtemisUIException("Cannot add a layer to a profile element of type " + ProfileElement.GetType().Name);
|
||||
|
||||
Layer layer = new(ProfileElement, "New layer", 0);
|
||||
|
||||
Layer layer = new(ProfileElement, "New layer");
|
||||
ProfileElement.AddChild(layer, 0);
|
||||
// Could be null if the default brush got disabled
|
||||
LayerBrushDescriptor brush = _layerBrushService.GetDefaultLayerBrush();
|
||||
if (brush != null)
|
||||
|
||||
@ -90,6 +90,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Visualization.Tools
|
||||
private void CreateLayer(Folder folder, List<ArtemisLed> selectedLeds)
|
||||
{
|
||||
Layer newLayer = new(folder, "New layer");
|
||||
folder.AddChild(newLayer);
|
||||
|
||||
LayerBrushDescriptor brush = _layerBrushService.GetDefaultLayerBrush();
|
||||
if (brush != null)
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="0.10.11" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.11" />
|
||||
<PackageReference Include="ReactiveUI" Version="17.1.9" />
|
||||
<PackageReference Include="ReactiveUI" Version="16.3.10" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Artemis.Core\Artemis.Core.csproj" />
|
||||
|
||||
@ -55,16 +55,12 @@
|
||||
},
|
||||
"ReactiveUI": {
|
||||
"type": "Direct",
|
||||
"requested": "[17.1.9, )",
|
||||
"resolved": "17.1.9",
|
||||
"contentHash": "bxH6uzEi1b6cfGoBBvCXWrdT18+Rleggi0R/vOaCYc+zvlSleJW6wlUtcWjrKzgQHD8EN3c02A4JBTt9oGSWWQ==",
|
||||
"requested": "[16.3.10, )",
|
||||
"resolved": "16.3.10",
|
||||
"contentHash": "NH9bg8BROqRrTp6YLpPDsJrfNDzRWNmP63fQ68CBAM+i7YHi6wcPeOkxyKpoemUxKEY4QECuicaTblJnxgbWmA==",
|
||||
"dependencies": {
|
||||
"DynamicData": "7.4.3",
|
||||
"Splat": "14.1.1",
|
||||
"System.ComponentModel": "4.3.0",
|
||||
"System.Diagnostics.Contracts": "4.3.0",
|
||||
"System.Dynamic.Runtime": "4.3.0",
|
||||
"System.Runtime.Serialization.Primitives": "4.3.0"
|
||||
"Splat": "13.1.42"
|
||||
}
|
||||
},
|
||||
"Avalonia.Angle.Windows.Natives": {
|
||||
@ -923,14 +919,6 @@
|
||||
"System.Text.Encoding": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.Contracts": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "eelRRbnm+OloiQvp9CXS0ixjNQldjjkHO4iIkR5XH2VIP8sUB/SIpa1TdUW6/+HDcQ+MlhP3pNa1u5SbzYuWGA==",
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.Debug": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
@ -1411,15 +1399,6 @@
|
||||
"System.Runtime.Extensions": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.Serialization.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==",
|
||||
"dependencies": {
|
||||
"System.Resources.ResourceManager": "4.3.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Security.AccessControl": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
@ -1779,7 +1758,7 @@
|
||||
"Material.Icons.Avalonia": "1.0.2",
|
||||
"RGB.NET.Core": "1.0.0-prerelease1",
|
||||
"RGB.NET.Layout": "1.0.0-prerelease1",
|
||||
"ReactiveUI": "17.1.9",
|
||||
"ReactiveUI": "16.3.10",
|
||||
"ReactiveUI.Validation": "2.2.1",
|
||||
"Splat.Ninject": "14.1.17"
|
||||
}
|
||||
@ -1797,7 +1776,7 @@
|
||||
"FluentAvaloniaUI": "1.1.8",
|
||||
"Material.Icons.Avalonia": "1.0.2",
|
||||
"RGB.NET.Core": "1.0.0-prerelease1",
|
||||
"ReactiveUI": "17.1.9",
|
||||
"ReactiveUI": "16.3.10",
|
||||
"ReactiveUI.Validation": "2.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="0.10.11" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.11" />
|
||||
<PackageReference Include="ReactiveUI" Version="17.1.9" />
|
||||
<PackageReference Include="ReactiveUI" Version="16.3.10" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Artemis.Core\Artemis.Core.csproj" />
|
||||
|
||||
@ -55,16 +55,12 @@
|
||||
},
|
||||
"ReactiveUI": {
|
||||
"type": "Direct",
|
||||
"requested": "[17.1.9, )",
|
||||
"resolved": "17.1.9",
|
||||
"contentHash": "bxH6uzEi1b6cfGoBBvCXWrdT18+Rleggi0R/vOaCYc+zvlSleJW6wlUtcWjrKzgQHD8EN3c02A4JBTt9oGSWWQ==",
|
||||
"requested": "[16.3.10, )",
|
||||
"resolved": "16.3.10",
|
||||
"contentHash": "NH9bg8BROqRrTp6YLpPDsJrfNDzRWNmP63fQ68CBAM+i7YHi6wcPeOkxyKpoemUxKEY4QECuicaTblJnxgbWmA==",
|
||||
"dependencies": {
|
||||
"DynamicData": "7.4.3",
|
||||
"Splat": "14.1.1",
|
||||
"System.ComponentModel": "4.3.0",
|
||||
"System.Diagnostics.Contracts": "4.3.0",
|
||||
"System.Dynamic.Runtime": "4.3.0",
|
||||
"System.Runtime.Serialization.Primitives": "4.3.0"
|
||||
"Splat": "13.1.42"
|
||||
}
|
||||
},
|
||||
"Avalonia.Angle.Windows.Natives": {
|
||||
@ -923,14 +919,6 @@
|
||||
"System.Text.Encoding": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.Contracts": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "eelRRbnm+OloiQvp9CXS0ixjNQldjjkHO4iIkR5XH2VIP8sUB/SIpa1TdUW6/+HDcQ+MlhP3pNa1u5SbzYuWGA==",
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.Debug": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
@ -1411,15 +1399,6 @@
|
||||
"System.Runtime.Extensions": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.Serialization.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==",
|
||||
"dependencies": {
|
||||
"System.Resources.ResourceManager": "4.3.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Security.AccessControl": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
@ -1779,7 +1758,7 @@
|
||||
"Material.Icons.Avalonia": "1.0.2",
|
||||
"RGB.NET.Core": "1.0.0-prerelease1",
|
||||
"RGB.NET.Layout": "1.0.0-prerelease1",
|
||||
"ReactiveUI": "17.1.9",
|
||||
"ReactiveUI": "16.3.10",
|
||||
"ReactiveUI.Validation": "2.2.1",
|
||||
"Splat.Ninject": "14.1.17"
|
||||
}
|
||||
@ -1797,7 +1776,7 @@
|
||||
"FluentAvaloniaUI": "1.1.8",
|
||||
"Material.Icons.Avalonia": "1.0.2",
|
||||
"RGB.NET.Core": "1.0.0-prerelease1",
|
||||
"ReactiveUI": "17.1.9",
|
||||
"ReactiveUI": "16.3.10",
|
||||
"ReactiveUI.Validation": "2.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
<PackageReference Include="Avalonia.Xaml.Interactivity" Version="0.10.11.5" />
|
||||
<PackageReference Include="FluentAvaloniaUI" Version="1.1.8" />
|
||||
<PackageReference Include="Material.Icons.Avalonia" Version="1.0.2" />
|
||||
<PackageReference Include="ReactiveUI" Version="17.1.9" />
|
||||
<PackageReference Include="ReactiveUI" Version="16.3.10" />
|
||||
<PackageReference Include="ReactiveUI.Validation" Version="2.2.1" />
|
||||
<PackageReference Include="RGB.NET.Core" Version="1.0.0-prerelease1" />
|
||||
</ItemGroup>
|
||||
|
||||
@ -93,16 +93,12 @@
|
||||
},
|
||||
"ReactiveUI": {
|
||||
"type": "Direct",
|
||||
"requested": "[17.1.9, )",
|
||||
"resolved": "17.1.9",
|
||||
"contentHash": "bxH6uzEi1b6cfGoBBvCXWrdT18+Rleggi0R/vOaCYc+zvlSleJW6wlUtcWjrKzgQHD8EN3c02A4JBTt9oGSWWQ==",
|
||||
"requested": "[16.3.10, )",
|
||||
"resolved": "16.3.10",
|
||||
"contentHash": "NH9bg8BROqRrTp6YLpPDsJrfNDzRWNmP63fQ68CBAM+i7YHi6wcPeOkxyKpoemUxKEY4QECuicaTblJnxgbWmA==",
|
||||
"dependencies": {
|
||||
"DynamicData": "7.4.3",
|
||||
"Splat": "14.1.1",
|
||||
"System.ComponentModel": "4.3.0",
|
||||
"System.Diagnostics.Contracts": "4.3.0",
|
||||
"System.Dynamic.Runtime": "4.3.0",
|
||||
"System.Runtime.Serialization.Primitives": "4.3.0"
|
||||
"Splat": "13.1.42"
|
||||
}
|
||||
},
|
||||
"ReactiveUI.Validation": {
|
||||
@ -725,8 +721,8 @@
|
||||
},
|
||||
"Splat": {
|
||||
"type": "Transitive",
|
||||
"resolved": "14.1.1",
|
||||
"contentHash": "bKQtKu57w+iJ1T+WDyDdNq+LBNVdmNu2i0vGNyUdtmg4TEIEFiX2GfPusNEAW2QOfxyDE7i4+xTxbOKZr/4jhg=="
|
||||
"resolved": "13.1.42",
|
||||
"contentHash": "a/NkGyoSsmvH2YZGgjFxt0dsXkRTgQRMgoUDN8WpBhTUr3wnPTdeQTOLLr2Jc/BCAdOA7cK2+E4Io8I1/q3f3Q=="
|
||||
},
|
||||
"Svg.Custom": {
|
||||
"type": "Transitive",
|
||||
@ -889,14 +885,6 @@
|
||||
"System.Text.Encoding": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.Contracts": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "eelRRbnm+OloiQvp9CXS0ixjNQldjjkHO4iIkR5XH2VIP8sUB/SIpa1TdUW6/+HDcQ+MlhP3pNa1u5SbzYuWGA==",
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.Debug": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
@ -1377,15 +1365,6 @@
|
||||
"System.Runtime.Extensions": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.Serialization.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==",
|
||||
"dependencies": {
|
||||
"System.Resources.ResourceManager": "4.3.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Security.AccessControl": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
<PackageReference Include="Avalonia.Win32" Version="0.10.11" />
|
||||
<PackageReference Include="Microsoft.Win32" Version="2.0.1" />
|
||||
<PackageReference Include="RawInput.Sharp" Version="0.0.4" />
|
||||
<PackageReference Include="ReactiveUI" Version="17.1.9" />
|
||||
<PackageReference Include="ReactiveUI" Version="16.3.10" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Artemis.Core\Artemis.Core.csproj" />
|
||||
|
||||
@ -82,16 +82,12 @@
|
||||
},
|
||||
"ReactiveUI": {
|
||||
"type": "Direct",
|
||||
"requested": "[17.1.9, )",
|
||||
"resolved": "17.1.9",
|
||||
"contentHash": "bxH6uzEi1b6cfGoBBvCXWrdT18+Rleggi0R/vOaCYc+zvlSleJW6wlUtcWjrKzgQHD8EN3c02A4JBTt9oGSWWQ==",
|
||||
"requested": "[16.3.10, )",
|
||||
"resolved": "16.3.10",
|
||||
"contentHash": "NH9bg8BROqRrTp6YLpPDsJrfNDzRWNmP63fQ68CBAM+i7YHi6wcPeOkxyKpoemUxKEY4QECuicaTblJnxgbWmA==",
|
||||
"dependencies": {
|
||||
"DynamicData": "7.4.3",
|
||||
"Splat": "14.1.1",
|
||||
"System.ComponentModel": "4.3.0",
|
||||
"System.Diagnostics.Contracts": "4.3.0",
|
||||
"System.Dynamic.Runtime": "4.3.0",
|
||||
"System.Runtime.Serialization.Primitives": "4.3.0"
|
||||
"Splat": "13.1.42"
|
||||
}
|
||||
},
|
||||
"Avalonia.Angle.Windows.Natives": {
|
||||
@ -939,14 +935,6 @@
|
||||
"System.Text.Encoding": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.Contracts": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "eelRRbnm+OloiQvp9CXS0ixjNQldjjkHO4iIkR5XH2VIP8sUB/SIpa1TdUW6/+HDcQ+MlhP3pNa1u5SbzYuWGA==",
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.Debug": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
@ -1427,15 +1415,6 @@
|
||||
"System.Runtime.Extensions": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.Serialization.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==",
|
||||
"dependencies": {
|
||||
"System.Resources.ResourceManager": "4.3.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Security.AccessControl": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
@ -1795,7 +1774,7 @@
|
||||
"Material.Icons.Avalonia": "1.0.2",
|
||||
"RGB.NET.Core": "1.0.0-prerelease1",
|
||||
"RGB.NET.Layout": "1.0.0-prerelease1",
|
||||
"ReactiveUI": "17.1.9",
|
||||
"ReactiveUI": "16.3.10",
|
||||
"ReactiveUI.Validation": "2.2.1",
|
||||
"Splat.Ninject": "14.1.17"
|
||||
}
|
||||
@ -1813,7 +1792,7 @@
|
||||
"FluentAvaloniaUI": "1.1.8",
|
||||
"Material.Icons.Avalonia": "1.0.2",
|
||||
"RGB.NET.Core": "1.0.0-prerelease1",
|
||||
"ReactiveUI": "17.1.9",
|
||||
"ReactiveUI": "16.3.10",
|
||||
"ReactiveUI.Validation": "2.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
<PackageReference Include="Flurl.Http" Version="3.2.0" />
|
||||
<PackageReference Include="Live.Avalonia" Version="1.3.1" />
|
||||
<PackageReference Include="Material.Icons.Avalonia" Version="1.0.2" />
|
||||
<PackageReference Include="ReactiveUI" Version="17.1.9" />
|
||||
<PackageReference Include="ReactiveUI" Version="16.3.10" />
|
||||
<PackageReference Include="ReactiveUI.Validation" Version="2.2.1" />
|
||||
<PackageReference Include="RGB.NET.Core" Version="1.0.0-prerelease1" />
|
||||
<PackageReference Include="RGB.NET.Layout" Version="1.0.0-prerelease1" />
|
||||
@ -59,9 +59,4 @@
|
||||
<ItemGroup>
|
||||
<Folder Include="Screens\ProfileEditor\Tools\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="HistoricalReactiveCommand">
|
||||
<HintPath>..\..\..\..\HistoricalReactiveCommand\HistoricalReactiveCommand\bin\Debug\netstandard2.1\HistoricalReactiveCommand.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Services.ProfileEditor;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Commands
|
||||
{
|
||||
public class AddProfileElement : IProfileEditorCommand, IDisposable
|
||||
{
|
||||
private readonly int _index;
|
||||
private readonly RenderProfileElement _subject;
|
||||
private readonly ProfileElement _target;
|
||||
private bool _isAdded;
|
||||
|
||||
public AddProfileElement(RenderProfileElement subject, ProfileElement target, int index)
|
||||
{
|
||||
_subject = subject;
|
||||
_target = target;
|
||||
_index = index;
|
||||
|
||||
DisplayName = subject switch
|
||||
{
|
||||
Layer => "Add layer",
|
||||
Folder => "Add folder",
|
||||
_ => throw new ArgumentException("Type of subject is not supported")
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
if (!_isAdded)
|
||||
_subject.Dispose();
|
||||
}
|
||||
|
||||
#region Implementation of IProfileEditorCommand
|
||||
|
||||
/// <inheritdoc />
|
||||
public string DisplayName { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Execute()
|
||||
{
|
||||
_isAdded = true;
|
||||
_target.AddChild(_subject, _index);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Undo()
|
||||
{
|
||||
_isAdded = false;
|
||||
_target.RemoveChild(_subject);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Exceptions;
|
||||
using Artemis.UI.Services.ProfileEditor;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Commands
|
||||
{
|
||||
public class RemoveProfileElement : IProfileEditorCommand, IDisposable
|
||||
{
|
||||
private readonly int _index;
|
||||
private readonly RenderProfileElement _subject;
|
||||
private readonly ProfileElement _target;
|
||||
private bool _isRemoved;
|
||||
|
||||
public RemoveProfileElement(RenderProfileElement subject)
|
||||
{
|
||||
if (subject.Parent == null)
|
||||
throw new ArtemisUIException("Can't remove a subject that has no parent");
|
||||
|
||||
_subject = subject;
|
||||
_target = _subject.Parent;
|
||||
_index = _subject.Children.IndexOf(_subject);
|
||||
|
||||
DisplayName = subject switch
|
||||
{
|
||||
Layer => "Remove layer",
|
||||
Folder => "Remove folder",
|
||||
_ => throw new ArgumentException("Type of subject is not supported")
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
if (_isRemoved)
|
||||
_subject.Dispose();
|
||||
}
|
||||
|
||||
#region Implementation of IProfileEditorCommand
|
||||
|
||||
/// <inheritdoc />
|
||||
public string DisplayName { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Execute()
|
||||
{
|
||||
_isRemoved = true;
|
||||
_target.RemoveChild(_subject);
|
||||
_target.Deactivate();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Undo()
|
||||
{
|
||||
_isRemoved = false;
|
||||
_target.Activate();
|
||||
_target.AddChild(_subject, _index);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -64,10 +64,27 @@
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
<MenuItem Header="_Edit" SubmenuOpened="MenuItem_OnSubmenuOpened">
|
||||
<MenuItem Header="_Undo"
|
||||
Command="{Binding History.Undo}"
|
||||
HotKey="Ctrl+Z"
|
||||
InputGesture="Ctrl+Z">
|
||||
<MenuItem.Icon>
|
||||
<avalonia:MaterialIcon Kind="Undo" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="_Redo"
|
||||
Command="{Binding History.Redo}"
|
||||
HotKey="Ctrl+Y"
|
||||
InputGesture="Ctrl+Y">
|
||||
<MenuItem.Icon>
|
||||
<avalonia:MaterialIcon Kind="Redo" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem Header="_Duplicate"
|
||||
Command="{Binding Duplicate}"
|
||||
HotKey="Ctrl+D"
|
||||
IsEnabled="{Binding HasSelectedElement}">
|
||||
Command="{Binding Duplicate}"
|
||||
HotKey="Ctrl+D"
|
||||
IsEnabled="{Binding HasSelectedElement}">
|
||||
<MenuItem.Icon>
|
||||
<avalonia:MaterialIcon Kind="ContentDuplicate" />
|
||||
</MenuItem.Icon>
|
||||
|
||||
@ -2,10 +2,11 @@ using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Panels.MenuBar
|
||||
{
|
||||
public partial class MenuBarView : UserControl
|
||||
public partial class MenuBarView : ReactiveUserControl<MenuBarViewModel>
|
||||
{
|
||||
public MenuBarView()
|
||||
{
|
||||
|
||||
@ -1,13 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reactive.Disposables;
|
||||
using Artemis.UI.Services.ProfileEditor;
|
||||
using Artemis.UI.Shared;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.Panels.MenuBar
|
||||
{
|
||||
public class MenuBarViewModel : ViewModelBase
|
||||
public class MenuBarViewModel : ActivatableViewModelBase
|
||||
{
|
||||
private ProfileEditorHistory? _history;
|
||||
|
||||
public MenuBarViewModel(IProfileEditorService profileEditorService)
|
||||
{
|
||||
this.WhenActivated(d => profileEditorService.History.Subscribe(history => History = history).DisposeWith(d));
|
||||
}
|
||||
|
||||
public ProfileEditorHistory? History
|
||||
{
|
||||
get => _history;
|
||||
set => this.RaiseAndSetIfChanged(ref _history, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,8 +7,8 @@
|
||||
x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.FolderTreeItemView">
|
||||
<Grid ColumnDefinitions="Auto,Auto,*,Auto">
|
||||
<Button Grid.Column="0"
|
||||
ToolTip.Tip="{Binding BrokenState}"
|
||||
IsVisible="{Binding BrokenState, Converter={x:Static ObjectConverters.IsNotNull}}"
|
||||
ToolTip.Tip="{Binding ProfileElement.BrokenState}"
|
||||
IsVisible="{Binding ProfileElement.BrokenState, Converter={x:Static ObjectConverters.IsNotNull}}"
|
||||
Classes="icon-button icon-button-small"
|
||||
Foreground="White"
|
||||
Background="#E74C4C"
|
||||
@ -28,7 +28,7 @@
|
||||
<ToggleButton Grid.Column="3"
|
||||
Classes="icon-button icon-button-small"
|
||||
ToolTip.Tip="Toggle suspended state"
|
||||
IsChecked="{Binding !Folder.Suspended}"
|
||||
IsChecked="{Binding Folder.Suspended}"
|
||||
VerticalAlignment="Center"
|
||||
Margin="4 0">
|
||||
<avalonia:MaterialIcon Kind="Pause" />
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Shared.Services.Interfaces;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
|
||||
{
|
||||
public class FolderTreeItemViewModel : TreeItemViewModel
|
||||
{
|
||||
public FolderTreeItemViewModel(TreeItemViewModel? parent, Folder folder, IProfileEditorVmFactory profileEditorVmFactory) : base(parent, folder)
|
||||
public FolderTreeItemViewModel(TreeItemViewModel? parent, Folder folder, IProfileEditorVmFactory profileEditorVmFactory, IWindowService windowService) : base(parent, folder, windowService)
|
||||
{
|
||||
Folder = folder;
|
||||
|
||||
|
||||
@ -7,8 +7,8 @@
|
||||
x:Class="Artemis.UI.Screens.ProfileEditor.ProfileTree.LayerTreeItemView">
|
||||
<Grid ColumnDefinitions="Auto,Auto,*,Auto">
|
||||
<Button Grid.Column="0"
|
||||
ToolTip.Tip="{Binding BrokenState}"
|
||||
IsVisible="{Binding BrokenState, Converter={x:Static ObjectConverters.IsNotNull}}"
|
||||
ToolTip.Tip="{Binding ProfileElement.BrokenState}"
|
||||
IsVisible="{Binding ProfileElement.BrokenState, Converter={x:Static ObjectConverters.IsNotNull}}"
|
||||
Classes="icon-button icon-button-small"
|
||||
Foreground="#E74C4C"
|
||||
Command="{Binding ShowBrokenStateExceptions}">
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Shared.Services.Interfaces;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
|
||||
{
|
||||
public class LayerTreeItemViewModel : TreeItemViewModel
|
||||
{
|
||||
public LayerTreeItemViewModel(TreeItemViewModel? parent, Layer layer) : base(parent, layer)
|
||||
public LayerTreeItemViewModel(TreeItemViewModel? parent, Layer layer, IWindowService windowService) : base(parent, layer, windowService)
|
||||
{
|
||||
Layer = layer;
|
||||
}
|
||||
|
||||
@ -4,51 +4,58 @@ using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Services;
|
||||
using Artemis.UI.Screens.ProfileEditor.Commands;
|
||||
using Artemis.UI.Services.ProfileEditor;
|
||||
using Artemis.UI.Shared;
|
||||
using HistoricalReactiveCommand;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
|
||||
{
|
||||
public class ProfileTreeViewModel : ActivatableViewModelBase
|
||||
{
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private readonly IProfileEditorVmFactory _profileEditorVmFactory;
|
||||
private ReactiveCommand<Unit, Unit>? _addFolder;
|
||||
private ReactiveCommand<Unit, Unit>? _addLayer;
|
||||
private TreeItemViewModel? _selectedTreeItem;
|
||||
|
||||
public ProfileTreeViewModel(IProfileEditorService profileEditorService, IProfileEditorVmFactory profileEditorVmFactory)
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_profileEditorVmFactory = profileEditorVmFactory;
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
ProfileConfiguration profileConfiguration = null!;
|
||||
profileEditorService.CurrentProfileConfiguration.WhereNotNull().Subscribe(p => profileConfiguration = p).DisposeWith(d);
|
||||
profileEditorService.CurrentProfileConfiguration.WhereNotNull().Subscribe(Repopulate).DisposeWith(d);
|
||||
profileEditorService.CurrentProfileElement.WhereNotNull().Subscribe(SelectCurrentProfileElement).DisposeWith(d);
|
||||
profileEditorService.ProfileConfiguration.WhereNotNull().Subscribe(configuration =>
|
||||
{
|
||||
Folder rootFolder = configuration.Profile!.GetRootFolder();
|
||||
CreateTreeItems(rootFolder);
|
||||
Observable.FromEventPattern<ProfileElementEventArgs>(x => rootFolder.ChildAdded += x, x => rootFolder.ChildAdded -= x).Subscribe(c => AddTreeItemIfMissing(c.EventArgs.ProfileElement));
|
||||
Observable.FromEventPattern<ProfileElementEventArgs>(x => rootFolder.ChildRemoved += x, x => rootFolder.ChildRemoved -= x).Subscribe(c => RemoveTreeItemsIfFound(c.EventArgs.ProfileElement));
|
||||
|
||||
Folder rootFolder = profileConfiguration.Profile!.GetRootFolder();
|
||||
AddLayer = ReactiveCommandEx.CreateWithHistory("AddLayerAtRoot",
|
||||
// ReSharper disable once ObjectCreationAsStatement
|
||||
() => new Layer(rootFolder, "New layer", 0),
|
||||
() => rootFolder.RemoveChild(rootFolder.Children[0]),
|
||||
profileConfiguration.Profile.EntityId.ToString()
|
||||
);
|
||||
AddLayer = ReactiveCommand.Create(() => AddLayerToRoot(configuration.Profile), profileEditorService.ProfileConfiguration.Select(p => p != null));
|
||||
AddFolder = ReactiveCommand.Create(() => AddFolderToRoot(configuration.Profile), profileEditorService.ProfileConfiguration.Select(p => p != null));
|
||||
}).DisposeWith(d);
|
||||
|
||||
AddFolder = ReactiveCommandEx.CreateWithHistory("AddFolderAtRoot",
|
||||
// ReSharper disable once ObjectCreationAsStatement
|
||||
() => new Folder(rootFolder, "New folder", 0),
|
||||
() => rootFolder.RemoveChild(rootFolder.Children[0]),
|
||||
profileConfiguration.Profile.EntityId.ToString()
|
||||
);
|
||||
profileEditorService.ProfileElement.WhereNotNull().Subscribe(SelectCurrentProfileElement).DisposeWith(d);
|
||||
});
|
||||
this.WhenAnyValue(vm => vm.SelectedTreeItem).Subscribe(model => profileEditorService.ChangeCurrentProfileElement(model?.ProfileElement));
|
||||
}
|
||||
|
||||
public ReactiveCommandWithHistory<Unit, Unit>? AddLayer { get; set; }
|
||||
public ReactiveCommandWithHistory<Unit, Unit>? AddFolder { get; set; }
|
||||
public ReactiveCommand<Unit, Unit>? AddLayer
|
||||
{
|
||||
get => _addLayer;
|
||||
set => this.RaiseAndSetIfChanged(ref _addLayer, value);
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit>? AddFolder
|
||||
{
|
||||
get => _addFolder;
|
||||
set => this.RaiseAndSetIfChanged(ref _addFolder, value);
|
||||
}
|
||||
|
||||
public ObservableCollection<TreeItemViewModel> TreeItems { get; } = new();
|
||||
|
||||
@ -58,15 +65,44 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
|
||||
set => this.RaiseAndSetIfChanged(ref _selectedTreeItem, value);
|
||||
}
|
||||
|
||||
private void Repopulate(ProfileConfiguration profileConfiguration)
|
||||
private void RemoveTreeItemsIfFound(ProfileElement profileElement)
|
||||
{
|
||||
List<TreeItemViewModel> toRemove = TreeItems.Where(t => t.ProfileElement == profileElement).ToList();
|
||||
foreach (TreeItemViewModel treeItemViewModel in toRemove)
|
||||
TreeItems.Remove(treeItemViewModel);
|
||||
}
|
||||
|
||||
private void AddTreeItemIfMissing(ProfileElement profileElement)
|
||||
{
|
||||
if (TreeItems.Any(t => t.ProfileElement == profileElement))
|
||||
return;
|
||||
|
||||
if (profileElement is Folder folder)
|
||||
TreeItems.Insert(folder.Parent.Children.IndexOf(folder), _profileEditorVmFactory.FolderTreeItemViewModel(null, folder));
|
||||
else if (profileElement is Layer layer)
|
||||
TreeItems.Insert(layer.Parent.Children.IndexOf(layer), _profileEditorVmFactory.LayerTreeItemViewModel(null, layer));
|
||||
}
|
||||
|
||||
private void AddFolderToRoot(Profile profile)
|
||||
{
|
||||
Folder rootFolder = profile.GetRootFolder();
|
||||
Folder folder = new(rootFolder, "New folder");
|
||||
_profileEditorService.ExecuteCommand(new AddProfileElement(folder, rootFolder, 0));
|
||||
}
|
||||
|
||||
private void AddLayerToRoot(Profile profile)
|
||||
{
|
||||
Folder rootFolder = profile.GetRootFolder();
|
||||
Layer layer = new(rootFolder, "New layer");
|
||||
_profileEditorService.ExecuteCommand(new AddProfileElement(layer, rootFolder, 0));
|
||||
}
|
||||
|
||||
private void CreateTreeItems(Folder rootFolder)
|
||||
{
|
||||
if (TreeItems.Any())
|
||||
TreeItems.Clear();
|
||||
|
||||
if (profileConfiguration.Profile == null)
|
||||
return;
|
||||
|
||||
foreach (ProfileElement profileElement in profileConfiguration.Profile.GetRootFolder().Children)
|
||||
foreach (ProfileElement profileElement in rootFolder.Children)
|
||||
{
|
||||
if (profileElement is Folder folder)
|
||||
TreeItems.Add(_profileEditorVmFactory.FolderTreeItemViewModel(null, folder));
|
||||
|
||||
@ -1,46 +1,51 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Shared;
|
||||
using HistoricalReactiveCommand;
|
||||
using Artemis.UI.Shared.Services.Interfaces;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
|
||||
{
|
||||
public abstract class TreeItemViewModel : ActivatableViewModelBase
|
||||
{
|
||||
private readonly IWindowService _windowService;
|
||||
private bool _isExpanded;
|
||||
|
||||
protected TreeItemViewModel(TreeItemViewModel? parent, RenderProfileElement profileElement)
|
||||
protected TreeItemViewModel(TreeItemViewModel? parent, RenderProfileElement profileElement, IWindowService windowService)
|
||||
{
|
||||
_windowService = windowService;
|
||||
Parent = parent;
|
||||
ProfileElement = profileElement;
|
||||
|
||||
AddLayerAtIndex = ReactiveCommandEx.CreateWithHistory<int, Layer>("AddLayerAtIndex",
|
||||
(targetIndex, _) => new Layer(ProfileElement, "New folder", targetIndex),
|
||||
(targetIndex, _) =>
|
||||
{
|
||||
Layer toRemove = (Layer) ProfileElement.Children.ElementAt(targetIndex);
|
||||
ProfileElement.RemoveChild(toRemove);
|
||||
return toRemove;
|
||||
},
|
||||
historyId: ProfileElement.Profile.EntityId.ToString()
|
||||
);
|
||||
// AddLayerAtIndex = ReactiveCommandWithHistory.CreateWithHistory<int, Layer>(
|
||||
// (targetIndex, _) => new Layer(ProfileElement, "New folder"),
|
||||
// (targetIndex, _) =>
|
||||
// {
|
||||
// Layer toRemove = (Layer) ProfileElement.Children.ElementAt(targetIndex);
|
||||
// ProfileElement.RemoveChild(toRemove);
|
||||
// return toRemove;
|
||||
// },
|
||||
// historyId: ProfileElement.Profile.EntityId.ToString()
|
||||
// );
|
||||
|
||||
AddFolderAtIndex = ReactiveCommandEx.CreateWithHistory<int, Folder>("AddFolderAtIndex",
|
||||
(targetIndex, _) => new Folder(ProfileElement, "New folder", targetIndex),
|
||||
(targetIndex, _) =>
|
||||
{
|
||||
Folder toRemove = (Folder) ProfileElement.Children.ElementAt(targetIndex);
|
||||
ProfileElement.RemoveChild(toRemove);
|
||||
return toRemove;
|
||||
},
|
||||
historyId: ProfileElement.Profile.EntityId.ToString()
|
||||
);
|
||||
// AddFolderAtIndex = ReactiveCommandWithHistory.CreateWithHistory<int, Folder>(
|
||||
// (targetIndex, _) => new Folder(ProfileElement, "New folder"),
|
||||
// (targetIndex, _) =>
|
||||
// {
|
||||
// Folder toRemove = (Folder) ProfileElement.Children.ElementAt(targetIndex);
|
||||
// ProfileElement.RemoveChild(toRemove);
|
||||
// return toRemove;
|
||||
// },
|
||||
// historyId: ProfileElement.Profile.EntityId.ToString()
|
||||
// );
|
||||
}
|
||||
|
||||
public ReactiveCommandWithHistory<int, Layer> AddLayerAtIndex { get; set; }
|
||||
public ReactiveCommandWithHistory<int, Folder> AddFolderAtIndex { get; set; }
|
||||
public ReactiveCommand<int, Unit> AddLayerAtIndex { get; set; }
|
||||
public ReactiveCommand<int, Unit> AddFolderAtIndex { get; set; }
|
||||
|
||||
public RenderProfileElement ProfileElement { get; }
|
||||
public TreeItemViewModel? Parent { get; set; }
|
||||
@ -51,5 +56,20 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
|
||||
get => _isExpanded;
|
||||
set => this.RaiseAndSetIfChanged(ref _isExpanded, value);
|
||||
}
|
||||
|
||||
public async Task ShowBrokenStateExceptions()
|
||||
{
|
||||
List<IBreakableModel> broken = ProfileElement.GetBrokenHierarchy().Where(b => b.BrokenStateException != null).ToList();
|
||||
|
||||
foreach (IBreakableModel current in broken)
|
||||
{
|
||||
_windowService.ShowExceptionDialog($"{current.BrokenDisplayName} - {current.BrokenState}", current.BrokenStateException!);
|
||||
if (broken.Last() != current)
|
||||
{
|
||||
if (!await _windowService.ShowConfirmContentDialog("Broken state", "Do you want to view the next exception?"))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Services;
|
||||
using Artemis.UI.Services.ProfileEditor;
|
||||
using Artemis.UI.Shared;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor.VisualEditor
|
||||
|
||||
@ -6,6 +6,10 @@
|
||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.ProfileEditor.ProfileEditorView">
|
||||
<UserControl.KeyBindings>
|
||||
<KeyBinding Command="{Binding History.Undo}" Gesture="Ctrl+Z"></KeyBinding>
|
||||
<KeyBinding Command="{Binding History.Redo}" Gesture="Ctrl+Y"></KeyBinding>
|
||||
</UserControl.KeyBindings>
|
||||
<UserControl.Styles>
|
||||
<Style Selector="GridSplitter.editor-grid-splitter-vertical">
|
||||
<Setter Property="MinWidth" Value="4" />
|
||||
|
||||
@ -4,17 +4,20 @@ using Artemis.Core;
|
||||
using Artemis.UI.Screens.ProfileEditor.Panels.MenuBar;
|
||||
using Artemis.UI.Screens.ProfileEditor.ProfileTree;
|
||||
using Artemis.UI.Screens.ProfileEditor.VisualEditor;
|
||||
using Artemis.UI.Services;
|
||||
using Artemis.UI.Services.ProfileEditor;
|
||||
using Ninject;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.ProfileEditor
|
||||
{
|
||||
public class ProfileEditorViewModel : MainScreenViewModel
|
||||
{
|
||||
private ProfileConfiguration? _profile;
|
||||
private ProfileConfiguration? _profileConfiguration;
|
||||
private ProfileEditorHistory? _history;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ProfileEditorViewModel(IScreen hostScreen,
|
||||
IKernel kernel,
|
||||
IProfileEditorService profileEditorService,
|
||||
VisualEditorViewModel visualEditorViewModel,
|
||||
ProfileTreeViewModel profileTreeViewModel,
|
||||
@ -30,17 +33,25 @@ namespace Artemis.UI.Screens.ProfileEditor
|
||||
else
|
||||
MenuBarViewModel = menuBarViewModel;
|
||||
|
||||
this.WhenActivated(disposables => profileEditorService.CurrentProfileConfiguration.WhereNotNull().Subscribe(p => Profile = p).DisposeWith(disposables));
|
||||
|
||||
this.WhenActivated(d => profileEditorService.ProfileConfiguration.WhereNotNull().Subscribe(p => ProfileConfiguration = p).DisposeWith(d));
|
||||
this.WhenActivated(d => profileEditorService.History.Subscribe(history => History = history).DisposeWith(d));
|
||||
}
|
||||
|
||||
public VisualEditorViewModel VisualEditorViewModel { get; }
|
||||
public ProfileTreeViewModel ProfileTreeViewModel { get; }
|
||||
public MenuBarViewModel? MenuBarViewModel { get; }
|
||||
|
||||
public ProfileConfiguration? Profile
|
||||
public ProfileConfiguration? ProfileConfiguration
|
||||
{
|
||||
get => _profile;
|
||||
set => this.RaiseAndSetIfChanged(ref _profile, value);
|
||||
get => _profileConfiguration;
|
||||
set => this.RaiseAndSetIfChanged(ref _profileConfiguration, value);
|
||||
}
|
||||
|
||||
public ProfileEditorHistory? History
|
||||
{
|
||||
get => _history;
|
||||
set => this.RaiseAndSetIfChanged(ref _history, value);
|
||||
}
|
||||
|
||||
public void OpenUrl(string url)
|
||||
|
||||
@ -7,6 +7,7 @@ using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Ninject.Factories;
|
||||
using Artemis.UI.Services;
|
||||
using Artemis.UI.Services.ProfileEditor;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services.Interfaces;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
@ -35,7 +36,7 @@ namespace Artemis.UI.Screens.Sidebar
|
||||
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
profileEditorService.CurrentProfileConfiguration
|
||||
profileEditorService.ProfileConfiguration
|
||||
.Subscribe(p => SelectedProfileConfiguration = ProfileConfigurations.FirstOrDefault(c => ReferenceEquals(c.ProfileConfiguration, p)))
|
||||
.DisposeWith(disposables);
|
||||
this.WhenAnyValue(vm => vm.SelectedProfileConfiguration)
|
||||
|
||||
@ -13,6 +13,7 @@ using Artemis.UI.Screens.Settings;
|
||||
using Artemis.UI.Screens.SurfaceEditor;
|
||||
using Artemis.UI.Screens.Workshop;
|
||||
using Artemis.UI.Services;
|
||||
using Artemis.UI.Services.ProfileEditor;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Services.Interfaces;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
@ -73,7 +74,7 @@ namespace Artemis.UI.Screens.Sidebar
|
||||
profileEditorService.ChangeCurrentProfileConfiguration(null);
|
||||
});
|
||||
|
||||
this.WhenAnyObservable(vm => vm._profileEditorService.CurrentProfileConfiguration)
|
||||
this.WhenAnyObservable(vm => vm._profileEditorService.ProfileConfiguration)
|
||||
.WhereNotNull()
|
||||
.Subscribe(_ =>
|
||||
{
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
namespace Artemis.UI.Services.ProfileEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a command that can be executed and if needed, undone
|
||||
/// </summary>
|
||||
public interface IProfileEditorCommand
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the command
|
||||
/// </summary>
|
||||
string DisplayName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Executes the command
|
||||
/// </summary>
|
||||
void Execute();
|
||||
|
||||
/// <summary>
|
||||
/// Undoes the command
|
||||
/// </summary>
|
||||
void Undo();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
|
||||
namespace Artemis.UI.Services.ProfileEditor
|
||||
{
|
||||
public interface IProfileEditorService : IArtemisUIService
|
||||
{
|
||||
IObservable<ProfileConfiguration?> ProfileConfiguration { get; }
|
||||
IObservable<RenderProfileElement?> ProfileElement { get; }
|
||||
IObservable<ProfileEditorHistory?> History { get; }
|
||||
|
||||
void ChangeCurrentProfileConfiguration(ProfileConfiguration? profileConfiguration);
|
||||
void ChangeCurrentProfileElement(RenderProfileElement? renderProfileElement);
|
||||
void ExecuteCommand(IProfileEditorCommand command);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive.Subjects;
|
||||
using Artemis.Core;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Services.ProfileEditor
|
||||
{
|
||||
public class ProfileEditorHistory
|
||||
{
|
||||
private readonly Subject<bool> _canRedo = new();
|
||||
private readonly Subject<bool> _canUndo = new();
|
||||
private readonly Stack<IProfileEditorCommand> _redoCommands = new();
|
||||
private readonly Stack<IProfileEditorCommand> _undoCommands = new();
|
||||
|
||||
public ProfileEditorHistory(ProfileConfiguration profileConfiguration)
|
||||
{
|
||||
ProfileConfiguration = profileConfiguration;
|
||||
|
||||
Execute = ReactiveCommand.Create<IProfileEditorCommand>(ExecuteEditorCommand);
|
||||
Undo = ReactiveCommand.Create(ExecuteUndo, CanUndo);
|
||||
Redo = ReactiveCommand.Create(ExecuteRedo, CanRedo);
|
||||
}
|
||||
|
||||
public ProfileConfiguration ProfileConfiguration { get; }
|
||||
public IObservable<bool> CanUndo => _canUndo.AsObservable().DistinctUntilChanged();
|
||||
public IObservable<bool> CanRedo => _canRedo.AsObservable().DistinctUntilChanged();
|
||||
|
||||
public ReactiveCommand<IProfileEditorCommand, Unit> Execute { get; }
|
||||
public ReactiveCommand<Unit, Unit> Undo { get; }
|
||||
public ReactiveCommand<Unit, Unit> Redo { get; }
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
ClearRedo();
|
||||
ClearUndo();
|
||||
UpdateSubjects();
|
||||
}
|
||||
|
||||
public void ExecuteEditorCommand(IProfileEditorCommand command)
|
||||
{
|
||||
command.Execute();
|
||||
|
||||
_undoCommands.Push(command);
|
||||
ClearRedo();
|
||||
UpdateSubjects();
|
||||
}
|
||||
|
||||
private void ClearRedo()
|
||||
{
|
||||
foreach (IProfileEditorCommand profileEditorCommand in _redoCommands)
|
||||
if (profileEditorCommand is IDisposable disposable)
|
||||
disposable.Dispose();
|
||||
|
||||
_redoCommands.Clear();
|
||||
}
|
||||
|
||||
private void ClearUndo()
|
||||
{
|
||||
foreach (IProfileEditorCommand profileEditorCommand in _undoCommands)
|
||||
if (profileEditorCommand is IDisposable disposable)
|
||||
disposable.Dispose();
|
||||
|
||||
_undoCommands.Clear();
|
||||
}
|
||||
|
||||
private void ExecuteUndo()
|
||||
{
|
||||
if (!_undoCommands.TryPop(out IProfileEditorCommand? command))
|
||||
return;
|
||||
|
||||
command.Undo();
|
||||
_redoCommands.Push(command);
|
||||
UpdateSubjects();
|
||||
}
|
||||
|
||||
private void ExecuteRedo()
|
||||
{
|
||||
if (!_redoCommands.TryPop(out IProfileEditorCommand? command))
|
||||
return;
|
||||
|
||||
command.Execute();
|
||||
_undoCommands.Push(command);
|
||||
UpdateSubjects();
|
||||
}
|
||||
|
||||
private void UpdateSubjects()
|
||||
{
|
||||
_canUndo.OnNext(_undoCommands.Any());
|
||||
_canRedo.OnNext(_redoCommands.Any());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive.Subjects;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Exceptions;
|
||||
|
||||
namespace Artemis.UI.Services.ProfileEditor
|
||||
{
|
||||
public class ProfileEditorService : IProfileEditorService
|
||||
{
|
||||
private readonly Dictionary<ProfileConfiguration, ProfileEditorHistory> _profileEditorHistories = new();
|
||||
private readonly BehaviorSubject<ProfileConfiguration?> _profileConfigurationSubject = new(null);
|
||||
private readonly BehaviorSubject<RenderProfileElement?> _profileElementSubject = new(null);
|
||||
|
||||
public ProfileEditorService()
|
||||
{
|
||||
ProfileConfiguration = _profileConfigurationSubject.AsObservable().DistinctUntilChanged();
|
||||
ProfileElement = _profileElementSubject.AsObservable().DistinctUntilChanged();
|
||||
History = Observable.Defer(() => Observable.Return(GetHistory(_profileConfigurationSubject.Value))).Concat(ProfileConfiguration.Select(GetHistory));
|
||||
}
|
||||
|
||||
private ProfileEditorHistory? GetHistory(ProfileConfiguration? profileConfiguration)
|
||||
{
|
||||
if (profileConfiguration == null)
|
||||
return null;
|
||||
if (_profileEditorHistories.TryGetValue(profileConfiguration, out ProfileEditorHistory? history))
|
||||
return history;
|
||||
|
||||
ProfileEditorHistory newHistory = new(profileConfiguration);
|
||||
_profileEditorHistories.Add(profileConfiguration, newHistory);
|
||||
return newHistory;
|
||||
}
|
||||
|
||||
public IObservable<ProfileConfiguration?> ProfileConfiguration { get; }
|
||||
public IObservable<RenderProfileElement?> ProfileElement { get; }
|
||||
public IObservable<ProfileEditorHistory?> History { get; }
|
||||
|
||||
public void ChangeCurrentProfileConfiguration(ProfileConfiguration? profileConfiguration)
|
||||
{
|
||||
_profileConfigurationSubject.OnNext(profileConfiguration);
|
||||
}
|
||||
|
||||
public void ChangeCurrentProfileElement(RenderProfileElement? renderProfileElement)
|
||||
{
|
||||
_profileElementSubject.OnNext(renderProfileElement);
|
||||
}
|
||||
|
||||
public void ExecuteCommand(IProfileEditorCommand command)
|
||||
{
|
||||
ProfileEditorHistory? history = GetHistory(_profileConfigurationSubject.Value);
|
||||
if (history == null)
|
||||
throw new ArtemisUIException("Can't execute a command when there's no active profile configuration");
|
||||
|
||||
history.Execute.Execute(command).Subscribe();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,50 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reactive.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Services.Interfaces;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Services
|
||||
{
|
||||
public class ProfileEditorService : IProfileEditorService
|
||||
{
|
||||
private readonly ReactiveCommand<ProfileConfiguration?, ProfileConfiguration?> _changeCurrentProfileConfiguration;
|
||||
private readonly ReactiveCommand<RenderProfileElement?, RenderProfileElement?> _changeCurrentProfileElement;
|
||||
private ProfileConfiguration? _currentProfileConfiguration;
|
||||
private RenderProfileElement? _currentProfileElement;
|
||||
|
||||
public ProfileEditorService()
|
||||
{
|
||||
_changeCurrentProfileConfiguration = ReactiveCommand.CreateFromObservable<ProfileConfiguration?, ProfileConfiguration?>(Observable.Return);
|
||||
_changeCurrentProfileElement = ReactiveCommand.CreateFromObservable<RenderProfileElement?, RenderProfileElement?>(Observable.Return);
|
||||
|
||||
CurrentProfileConfiguration = Observable.Defer(() => Observable.Return(_currentProfileConfiguration)).Concat(_changeCurrentProfileConfiguration);
|
||||
CurrentProfileElement = Observable.Defer(() => Observable.Return(_currentProfileElement)).Concat(_changeCurrentProfileElement);
|
||||
}
|
||||
|
||||
public IObservable<ProfileConfiguration?> CurrentProfileConfiguration { get; }
|
||||
public IObservable<RenderProfileElement?> CurrentProfileElement { get; }
|
||||
|
||||
public void ChangeCurrentProfileConfiguration(ProfileConfiguration? profileConfiguration)
|
||||
{
|
||||
_currentProfileConfiguration = profileConfiguration;
|
||||
_changeCurrentProfileConfiguration.Execute(profileConfiguration).Subscribe();
|
||||
}
|
||||
|
||||
public void ChangeCurrentProfileElement(RenderProfileElement? renderProfileElement)
|
||||
{
|
||||
_currentProfileElement = renderProfileElement;
|
||||
_changeCurrentProfileElement.Execute(renderProfileElement).Subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
public interface IProfileEditorService : IArtemisUIService
|
||||
{
|
||||
IObservable<ProfileConfiguration?> CurrentProfileConfiguration { get; }
|
||||
IObservable<RenderProfileElement?> CurrentProfileElement { get; }
|
||||
|
||||
void ChangeCurrentProfileConfiguration(ProfileConfiguration? profileConfiguration);
|
||||
void ChangeCurrentProfileElement(RenderProfileElement? renderProfileElement);
|
||||
}
|
||||
}
|
||||
@ -117,16 +117,12 @@
|
||||
},
|
||||
"ReactiveUI": {
|
||||
"type": "Direct",
|
||||
"requested": "[17.1.9, )",
|
||||
"resolved": "17.1.9",
|
||||
"contentHash": "bxH6uzEi1b6cfGoBBvCXWrdT18+Rleggi0R/vOaCYc+zvlSleJW6wlUtcWjrKzgQHD8EN3c02A4JBTt9oGSWWQ==",
|
||||
"requested": "[16.3.10, )",
|
||||
"resolved": "16.3.10",
|
||||
"contentHash": "NH9bg8BROqRrTp6YLpPDsJrfNDzRWNmP63fQ68CBAM+i7YHi6wcPeOkxyKpoemUxKEY4QECuicaTblJnxgbWmA==",
|
||||
"dependencies": {
|
||||
"DynamicData": "7.4.3",
|
||||
"Splat": "14.1.1",
|
||||
"System.ComponentModel": "4.3.0",
|
||||
"System.Diagnostics.Contracts": "4.3.0",
|
||||
"System.Dynamic.Runtime": "4.3.0",
|
||||
"System.Runtime.Serialization.Primitives": "4.3.0"
|
||||
"Splat": "13.1.42"
|
||||
}
|
||||
},
|
||||
"ReactiveUI.Validation": {
|
||||
@ -933,14 +929,6 @@
|
||||
"System.Text.Encoding": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.Contracts": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "eelRRbnm+OloiQvp9CXS0ixjNQldjjkHO4iIkR5XH2VIP8sUB/SIpa1TdUW6/+HDcQ+MlhP3pNa1u5SbzYuWGA==",
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.Debug": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
@ -1421,15 +1409,6 @@
|
||||
"System.Runtime.Extensions": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.Serialization.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==",
|
||||
"dependencies": {
|
||||
"System.Resources.ResourceManager": "4.3.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Security.AccessControl": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
@ -1785,7 +1764,7 @@
|
||||
"FluentAvaloniaUI": "1.1.8",
|
||||
"Material.Icons.Avalonia": "1.0.2",
|
||||
"RGB.NET.Core": "1.0.0-prerelease1",
|
||||
"ReactiveUI": "17.1.9",
|
||||
"ReactiveUI": "16.3.10",
|
||||
"ReactiveUI.Validation": "2.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user