mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 04:05:35 +08:00
Disable toolbox composition buttons when beatmap is not timed
This commit is contained in:
parent
3ae5f6707a
commit
eac9b1ec7e
@ -2,17 +2,24 @@
|
|||||||
// 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.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
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;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Osu.Edit;
|
using osu.Game.Rulesets.Osu.Edit;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
|
using osu.Game.Screens.Edit.Components.RadioButtons;
|
||||||
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Editing
|
namespace osu.Game.Tests.Visual.Editing
|
||||||
@ -20,37 +27,89 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneHitObjectComposer : EditorClockTestScene
|
public class TestSceneHitObjectComposer : EditorClockTestScene
|
||||||
{
|
{
|
||||||
[BackgroundDependencyLoader]
|
private OsuHitObjectComposer hitObjectComposer;
|
||||||
private void load()
|
private EditorBeatmapContainer editorBeatmapContainer;
|
||||||
|
|
||||||
|
private EditorBeatmap editorBeatmap => editorBeatmapContainer.EditorBeatmap;
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public void SetUpSteps()
|
||||||
{
|
{
|
||||||
Beatmap.Value = CreateWorkingBeatmap(new Beatmap
|
AddStep("create beatmap", () =>
|
||||||
{
|
{
|
||||||
HitObjects = new List<HitObject>
|
Beatmap.Value = CreateWorkingBeatmap(new Beatmap
|
||||||
{
|
{
|
||||||
new HitCircle { Position = new Vector2(256, 192), Scale = 0.5f },
|
HitObjects = new List<HitObject>
|
||||||
new HitCircle { Position = new Vector2(344, 148), Scale = 0.5f },
|
|
||||||
new Slider
|
|
||||||
{
|
{
|
||||||
Position = new Vector2(128, 256),
|
new HitCircle { Position = new Vector2(256, 192), Scale = 0.5f },
|
||||||
Path = new SliderPath(PathType.Linear, new[]
|
new HitCircle { Position = new Vector2(344, 148), Scale = 0.5f },
|
||||||
|
new Slider
|
||||||
{
|
{
|
||||||
Vector2.Zero,
|
Position = new Vector2(128, 256),
|
||||||
new Vector2(216, 0),
|
Path = new SliderPath(PathType.Linear, new[]
|
||||||
}),
|
{
|
||||||
Scale = 0.5f,
|
Vector2.Zero,
|
||||||
}
|
new Vector2(216, 0),
|
||||||
},
|
}),
|
||||||
|
Scale = 0.5f,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
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 };
|
[Test]
|
||||||
Dependencies.CacheAs<IAdjustableClock>(clock);
|
public void TestPlacementOnlyWorksWithTiming()
|
||||||
Dependencies.CacheAs<IFrameBasedClock>(clock);
|
{
|
||||||
Dependencies.CacheAs(editorBeatmap);
|
AddStep("clear all control points", () => editorBeatmap.ControlPointInfo.Clear());
|
||||||
Dependencies.CacheAs<IBeatSnapProvider>(editorBeatmap);
|
|
||||||
|
|
||||||
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,8 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
|
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
item.Select();
|
if (!item.Selected.Disabled)
|
||||||
|
item.Select();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,11 @@ using System;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Cursor;
|
||||||
using osu.Framework.Graphics.Effects;
|
using osu.Framework.Graphics.Effects;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
@ -16,24 +18,28 @@ using osuTK.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Components.RadioButtons
|
namespace osu.Game.Screens.Edit.Components.RadioButtons
|
||||||
{
|
{
|
||||||
public class DrawableRadioButton : OsuButton
|
public class DrawableRadioButton : OsuButton, IHasTooltip
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when this <see cref="DrawableRadioButton"/> has been selected.
|
/// Invoked when this <see cref="DrawableRadioButton"/> has been selected.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Action<RadioButton> Selected;
|
public Action<RadioButton> Selected;
|
||||||
|
|
||||||
|
public readonly RadioButton Button;
|
||||||
|
|
||||||
private Color4 defaultBackgroundColour;
|
private Color4 defaultBackgroundColour;
|
||||||
private Color4 defaultBubbleColour;
|
private Color4 defaultBubbleColour;
|
||||||
private Color4 selectedBackgroundColour;
|
private Color4 selectedBackgroundColour;
|
||||||
private Color4 selectedBubbleColour;
|
private Color4 selectedBubbleColour;
|
||||||
|
|
||||||
private Drawable icon;
|
private Drawable icon;
|
||||||
private readonly RadioButton button;
|
|
||||||
|
[Resolved(canBeNull: true)]
|
||||||
|
private EditorBeatmap editorBeatmap { get; set; }
|
||||||
|
|
||||||
public DrawableRadioButton(RadioButton button)
|
public DrawableRadioButton(RadioButton button)
|
||||||
{
|
{
|
||||||
this.button = button;
|
this.Button = button;
|
||||||
|
|
||||||
Text = button.Item.ToString();
|
Text = button.Item.ToString();
|
||||||
Action = button.Select;
|
Action = button.Select;
|
||||||
@ -57,7 +63,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
|
|||||||
Colour = Color4.Black.Opacity(0.5f)
|
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.Blending = BlendingParameters.Additive;
|
||||||
b.Anchor = Anchor.CentreLeft;
|
b.Anchor = Anchor.CentreLeft;
|
||||||
@ -71,13 +77,16 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
button.Selected.ValueChanged += selected =>
|
Button.Selected.ValueChanged += selected =>
|
||||||
{
|
{
|
||||||
updateSelectionState();
|
updateSelectionState();
|
||||||
if (selected.NewValue)
|
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();
|
updateSelectionState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,8 +95,8 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
|
|||||||
if (!IsLoaded)
|
if (!IsLoaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BackgroundColour = button.Selected.Value ? selectedBackgroundColour : defaultBackgroundColour;
|
BackgroundColour = Button.Selected.Value ? selectedBackgroundColour : defaultBackgroundColour;
|
||||||
icon.Colour = button.Selected.Value ? selectedBubbleColour : defaultBubbleColour;
|
icon.Colour = Button.Selected.Value ? selectedBubbleColour : defaultBubbleColour;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override SpriteText CreateText() => new OsuSpriteText
|
protected override SpriteText CreateText() => new OsuSpriteText
|
||||||
@ -97,5 +106,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
|
|||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
X = 40f
|
X = 40f
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public LocalisableString TooltipText => Enabled.Value ? string.Empty : "Add at least one timing point first!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user