1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 12:17:26 +08:00

Merge branch 'taiko-single-tap' of https://github.com/OpenSauce04/osu into taiko-single-tap

This commit is contained in:
OpenSauce04 2023-02-28 15:37:54 +00:00
commit 8851da05f1
10 changed files with 120 additions and 16 deletions

View File

@ -10,7 +10,7 @@
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk> <EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ppy.osu.Framework.Android" Version="2023.131.0" /> <PackageReference Include="ppy.osu.Framework.Android" Version="2023.228.0" />
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
<!-- Fody does not handle Android build well, and warns when unchanged. <!-- Fody does not handle Android build well, and warns when unchanged.

View File

@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Taiko.Mods
{ {
public class TaikoModRelax : ModRelax public class TaikoModRelax : ModRelax
{ {
public override LocalisableString Description => @"No ninja-like spinners, demanding drumrolls or unexpected katu's."; public override LocalisableString Description => @"No ninja-like spinners, demanding drumrolls or unexpected katus.";
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(TaikoModSingleTap) }).ToArray(); public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(TaikoModSingleTap) }).ToArray();
} }

View File

@ -1,9 +1,11 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.UserInterface;
using osu.Framework.Testing; using osu.Framework.Testing;
@ -21,7 +23,7 @@ namespace osu.Game.Tests.Visual.Gameplay
{ {
public partial class TestSceneSkinEditor : PlayerTestScene public partial class TestSceneSkinEditor : PlayerTestScene
{ {
private SkinEditor? skinEditor; private SkinEditor skinEditor = null!;
protected override bool Autoplay => true; protected override bool Autoplay => true;
@ -31,26 +33,75 @@ namespace osu.Game.Tests.Visual.Gameplay
[Cached] [Cached]
public readonly EditorClipboard Clipboard = new EditorClipboard(); public readonly EditorClipboard Clipboard = new EditorClipboard();
private SkinComponentsContainer targetContainer => Player.ChildrenOfType<SkinComponentsContainer>().First();
[SetUpSteps] [SetUpSteps]
public override void SetUpSteps() public override void SetUpSteps()
{ {
base.SetUpSteps(); base.SetUpSteps();
AddUntilStep("wait for hud load", () => Player.ChildrenOfType<SkinComponentsContainer>().All(c => c.ComponentsLoaded)); AddUntilStep("wait for hud load", () => targetContainer.ComponentsLoaded);
AddStep("reload skin editor", () => AddStep("reload skin editor", () =>
{ {
skinEditor?.Expire(); if (skinEditor.IsNotNull())
skinEditor.Expire();
Player.ScaleTo(0.4f); Player.ScaleTo(0.4f);
LoadComponentAsync(skinEditor = new SkinEditor(Player), Add); LoadComponentAsync(skinEditor = new SkinEditor(Player), Add);
}); });
AddUntilStep("wait for loaded", () => skinEditor!.IsLoaded); AddUntilStep("wait for loaded", () => skinEditor.IsLoaded);
}
[TestCase(false)]
[TestCase(true)]
public void TestBringToFront(bool alterSelectionOrder)
{
AddAssert("Ensure over three components available", () => targetContainer.Components.Count, () => Is.GreaterThan(3));
IEnumerable<ISerialisableDrawable> originalOrder = null!;
AddStep("Save order of components before operation", () => originalOrder = targetContainer.Components.Take(3).ToArray());
if (alterSelectionOrder)
AddStep("Select first three components in reverse order", () => skinEditor.SelectedComponents.AddRange(originalOrder.Reverse()));
else
AddStep("Select first three components", () => skinEditor.SelectedComponents.AddRange(originalOrder));
AddAssert("Components are not front-most", () => targetContainer.Components.TakeLast(3).ToArray(), () => Is.Not.EqualTo(skinEditor.SelectedComponents));
AddStep("Bring to front", () => skinEditor.BringSelectionToFront());
AddAssert("Ensure components are now front-most in original order", () => targetContainer.Components.TakeLast(3).ToArray(), () => Is.EqualTo(originalOrder));
AddStep("Bring to front again", () => skinEditor.BringSelectionToFront());
AddAssert("Ensure components are still front-most in original order", () => targetContainer.Components.TakeLast(3).ToArray(), () => Is.EqualTo(originalOrder));
}
[TestCase(false)]
[TestCase(true)]
public void TestSendToBack(bool alterSelectionOrder)
{
AddAssert("Ensure over three components available", () => targetContainer.Components.Count, () => Is.GreaterThan(3));
IEnumerable<ISerialisableDrawable> originalOrder = null!;
AddStep("Save order of components before operation", () => originalOrder = targetContainer.Components.TakeLast(3).ToArray());
if (alterSelectionOrder)
AddStep("Select last three components in reverse order", () => skinEditor.SelectedComponents.AddRange(originalOrder.Reverse()));
else
AddStep("Select last three components", () => skinEditor.SelectedComponents.AddRange(originalOrder));
AddAssert("Components are not back-most", () => targetContainer.Components.Take(3).ToArray(), () => Is.Not.EqualTo(skinEditor.SelectedComponents));
AddStep("Send to back", () => skinEditor.SendSelectionToBack());
AddAssert("Ensure components are now back-most in original order", () => targetContainer.Components.Take(3).ToArray(), () => Is.EqualTo(originalOrder));
AddStep("Send to back again", () => skinEditor.SendSelectionToBack());
AddAssert("Ensure components are still back-most in original order", () => targetContainer.Components.Take(3).ToArray(), () => Is.EqualTo(originalOrder));
} }
[Test] [Test]
public void TestToggleEditor() public void TestToggleEditor()
{ {
AddToggleStep("toggle editor visibility", _ => skinEditor!.ToggleVisibility()); AddToggleStep("toggle editor visibility", _ => skinEditor.ToggleVisibility());
} }
[Test] [Test]
@ -63,7 +114,7 @@ namespace osu.Game.Tests.Visual.Gameplay
var blueprint = skinEditor.ChildrenOfType<SkinBlueprint>().First(b => b.Item is BarHitErrorMeter); var blueprint = skinEditor.ChildrenOfType<SkinBlueprint>().First(b => b.Item is BarHitErrorMeter);
hitErrorMeter = (BarHitErrorMeter)blueprint.Item; hitErrorMeter = (BarHitErrorMeter)blueprint.Item;
skinEditor!.SelectedComponents.Clear(); skinEditor.SelectedComponents.Clear();
skinEditor.SelectedComponents.Add(blueprint.Item); skinEditor.SelectedComponents.Add(blueprint.Item);
}); });

View File

@ -82,6 +82,7 @@ namespace osu.Game.Overlays.SkinEditor
{ {
Text = Item.GetType().Name, Text = Item.GetType().Name,
Font = OsuFont.Default.With(size: 10, weight: FontWeight.Bold), Font = OsuFont.Default.With(size: 10, weight: FontWeight.Bold),
Alpha = 0,
Anchor = Anchor.BottomRight, Anchor = Anchor.BottomRight,
Origin = Anchor.TopRight, Origin = Anchor.TopRight,
}, },
@ -99,7 +100,6 @@ namespace osu.Game.Overlays.SkinEditor
base.LoadComplete(); base.LoadComplete();
updateSelectedState(); updateSelectedState();
this.FadeInFromZero(200, Easing.OutQuint);
} }
protected override bool OnHover(HoverEvent e) protected override bool OnHover(HoverEvent e)

View File

@ -556,7 +556,50 @@ 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();
}
public void BringSelectionToFront()
{
if (getTarget(selectedTarget.Value) is not SkinComponentsContainer target)
return;
changeHandler?.BeginChange();
// 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);
}
changeHandler?.EndChange();
}
public void SendSelectionToBack()
{
if (getTarget(selectedTarget.Value) is not SkinComponentsContainer target)
return;
changeHandler?.BeginChange();
foreach (var d in target.Components.ToArray())
{
if (SelectedComponents.Contains(d))
continue;
target.Remove(d, false);
target.Add(d);
}
changeHandler?.EndChange(); changeHandler?.EndChange();
} }

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);
} }

View File

@ -35,8 +35,8 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Realm" Version="10.20.0" /> <PackageReference Include="Realm" Version="10.20.0" />
<PackageReference Include="ppy.osu.Framework" Version="2023.131.0" /> <PackageReference Include="ppy.osu.Framework" Version="2023.228.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2023.202.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2023.228.0" />
<PackageReference Include="Sentry" Version="3.28.1" /> <PackageReference Include="Sentry" Version="3.28.1" />
<PackageReference Include="SharpCompress" Version="0.32.2" /> <PackageReference Include="SharpCompress" Version="0.32.2" />
<PackageReference Include="NUnit" Version="3.13.3" /> <PackageReference Include="NUnit" Version="3.13.3" />

View File

@ -16,6 +16,6 @@
<RuntimeIdentifier>iossimulator-x64</RuntimeIdentifier> <RuntimeIdentifier>iossimulator-x64</RuntimeIdentifier>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ppy.osu.Framework.iOS" Version="2023.131.0" /> <PackageReference Include="ppy.osu.Framework.iOS" Version="2023.228.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>