Add ability to send selected skin components to front or back

This commit is contained in:
Dean Herbert 2023-02-22 17:45:38 +09:00
parent 4f9f4b3970
commit 16c8a392a1
4 changed files with 49 additions and 4 deletions

View File

@ -556,11 +556,46 @@ namespace osu.Game.Overlays.SkinEditor
changeHandler?.BeginChange(); changeHandler?.BeginChange();
foreach (var item in items) foreach (var item in items)
availableTargets.FirstOrDefault(t => t.Components.Contains(item))?.Remove(item); availableTargets.FirstOrDefault(t => t.Components.Contains(item))?.Remove(item, true);
changeHandler?.EndChange(); changeHandler?.EndChange();
} }
public void BringSelectionToFront()
{
if (getTarget(selectedTarget.Value) is not SkinComponentsContainer target)
return;
// Iterating by target components order ensures we maintain the same order across selected components, regardless
// of the order they were selected in.
foreach (var d in target.Components.ToArray())
{
if (!SelectedComponents.Contains(d))
continue;
target.Remove(d, false);
// Selection would be reset by the remove.
SelectedComponents.Add(d);
target.Add(d);
}
}
public void SendSelectionToBack()
{
if (getTarget(selectedTarget.Value) is not SkinComponentsContainer target)
return;
foreach (var d in target.Components.ToArray())
{
if (SelectedComponents.Contains(d))
continue;
target.Remove(d, false);
target.Add(d);
}
}
#region Drag & drop import handling #region Drag & drop import handling
public Task Import(params string[] paths) public Task Import(params string[] paths)

View File

@ -13,6 +13,7 @@ using osu.Framework.Utils;
using osu.Game.Extensions; using osu.Game.Extensions;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Screens.Edit.Components.Menus;
using osu.Game.Screens.Edit.Compose.Components; using osu.Game.Screens.Edit.Compose.Components;
using osu.Game.Skinning; using osu.Game.Skinning;
using osuTK; using osuTK;
@ -206,6 +207,14 @@ namespace osu.Game.Overlays.SkinEditor
((Drawable)blueprint.Item).Position = Vector2.Zero; ((Drawable)blueprint.Item).Position = Vector2.Zero;
}); });
yield return new EditorMenuItemSpacer();
yield return new OsuMenuItem("Bring to front", MenuItemType.Standard, () => skinEditor.BringSelectionToFront());
yield return new OsuMenuItem("Send to back", MenuItemType.Standard, () => skinEditor.SendSelectionToBack());
yield return new EditorMenuItemSpacer();
foreach (var item in base.GetContextMenuItemsForSelection(selection)) foreach (var item in base.GetContextMenuItemsForSelection(selection))
yield return item; yield return item;

View File

@ -45,6 +45,7 @@ namespace osu.Game.Skinning
/// Remove an existing skinnable component from this target. /// Remove an existing skinnable component from this target.
/// </summary> /// </summary>
/// <param name="component">The component to remove.</param> /// <param name="component">The component to remove.</param>
void Remove(ISerialisableDrawable component); /// <param name="disposeImmediately">Whether removed items should be immediately disposed.</param>
void Remove(ISerialisableDrawable component, bool disposeImmediately);
} }
} }

View File

@ -100,7 +100,7 @@ namespace osu.Game.Skinning
/// <inheritdoc cref="ISerialisableDrawableContainer"/> /// <inheritdoc cref="ISerialisableDrawableContainer"/>
/// <exception cref="NotSupportedException">Thrown when attempting to add an element to a target which is not supported by the current skin.</exception> /// <exception cref="NotSupportedException">Thrown when attempting to add an element to a target which is not supported by the current skin.</exception>
/// <exception cref="ArgumentException">Thrown if the provided instance is not a <see cref="Drawable"/>.</exception> /// <exception cref="ArgumentException">Thrown if the provided instance is not a <see cref="Drawable"/>.</exception>
public void Remove(ISerialisableDrawable component) public void Remove(ISerialisableDrawable component, bool disposeImmediately)
{ {
if (content == null) if (content == null)
throw new NotSupportedException("Attempting to remove a new component from a target container which is not supported by the current skin."); throw new NotSupportedException("Attempting to remove a new component from a target container which is not supported by the current skin.");
@ -108,7 +108,7 @@ namespace osu.Game.Skinning
if (!(component is Drawable drawable)) if (!(component is Drawable drawable))
throw new ArgumentException($"Provided argument must be of type {nameof(Drawable)}.", nameof(component)); throw new ArgumentException($"Provided argument must be of type {nameof(Drawable)}.", nameof(component));
content.Remove(drawable, true); content.Remove(drawable, disposeImmediately);
components.Remove(component); components.Remove(component);
} }