1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 03:22:55 +08:00

Disable toolbox composition buttons when beatmap is not timed

This commit is contained in:
Dean Herbert 2021-07-17 02:30:13 +09:00
parent 3ae5f6707a
commit eac9b1ec7e
3 changed files with 103 additions and 32 deletions

View File

@ -2,17 +2,24 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Timing;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Edit;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Components.RadioButtons;
using osu.Game.Screens.Edit.Compose.Components;
using osuTK;
namespace osu.Game.Tests.Visual.Editing
@ -20,8 +27,15 @@ namespace osu.Game.Tests.Visual.Editing
[TestFixture]
public class TestSceneHitObjectComposer : EditorClockTestScene
{
[BackgroundDependencyLoader]
private void load()
private OsuHitObjectComposer hitObjectComposer;
private EditorBeatmapContainer editorBeatmapContainer;
private EditorBeatmap editorBeatmap => editorBeatmapContainer.EditorBeatmap;
[SetUpSteps]
public void SetUpSteps()
{
AddStep("create beatmap", () =>
{
Beatmap.Value = CreateWorkingBeatmap(new Beatmap
{
@ -41,16 +55,61 @@ namespace osu.Game.Tests.Visual.Editing
}
},
});
});
var editorBeatmap = new EditorBeatmap(Beatmap.Value.GetPlayableBeatmap(new OsuRuleset().RulesetInfo));
AddStep("Create composer", () =>
{
Child = editorBeatmapContainer = new EditorBeatmapContainer(Beatmap.Value)
{
Child = hitObjectComposer = new OsuHitObjectComposer(new OsuRuleset())
};
});
}
var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
Dependencies.CacheAs<IAdjustableClock>(clock);
Dependencies.CacheAs<IFrameBasedClock>(clock);
Dependencies.CacheAs(editorBeatmap);
Dependencies.CacheAs<IBeatSnapProvider>(editorBeatmap);
[Test]
public void TestPlacementOnlyWorksWithTiming()
{
AddStep("clear all control points", () => editorBeatmap.ControlPointInfo.Clear());
Child = new OsuHitObjectComposer(new OsuRuleset());
AddAssert("Tool is selection", () => hitObjectComposer.ChildrenOfType<ComposeBlueprintContainer>().First().CurrentTool is SelectTool);
AddAssert("Hitcircle button not clickable", () => !hitObjectComposer.ChildrenOfType<DrawableRadioButton>().First(d => d.Button.Item == "HitCircle").Enabled.Value);
AddStep("Add timing point", () => editorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint()));
AddAssert("Hitcircle button is clickable", () => hitObjectComposer.ChildrenOfType<DrawableRadioButton>().First(d => d.Button.Item == "HitCircle").Enabled.Value);
AddStep("Change to hitcircle", () => hitObjectComposer.ChildrenOfType<DrawableRadioButton>().First(d => d.Button.Item == "HitCircle").Click());
AddAssert("Tool changed", () => hitObjectComposer.ChildrenOfType<ComposeBlueprintContainer>().First().CurrentTool is HitCircleCompositionTool);
}
public class EditorBeatmapContainer : Container
{
private readonly WorkingBeatmap working;
public EditorBeatmap EditorBeatmap { get; private set; }
public EditorBeatmapContainer(WorkingBeatmap working)
{
this.working = working;
RelativeSizeAxes = Axes.Both;
}
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
EditorBeatmap = new EditorBeatmap(working.GetPlayableBeatmap(new OsuRuleset().RulesetInfo));
dependencies.CacheAs(EditorBeatmap);
dependencies.CacheAs<IBeatSnapProvider>(EditorBeatmap);
return dependencies;
}
protected override void LoadComplete()
{
base.LoadComplete();
Add(EditorBeatmap);
}
}
}
}

View File

@ -219,6 +219,7 @@ namespace osu.Game.Rulesets.Edit
if (item != null)
{
if (!item.Selected.Disabled)
item.Select();
return true;
}

View File

@ -5,9 +5,11 @@ using System;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
@ -16,24 +18,28 @@ using osuTK.Graphics;
namespace osu.Game.Screens.Edit.Components.RadioButtons
{
public class DrawableRadioButton : OsuButton
public class DrawableRadioButton : OsuButton, IHasTooltip
{
/// <summary>
/// Invoked when this <see cref="DrawableRadioButton"/> has been selected.
/// </summary>
public Action<RadioButton> Selected;
public readonly RadioButton Button;
private Color4 defaultBackgroundColour;
private Color4 defaultBubbleColour;
private Color4 selectedBackgroundColour;
private Color4 selectedBubbleColour;
private Drawable icon;
private readonly RadioButton button;
[Resolved(canBeNull: true)]
private EditorBeatmap editorBeatmap { get; set; }
public DrawableRadioButton(RadioButton button)
{
this.button = button;
this.Button = button;
Text = button.Item.ToString();
Action = button.Select;
@ -57,7 +63,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
Colour = Color4.Black.Opacity(0.5f)
};
Add(icon = (button.CreateIcon?.Invoke() ?? new Circle()).With(b =>
Add(icon = (Button.CreateIcon?.Invoke() ?? new Circle()).With(b =>
{
b.Blending = BlendingParameters.Additive;
b.Anchor = Anchor.CentreLeft;
@ -71,13 +77,16 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
{
base.LoadComplete();
button.Selected.ValueChanged += selected =>
Button.Selected.ValueChanged += selected =>
{
updateSelectionState();
if (selected.NewValue)
Selected?.Invoke(button);
Selected?.Invoke(Button);
};
editorBeatmap?.HasTiming.BindValueChanged(hasTiming => Button.Selected.Disabled = !hasTiming.NewValue, true);
Button.Selected.BindDisabledChanged(disabled => Enabled.Value = !disabled, true);
updateSelectionState();
}
@ -86,8 +95,8 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
if (!IsLoaded)
return;
BackgroundColour = button.Selected.Value ? selectedBackgroundColour : defaultBackgroundColour;
icon.Colour = button.Selected.Value ? selectedBubbleColour : defaultBubbleColour;
BackgroundColour = Button.Selected.Value ? selectedBackgroundColour : defaultBackgroundColour;
icon.Colour = Button.Selected.Value ? selectedBubbleColour : defaultBubbleColour;
}
protected override SpriteText CreateText() => new OsuSpriteText
@ -97,5 +106,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
Anchor = Anchor.CentreLeft,
X = 40f
};
public LocalisableString TooltipText => Enabled.Value ? string.Empty : "Add at least one timing point first!";
}
}