mirror of
https://github.com/osukey/osukey.git
synced 2025-08-06 16:13:57 +09:00
Merge branch 'master' into fix-unsafe-skinnable-sample-play
This commit is contained in:
@ -7,11 +7,13 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Cursor;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -23,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A visualisation of a single <see cref="PathControlPoint"/> in a <see cref="Slider"/>.
|
/// A visualisation of a single <see cref="PathControlPoint"/> in a <see cref="Slider"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PathControlPointPiece : BlueprintPiece<Slider>
|
public class PathControlPointPiece : BlueprintPiece<Slider>, IHasTooltip
|
||||||
{
|
{
|
||||||
public Action<PathControlPointPiece, MouseButtonEvent> RequestSelection;
|
public Action<PathControlPointPiece, MouseButtonEvent> RequestSelection;
|
||||||
|
|
||||||
@ -195,7 +197,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
|
|
||||||
markerRing.Alpha = IsSelected.Value ? 1 : 0;
|
markerRing.Alpha = IsSelected.Value ? 1 : 0;
|
||||||
|
|
||||||
Color4 colour = ControlPoint.Type.Value != null ? colours.Red : colours.Yellow;
|
Color4 colour = getColourFromNodeType();
|
||||||
|
|
||||||
if (IsHovered || IsSelected.Value)
|
if (IsHovered || IsSelected.Value)
|
||||||
colour = colour.Lighten(1);
|
colour = colour.Lighten(1);
|
||||||
@ -203,5 +205,28 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
marker.Colour = colour;
|
marker.Colour = colour;
|
||||||
marker.Scale = new Vector2(slider.Scale);
|
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]
|
[Resolved]
|
||||||
private EditorClock editorClock { get; set; }
|
private EditorClock editorClock { get; set; }
|
||||||
|
|
||||||
private bool started;
|
|
||||||
|
|
||||||
public StartStopButton()
|
public StartStopButton()
|
||||||
{
|
{
|
||||||
BackgroundColour = Color4.SlateGray;
|
BackgroundColour = Color4.SlateGray;
|
||||||
@ -123,18 +121,17 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
|
|
||||||
private void onClick()
|
private void onClick()
|
||||||
{
|
{
|
||||||
if (started)
|
if (editorClock.IsRunning)
|
||||||
{
|
|
||||||
editorClock.Stop();
|
editorClock.Stop();
|
||||||
Text = "Start";
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
editorClock.Start();
|
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>
|
/// </summary>
|
||||||
public readonly BindableDouble SpeedMultiplierBindable = new BindableDouble(1)
|
public readonly BindableDouble SpeedMultiplierBindable = new BindableDouble(1)
|
||||||
{
|
{
|
||||||
Precision = 0.1,
|
Precision = 0.01,
|
||||||
Default = 1,
|
Default = 1,
|
||||||
MinValue = 0.1,
|
MinValue = 0.1,
|
||||||
MaxValue = 10
|
MaxValue = 10
|
||||||
|
@ -177,7 +177,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
if (!track.IsLoaded)
|
if (!track.IsLoaded)
|
||||||
return;
|
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()
|
private void scrollToTrackTime()
|
||||||
|
@ -31,6 +31,8 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
private readonly DecoupleableInterpolatingFramedClock underlyingClock;
|
private readonly DecoupleableInterpolatingFramedClock underlyingClock;
|
||||||
|
|
||||||
|
private bool playbackFinished;
|
||||||
|
|
||||||
public IBindable<bool> SeekingOrStopped => seekingOrStopped;
|
public IBindable<bool> SeekingOrStopped => seekingOrStopped;
|
||||||
|
|
||||||
private readonly Bindable<bool> seekingOrStopped = new Bindable<bool>(true);
|
private readonly Bindable<bool> seekingOrStopped = new Bindable<bool>(true);
|
||||||
@ -170,6 +172,10 @@ namespace osu.Game.Screens.Edit
|
|||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
ClearTransforms();
|
ClearTransforms();
|
||||||
|
|
||||||
|
if (playbackFinished)
|
||||||
|
underlyingClock.Seek(0);
|
||||||
|
|
||||||
underlyingClock.Start();
|
underlyingClock.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +222,21 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
public bool IsRunning => underlyingClock.IsRunning;
|
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;
|
public double ElapsedFrameTime => underlyingClock.ElapsedFrameTime;
|
||||||
|
|
||||||
|
@ -18,7 +18,8 @@ namespace osu.Game.Screens.Edit.Timing
|
|||||||
{
|
{
|
||||||
multiplierSlider = new SliderWithTextBoxInput<double>("Speed Multiplier")
|
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);
|
}, 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
|
public Bindable<T> Current
|
||||||
{
|
{
|
||||||
get => slider.Current;
|
get => slider.Current;
|
||||||
|
@ -86,7 +86,7 @@ namespace osu.Game.Skinning
|
|||||||
public void SelectRandomSkin()
|
public void SelectRandomSkin()
|
||||||
{
|
{
|
||||||
// choose from only user skins, removing the current selection to ensure a new one is chosen.
|
// 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)
|
if (randomChoices.Length == 0)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user