diff --git a/src/Artemis.Core/Models/Profile/Folder.cs b/src/Artemis.Core/Models/Profile/Folder.cs index 93867bd08..6f4fd1d1c 100644 --- a/src/Artemis.Core/Models/Profile/Folder.cs +++ b/src/Artemis.Core/Models/Profile/Folder.cs @@ -52,7 +52,10 @@ namespace Artemis.Core /// public bool IsRootFolder => Parent == Profile; - internal FolderEntity FolderEntity { get; set; } + /// + /// Gets the folder entity this folder uses for persistent storage + /// + public FolderEntity FolderEntity { get; internal set; } internal override RenderElementEntity RenderElementEntity => FolderEntity; diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs index 9064e03ef..51da2b65f 100644 --- a/src/Artemis.Core/Models/Profile/Layer.cs +++ b/src/Artemis.Core/Models/Profile/Layer.cs @@ -6,7 +6,6 @@ using Artemis.Core.LayerBrushes; using Artemis.Core.LayerEffects; using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile.Abstract; -using Newtonsoft.Json; using SkiaSharp; namespace Artemis.Core @@ -18,9 +17,9 @@ namespace Artemis.Core { private LayerGeneralProperties _general; private BaseLayerBrush? _layerBrush; - private LayerTransformProperties _transform; private LayerShape? _layerShape; private List _leds; + private LayerTransformProperties _transform; /// /// Creates a new instance of the class and adds itself to the child collection of the provided @@ -46,7 +45,13 @@ namespace Artemis.Core Parent.AddChild(this); } - internal Layer(Profile profile, ProfileElement parent, LayerEntity layerEntity) : base(parent.Profile) + /// + /// Creates a new instance of the class based on the provided layer entity + /// + /// The profile the layer belongs to + /// The parent of the layer + /// The entity of the layer + public Layer(Profile profile, ProfileElement parent, LayerEntity layerEntity) : base(parent.Profile) { LayerEntity = layerEntity; EntityId = layerEntity.Id; @@ -82,7 +87,7 @@ namespace Artemis.Core } /// - /// Gets the general properties of the layer + /// Gets the general properties of the layer /// [PropertyGroupDescription(Name = "General", Description = "A collection of general properties")] public LayerGeneralProperties General @@ -92,7 +97,7 @@ namespace Artemis.Core } /// - /// Gets the transform properties of the layer + /// Gets the transform properties of the layer /// [PropertyGroupDescription(Name = "Transform", Description = "A collection of transformation properties")] public LayerTransformProperties Transform @@ -110,7 +115,10 @@ namespace Artemis.Core internal set => SetAndNotify(ref _layerBrush, value); } - internal LayerEntity LayerEntity { get; set; } + /// + /// Gets the layer entity this layer uses for persistent storage + /// + public LayerEntity LayerEntity { get; internal set; } internal override RenderElementEntity RenderElementEntity => LayerEntity; diff --git a/src/Artemis.Core/Models/Profile/ProfileElement.cs b/src/Artemis.Core/Models/Profile/ProfileElement.cs index b9ee1b524..5b25c82c5 100644 --- a/src/Artemis.Core/Models/Profile/ProfileElement.cs +++ b/src/Artemis.Core/Models/Profile/ProfileElement.cs @@ -143,6 +143,8 @@ namespace Artemis.Core // Shift everything after the given order else { + if (order < 0) + order = 0; foreach (ProfileElement profileElement in ChildrenList.Where(c => c.Order >= order).ToList()) profileElement.Order++; diff --git a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs index 9fc045777..fc9e59ba2 100644 --- a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs +++ b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs @@ -114,7 +114,6 @@ namespace Artemis.Core #region Properties - private ProfileElement? _parent; private SKPath? _path; internal abstract RenderElementEntity RenderElementEntity { get; } @@ -123,10 +122,11 @@ namespace Artemis.Core /// public new ProfileElement? Parent { - get => _parent; + get => base.Parent; internal set { - SetAndNotify(ref _parent, value); + base.Parent = value; + OnPropertyChanged(nameof(Parent)); Renderer.Invalidate(); } } diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml index 2bfeabae5..33414f284 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml @@ -36,6 +36,8 @@ + + diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerView.xaml b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerView.xaml index 846634132..65f09b121 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerView.xaml +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerView.xaml @@ -18,7 +18,7 @@ - + diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerViewModel.cs index 7a69797ec..534db413e 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/LayerViewModel.cs @@ -21,7 +21,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem _profileEditorService = profileEditorService; } - public void CopyElement() + public void DuplicateElement() { Layer layer = Layer.CreateCopy(); diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs index a84d409e0..b1c85351e 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs @@ -5,10 +5,12 @@ using System.Threading.Tasks; using Artemis.Core; using Artemis.Core.LayerBrushes; using Artemis.Core.Services; +using Artemis.Storage.Entities.Profile; using Artemis.UI.Exceptions; using Artemis.UI.Ninject.Factories; using Artemis.UI.Screens.ProfileEditor.Dialogs; using Artemis.UI.Shared.Services; +using Artemis.UI.Utilities; using Stylet; namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem @@ -185,6 +187,29 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem _profileEditorService.ChangeSelectedProfileElement(null); } + public void CopyElement() + { + if (ProfileElement is Layer layer) + JsonClipboard.SetObject(layer.LayerEntity); + else if (ProfileElement is Folder folder) + JsonClipboard.SetObject(folder.FolderEntity); + } + + public void PasteElement() + { + object? clipboardObject = JsonClipboard.GetData(); + if (clipboardObject is LayerEntity layerEntity) + { + layerEntity.Id = Guid.NewGuid(); + layerEntity.Name += " - copy"; + Layer pasted = new Layer(ProfileElement.Profile, ProfileElement.Parent, layerEntity); + ProfileElement.Parent.AddChild(pasted, ProfileElement.Order - 1); + } + else if (clipboardObject is FolderEntity folderEntity) + { + } + } + public void UpdateProfileElements() { // Remove VMs that are no longer a child diff --git a/src/Artemis.UI/Utilities/ClipboardHelper.cs b/src/Artemis.UI/Utilities/ClipboardHelper.cs new file mode 100644 index 000000000..20cb8975f --- /dev/null +++ b/src/Artemis.UI/Utilities/ClipboardHelper.cs @@ -0,0 +1,35 @@ +using System.Windows; +using Newtonsoft.Json; + +namespace Artemis.UI.Utilities +{ + public static class JsonClipboard + { + private static readonly JsonSerializerSettings JsonSettings = new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.All}; + + public static void SetObject(object clipboardObject) + { + string json = JsonConvert.SerializeObject(clipboardObject, JsonSettings); + Clipboard.SetData("Artemis", json); + } + + public static object GetData() + { + string json = Clipboard.GetData("Artemis")?.ToString(); + if (json != null) + return JsonConvert.DeserializeObject(json, JsonSettings); + return null; + } + + public static T GetData() + { + object data = GetData(); + return data is T castData ? castData : default; + } + + public static bool ContainsArtemisData() + { + return Clipboard.ContainsData("Artemis"); + } + } +} \ No newline at end of file