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

Profile elements - Added Windows Explorer-like naming of new elements

This commit is contained in:
Robert 2022-02-15 23:19:38 +01:00
parent b503906b9a
commit 013bc1c316
4 changed files with 92 additions and 58 deletions

View File

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text.RegularExpressions;
using SkiaSharp;
namespace Artemis.Core
@ -11,6 +12,7 @@ namespace Artemis.Core
/// </summary>
public abstract class ProfileElement : BreakableModel, IDisposable
{
internal readonly List<ProfileElement> ChildrenList;
private Guid _entityId;
private string? _name;
private int _order;
@ -18,8 +20,6 @@ namespace Artemis.Core
private Profile _profile;
private bool _suspended;
internal readonly List<ProfileElement> ChildrenList;
internal ProfileElement(Profile profile)
{
_profile = profile;
@ -120,6 +120,49 @@ namespace Artemis.Core
return $"{nameof(EntityId)}: {EntityId}, {nameof(Order)}: {Order}, {nameof(Name)}: {Name}";
}
/// <summary>
/// Occurs when a child was added to the <see cref="Children" /> list
/// </summary>
public event EventHandler<ProfileElementEventArgs>? ChildAdded;
/// <summary>
/// Occurs when a child was removed from the <see cref="Children" /> list
/// </summary>
public event EventHandler<ProfileElementEventArgs>? ChildRemoved;
/// <summary>
/// Invokes the <see cref="ChildAdded" /> event
/// </summary>
protected virtual void OnChildAdded(ProfileElement child)
{
ChildAdded?.Invoke(this, new ProfileElementEventArgs(child));
}
/// <summary>
/// Invokes the <see cref="ChildRemoved" /> event
/// </summary>
protected virtual void OnChildRemoved(ProfileElement child)
{
ChildRemoved?.Invoke(this, new ProfileElementEventArgs(child));
}
/// <summary>
/// Disposes the profile element
/// </summary>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
}
}
/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#region Hierarchy
/// <summary>
@ -248,6 +291,48 @@ namespace Artemis.Core
return layers;
}
/// <summary>
/// Returns a name for a new layer according to any other layers with a default name similar to creating new folders in
/// Explorer
/// </summary>
/// <returns>The resulting name i.e. <c>New layer</c> or <c>New layer (2)</c></returns>
public string GetNewLayerName()
{
if (!Children.Any(c => c is Layer))
return "New layer";
// Grab existing unnamed layers and get the first available number
// Looks slow but it's not https://stackoverflow.com/a/8865806/5015269
Regex regex = new(@"New layer \((\d+)\)");
int firstAvailable = Enumerable.Range(1, int.MaxValue)
.Except(Children.Where(c => c is Layer && c.Name != null && regex.IsMatch(c.Name))
.Select(c => int.Parse(regex.Match(c.Name!).Groups[1].Value))
.OrderBy(i => i))
.First();
return $"New layer ({firstAvailable})";
}
/// <summary>
/// Returns a name for a new folder according to any other folders with a default name similar to creating new folders
/// in Explorer
/// </summary>
/// <returns>The resulting name i.e. <c>New folder</c> or <c>New folder (2)</c></returns>
public string GetNewFolderName()
{
if (!Children.Any(c => c is Folder))
return "New folder";
// Grab existing unnamed layers and get the first available number
// Looks slow but it's not https://stackoverflow.com/a/8865806/5015269
Regex regex = new(@"New folder \((\d+)\)");
int firstAvailable = Enumerable.Range(1, int.MaxValue)
.Except(Children.Where(c => c is Folder && c.Name != null && regex.IsMatch(c.Name))
.Select(c => int.Parse(regex.Match(c.Name!).Groups[1].Value))
.OrderBy(i => i))
.First();
return $"New folder ({firstAvailable})";
}
#endregion
#region Storage
@ -256,56 +341,5 @@ namespace Artemis.Core
internal abstract void Save();
#endregion
#region Events
/// <summary>
/// Occurs when a child was added to the <see cref="Children" /> list
/// </summary>
public event EventHandler<ProfileElementEventArgs>? ChildAdded;
/// <summary>
/// Occurs when a child was removed from the <see cref="Children" /> list
/// </summary>
public event EventHandler<ProfileElementEventArgs>? ChildRemoved;
/// <summary>
/// Invokes the <see cref="ChildAdded" /> event
/// </summary>
protected virtual void OnChildAdded(ProfileElement child)
{
ChildAdded?.Invoke(this, new ProfileElementEventArgs(child));
}
/// <summary>
/// Invokes the <see cref="ChildRemoved" /> event
/// </summary>
protected virtual void OnChildRemoved(ProfileElement child)
{
ChildRemoved?.Invoke(this, new ProfileElementEventArgs(child));
}
#endregion
#region IDisposable
/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Disposes the profile element
/// </summary>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
}
}
#endregion
}
}

View File

@ -42,13 +42,13 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
{
if (ProfileElement is Layer targetLayer)
{
Layer layer = new(targetLayer.Parent, "New layer");
Layer layer = new(targetLayer.Parent, targetLayer.GetNewLayerName());
layer.AddLeds(rgbService.EnabledDevices.SelectMany(d => d.Leds));
profileEditorService.ExecuteCommand(new AddProfileElement(layer, targetLayer.Parent, targetLayer.Order));
}
else if (ProfileElement != null)
{
Layer layer = new(ProfileElement, "New layer");
Layer layer = new(ProfileElement, ProfileElement.GetNewLayerName());
layer.AddLeds(rgbService.EnabledDevices.SelectMany(d => d.Leds));
profileEditorService.ExecuteCommand(new AddProfileElement(layer, ProfileElement, 0));
}
@ -57,9 +57,9 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree
AddFolder = ReactiveCommand.Create(() =>
{
if (ProfileElement is Layer targetLayer)
profileEditorService.ExecuteCommand(new AddProfileElement(new Folder(targetLayer.Parent, "New folder"), targetLayer.Parent, targetLayer.Order));
profileEditorService.ExecuteCommand(new AddProfileElement(new Folder(targetLayer.Parent, targetLayer.Parent.GetNewFolderName()), targetLayer.Parent, targetLayer.Order));
else if (ProfileElement != null)
profileEditorService.ExecuteCommand(new AddProfileElement(new Folder(ProfileElement, "New folder"), ProfileElement, 0));
profileEditorService.ExecuteCommand(new AddProfileElement(new Folder(ProfileElement, ProfileElement.GetNewFolderName()), ProfileElement, 0));
});
Rename = ReactiveCommand.Create(() =>

View File

@ -56,6 +56,7 @@ public class VisualEditorViewModel : ActivatableViewModelBase
private void CreateVisualizers(ProfileConfiguration? profileConfiguration)
{
// TODO: Monitor and respond to new layers/folders and deletions
_visualizers.Edit(list =>
{
list.Clear();

View File

@ -7,7 +7,6 @@ using Artemis.UI.Shared.Services.ProfileEditor;
using Avalonia;
using Avalonia.Controls.Mixins;
using ReactiveUI;
using ShimSkiaSharp;
using SKRect = SkiaSharp.SKRect;
namespace Artemis.UI.Screens.ProfileEditor.VisualEditor.Visualizers;