mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 16:12:57 +08:00
Merge branch 'master' into fix-unsafe-skinnable-sample-play
This commit is contained in:
commit
f59327cc3e
@ -7,11 +7,13 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osuTK;
|
||||
@ -23,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
||||
/// <summary>
|
||||
/// A visualisation of a single <see cref="PathControlPoint"/> in a <see cref="Slider"/>.
|
||||
/// </summary>
|
||||
public class PathControlPointPiece : BlueprintPiece<Slider>
|
||||
public class PathControlPointPiece : BlueprintPiece<Slider>, IHasTooltip
|
||||
{
|
||||
public Action<PathControlPointPiece, MouseButtonEvent> RequestSelection;
|
||||
|
||||
@ -195,7 +197,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
||||
|
||||
markerRing.Alpha = IsSelected.Value ? 1 : 0;
|
||||
|
||||
Color4 colour = ControlPoint.Type.Value != null ? colours.Red : colours.Yellow;
|
||||
Color4 colour = getColourFromNodeType();
|
||||
|
||||
if (IsHovered || IsSelected.Value)
|
||||
colour = colour.Lighten(1);
|
||||
@ -203,5 +205,28 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
||||
marker.Colour = colour;
|
||||
marker.Scale = new Vector2(slider.Scale);
|
||||
}
|
||||
|
||||
private Color4 getColourFromNodeType()
|
||||
{
|
||||
if (!(ControlPoint.Type.Value is PathType pathType))
|
||||
return colours.Yellow;
|
||||
|
||||
switch (pathType)
|
||||
{
|
||||
case PathType.Catmull:
|
||||
return colours.Seafoam;
|
||||
|
||||
case PathType.Bezier:
|
||||
return colours.Pink;
|
||||
|
||||
case PathType.PerfectCurve:
|
||||
return colours.PurpleDark;
|
||||
|
||||
default:
|
||||
return colours.Red;
|
||||
}
|
||||
}
|
||||
|
||||
public string TooltipText => ControlPoint.Type.Value.ToString() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
81
osu.Game.Tests/Visual/Editing/TestSceneEditorClock.cs
Normal file
81
osu.Game.Tests/Visual/Editing/TestSceneEditorClock.cs
Normal file
@ -0,0 +1,81 @@
|
||||
// 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.
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.Edit.Components;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneEditorClock : EditorClockTestScene
|
||||
{
|
||||
public TestSceneEditorClock()
|
||||
{
|
||||
Add(new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TimeInfoContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(200, 100)
|
||||
},
|
||||
new PlaybackControl
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(200, 100)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
||||
// ensure that music controller does not change this beatmap due to it
|
||||
// completing naturally as part of the test.
|
||||
Beatmap.Disabled = true;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestStopAtTrackEnd()
|
||||
{
|
||||
AddStep("reset clock", () => Clock.Seek(0));
|
||||
|
||||
AddStep("start clock", Clock.Start);
|
||||
AddAssert("clock running", () => Clock.IsRunning);
|
||||
|
||||
AddStep("seek near end", () => Clock.Seek(Clock.TrackLength - 250));
|
||||
AddUntilStep("clock stops", () => !Clock.IsRunning);
|
||||
|
||||
AddAssert("clock stopped at end", () => Clock.CurrentTime == Clock.TrackLength);
|
||||
|
||||
AddStep("start clock again", Clock.Start);
|
||||
AddAssert("clock looped to start", () => Clock.IsRunning && Clock.CurrentTime < 500);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestWrapWhenStoppedAtTrackEnd()
|
||||
{
|
||||
AddStep("reset clock", () => Clock.Seek(0));
|
||||
|
||||
AddStep("stop clock", Clock.Stop);
|
||||
AddAssert("clock stopped", () => !Clock.IsRunning);
|
||||
|
||||
AddStep("seek exactly to end", () => Clock.Seek(Clock.TrackLength));
|
||||
AddAssert("clock stopped at end", () => Clock.CurrentTime == Clock.TrackLength);
|
||||
|
||||
AddStep("start clock again", Clock.Start);
|
||||
AddAssert("clock looped to start", () => Clock.IsRunning && Clock.CurrentTime < 500);
|
||||
}
|
||||
}
|
||||
}
|
@ -110,8 +110,6 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
[Resolved]
|
||||
private EditorClock editorClock { get; set; }
|
||||
|
||||
private bool started;
|
||||
|
||||
public StartStopButton()
|
||||
{
|
||||
BackgroundColour = Color4.SlateGray;
|
||||
@ -123,18 +121,17 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
|
||||
private void onClick()
|
||||
{
|
||||
if (started)
|
||||
{
|
||||
if (editorClock.IsRunning)
|
||||
editorClock.Stop();
|
||||
Text = "Start";
|
||||
}
|
||||
else
|
||||
{
|
||||
editorClock.Start();
|
||||
Text = "Stop";
|
||||
}
|
||||
}
|
||||
|
||||
started = !started;
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
Text = editorClock.IsRunning ? "Stop" : "Start";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ namespace osu.Game.Beatmaps.ControlPoints
|
||||
/// </summary>
|
||||
public readonly BindableDouble SpeedMultiplierBindable = new BindableDouble(1)
|
||||
{
|
||||
Precision = 0.1,
|
||||
Precision = 0.01,
|
||||
Default = 1,
|
||||
MinValue = 0.1,
|
||||
MaxValue = 10
|
||||
|
@ -177,7 +177,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
if (!track.IsLoaded)
|
||||
return;
|
||||
|
||||
editorClock.Seek(Current / Content.DrawWidth * track.Length);
|
||||
double target = Current / Content.DrawWidth * track.Length;
|
||||
editorClock.Seek(Math.Min(track.Length, target));
|
||||
}
|
||||
|
||||
private void scrollToTrackTime()
|
||||
|
@ -31,6 +31,8 @@ namespace osu.Game.Screens.Edit
|
||||
|
||||
private readonly DecoupleableInterpolatingFramedClock underlyingClock;
|
||||
|
||||
private bool playbackFinished;
|
||||
|
||||
public IBindable<bool> SeekingOrStopped => seekingOrStopped;
|
||||
|
||||
private readonly Bindable<bool> seekingOrStopped = new Bindable<bool>(true);
|
||||
@ -170,6 +172,10 @@ namespace osu.Game.Screens.Edit
|
||||
public void Start()
|
||||
{
|
||||
ClearTransforms();
|
||||
|
||||
if (playbackFinished)
|
||||
underlyingClock.Seek(0);
|
||||
|
||||
underlyingClock.Start();
|
||||
}
|
||||
|
||||
@ -216,7 +222,21 @@ namespace osu.Game.Screens.Edit
|
||||
|
||||
public bool IsRunning => underlyingClock.IsRunning;
|
||||
|
||||
public void ProcessFrame() => underlyingClock.ProcessFrame();
|
||||
public void ProcessFrame()
|
||||
{
|
||||
underlyingClock.ProcessFrame();
|
||||
|
||||
playbackFinished = CurrentTime >= TrackLength;
|
||||
|
||||
if (playbackFinished)
|
||||
{
|
||||
if (IsRunning)
|
||||
underlyingClock.Stop();
|
||||
|
||||
if (CurrentTime > TrackLength)
|
||||
underlyingClock.Seek(TrackLength);
|
||||
}
|
||||
}
|
||||
|
||||
public double ElapsedFrameTime => underlyingClock.ElapsedFrameTime;
|
||||
|
||||
|
@ -18,7 +18,8 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
{
|
||||
multiplierSlider = new SliderWithTextBoxInput<double>("Speed Multiplier")
|
||||
{
|
||||
Current = new DifficultyControlPoint().SpeedMultiplierBindable
|
||||
Current = new DifficultyControlPoint().SpeedMultiplierBindable,
|
||||
KeyboardStep = 0.1f
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -69,6 +69,15 @@ namespace osu.Game.Screens.Edit.Timing
|
||||
}, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A custom step value for each key press which actuates a change on this control.
|
||||
/// </summary>
|
||||
public float KeyboardStep
|
||||
{
|
||||
get => slider.KeyboardStep;
|
||||
set => slider.KeyboardStep = value;
|
||||
}
|
||||
|
||||
public Bindable<T> Current
|
||||
{
|
||||
get => slider.Current;
|
||||
|
@ -86,7 +86,7 @@ namespace osu.Game.Skinning
|
||||
public void SelectRandomSkin()
|
||||
{
|
||||
// choose from only user skins, removing the current selection to ensure a new one is chosen.
|
||||
var randomChoices = GetAllUsableSkins().Where(s => s.ID > 0 && s.ID != CurrentSkinInfo.Value.ID).ToArray();
|
||||
var randomChoices = GetAllUsableSkins().Where(s => s.ID != CurrentSkinInfo.Value.ID).ToArray();
|
||||
|
||||
if (randomChoices.Length == 0)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user