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:
parent
b503906b9a
commit
013bc1c316
@ -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
|
||||
}
|
||||
}
|
||||
@ -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(() =>
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user