diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs index 14853c6ba4..07b6a1bdc2 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs @@ -8,12 +8,14 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Input; using osu.Framework.Input.Events; +using osu.Game.Beatmaps.ControlPoints; 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.Edit.Blueprints.HitCircles.Components; using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components; +using osu.Game.Screens.Edit; using osuTK; using osuTK.Input; @@ -67,6 +69,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders inputManager = GetContainingInputManager(); } + [Resolved] + private EditorBeatmap editorBeatmap { get; set; } + public override void UpdateTimeAndPosition(SnapResult result) { base.UpdateTimeAndPosition(result); @@ -75,6 +80,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders { case SliderPlacementState.Initial: BeginPlacement(); + + var nearestDifficultyPoint = editorBeatmap.HitObjects.LastOrDefault(h => h.GetEndTime() < HitObject.StartTime)?.DifficultyControlPoint?.DeepClone() as DifficultyControlPoint; + + HitObject.DifficultyControlPoint = nearestDifficultyPoint ?? new DifficultyControlPoint(); HitObject.Position = ToLocalSpace(result.ScreenSpacePosition); break; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs index cd1ef9127e..21457ea273 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs @@ -1,27 +1,106 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Rulesets.Objects; +using osu.Game.Screens.Edit.Timing; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class DifficultyPointPiece : TopPointPiece + public class DifficultyPointPiece : HitObjectPointPiece, IHasPopover { + private readonly HitObject hitObject; + private readonly BindableNumber speedMultiplier; - public DifficultyPointPiece(DifficultyControlPoint point) - : base(point) + public DifficultyPointPiece(HitObject hitObject) + : base(hitObject.DifficultyControlPoint) { - speedMultiplier = point.SliderVelocityBindable.GetBoundCopy(); + this.hitObject = hitObject; - Y = Height; + speedMultiplier = hitObject.DifficultyControlPoint.SliderVelocityBindable.GetBoundCopy(); } protected override void LoadComplete() { base.LoadComplete(); + speedMultiplier.BindValueChanged(multiplier => Label.Text = $"{multiplier.NewValue:n2}x", true); } + + protected override bool OnClick(ClickEvent e) + { + this.ShowPopover(); + return true; + } + + public Popover GetPopover() => new DifficultyEditPopover(hitObject); + + public class DifficultyEditPopover : OsuPopover + { + private readonly HitObject hitObject; + private readonly DifficultyControlPoint point; + + private SliderWithTextBoxInput sliderVelocitySlider; + + [Resolved(canBeNull: true)] + private EditorBeatmap beatmap { get; set; } + + public DifficultyEditPopover(HitObject hitObject) + { + this.hitObject = hitObject; + point = hitObject.DifficultyControlPoint; + } + + [BackgroundDependencyLoader] + private void load() + { + Children = new Drawable[] + { + new FillFlowContainer + { + Width = 200, + Direction = FillDirection.Vertical, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + sliderVelocitySlider = new SliderWithTextBoxInput("Velocity") + { + Current = new DifficultyControlPoint().SliderVelocityBindable, + KeyboardStep = 0.1f + }, + new OsuTextFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Text = "Hold shift while dragging the end of an object to adjust velocity while snapping." + } + } + } + }; + + var selectedPointBindable = point.SliderVelocityBindable; + + // there may be legacy control points, which contain infinite precision for compatibility reasons (see LegacyDifficultyControlPoint). + // generally that level of precision could only be set by externally editing the .osu file, so at the point + // a user is looking to update this within the editor it should be safe to obliterate this additional precision. + double expectedPrecision = new DifficultyControlPoint().SliderVelocityBindable.Precision; + if (selectedPointBindable.Precision < expectedPrecision) + selectedPointBindable.Precision = expectedPrecision; + + sliderVelocitySlider.Current = selectedPointBindable; + sliderVelocitySlider.Current.BindValueChanged(_ => beatmap?.Update(hitObject)); + } + } } } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs new file mode 100644 index 0000000000..6b62459c97 --- /dev/null +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs @@ -0,0 +1,63 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osuTK.Graphics; + +namespace osu.Game.Screens.Edit.Compose.Components.Timeline +{ + public class HitObjectPointPiece : CircularContainer + { + private readonly ControlPoint point; + + protected OsuSpriteText Label { get; private set; } + + protected HitObjectPointPiece(ControlPoint point) + { + this.point = point; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AutoSizeAxes = Axes.Both; + + Color4 colour = point.GetRepresentingColour(colours); + + InternalChildren = new Drawable[] + { + new Container + { + AutoSizeAxes = Axes.X, + Height = 16, + Masking = true, + CornerRadius = 8, + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Children = new Drawable[] + { + new Box + { + Colour = colour, + RelativeSizeAxes = Axes.Both, + }, + Label = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Padding = new MarginPadding(5), + Font = OsuFont.Default.With(size: 12, weight: FontWeight.SemiBold), + Colour = colours.B5, + } + } + }, + }; + } + } +} diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs index 9461f5e885..6a26f69e41 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs @@ -3,88 +3,102 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osuTK.Graphics; +using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Rulesets.Objects; +using osu.Game.Screens.Edit.Timing; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class SamplePointPiece : CompositeDrawable + public class SamplePointPiece : HitObjectPointPiece, IHasPopover { - private readonly SampleControlPoint samplePoint; + private readonly HitObject hitObject; private readonly Bindable bank; private readonly BindableNumber volume; - private OsuSpriteText text; - private Container volumeBox; - - private const int max_volume_height = 22; - - public SamplePointPiece(SampleControlPoint samplePoint) + public SamplePointPiece(HitObject hitObject) + : base(hitObject.SampleControlPoint) { - this.samplePoint = samplePoint; - volume = samplePoint.SampleVolumeBindable.GetBoundCopy(); - bank = samplePoint.SampleBankBindable.GetBoundCopy(); + this.hitObject = hitObject; + volume = hitObject.SampleControlPoint.SampleVolumeBindable.GetBoundCopy(); + bank = hitObject.SampleControlPoint.SampleBankBindable.GetBoundCopy(); } [BackgroundDependencyLoader] private void load(OsuColour colours) { - Margin = new MarginPadding { Vertical = 5 }; + volume.BindValueChanged(volume => updateText()); + bank.BindValueChanged(bank => updateText(), true); + } - Origin = Anchor.BottomCentre; - Anchor = Anchor.BottomCentre; + protected override bool OnClick(ClickEvent e) + { + this.ShowPopover(); + return true; + } - AutoSizeAxes = Axes.X; - RelativeSizeAxes = Axes.Y; + private void updateText() + { + Label.Text = $"{bank.Value} {volume.Value}"; + } - Color4 colour = samplePoint.GetRepresentingColour(colours); + public Popover GetPopover() => new SampleEditPopover(hitObject); - InternalChildren = new Drawable[] + public class SampleEditPopover : OsuPopover + { + private readonly HitObject hitObject; + private readonly SampleControlPoint point; + + private LabelledTextBox bank; + private SliderWithTextBoxInput volume; + + [Resolved(canBeNull: true)] + private EditorBeatmap beatmap { get; set; } + + public SampleEditPopover(HitObject hitObject) { - volumeBox = new Circle + this.hitObject = hitObject; + point = hitObject.SampleControlPoint; + } + + [BackgroundDependencyLoader] + private void load() + { + Children = new Drawable[] { - CornerRadius = 5, - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Y = -20, - Width = 10, - Colour = colour, - }, - new Container - { - AutoSizeAxes = Axes.X, - Height = 16, - Masking = true, - CornerRadius = 8, - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Children = new Drawable[] + new FillFlowContainer { - new Box + Width = 200, + Direction = FillDirection.Vertical, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] { - Colour = colour, - RelativeSizeAxes = Axes.Both, - }, - text = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Padding = new MarginPadding(5), - Font = OsuFont.Default.With(size: 12, weight: FontWeight.SemiBold), - Colour = colours.B5, + bank = new LabelledTextBox + { + Label = "Bank Name", + }, + volume = new SliderWithTextBoxInput("Volume") + { + Current = new SampleControlPoint().SampleVolumeBindable, + } } } - }, - }; + }; - volume.BindValueChanged(volume => volumeBox.Height = max_volume_height * volume.NewValue / 100f, true); - bank.BindValueChanged(bank => text.Text = bank.NewValue, true); + bank.Current = point.SampleBankBindable; + bank.Current.BindValueChanged(_ => beatmap.Update(hitObject)); + + volume.Current = point.SampleVolumeBindable; + volume.Current.BindValueChanged(_ => beatmap.Update(hitObject)); + } } } } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 4296581480..b8fa05e7eb 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private Track track; private const float timeline_height = 72; - private const float timeline_expanded_height = 156; + private const float timeline_expanded_height = 94; public Timeline(Drawable userContent) { @@ -159,7 +159,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline if (visible.NewValue) { this.ResizeHeightTo(timeline_expanded_height, 200, Easing.OutQuint); - mainContent.MoveToY(36, 200, Easing.OutQuint); + mainContent.MoveToY(20, 200, Easing.OutQuint); // delay the fade in else masking looks weird. controlPoints.Delay(180).FadeIn(400, Easing.OutQuint); diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineControlPointGroup.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineControlPointGroup.cs index c4beb40f92..2b2e66fb18 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineControlPointGroup.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineControlPointGroup.cs @@ -45,17 +45,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { switch (point) { - case DifficultyControlPoint difficultyPoint: - AddInternal(new DifficultyPointPiece(difficultyPoint) { Depth = -2 }); - break; - case TimingControlPoint timingPoint: AddInternal(new TimingPointPiece(timingPoint)); break; - - case SampleControlPoint samplePoint: - AddInternal(new SamplePointPiece(samplePoint) { Depth = -1 }); - break; } } }, true); diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 911c9fea51..e2458d45c9 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -13,7 +13,9 @@ using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; +using osu.Framework.Threading; using osu.Framework.Utils; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Edit; @@ -179,6 +181,15 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline colouredComponents.Colour = OsuColour.ForegroundTextColourFor(col); } + private SamplePointPiece sampleOverrideDisplay; + private DifficultyPointPiece difficultyOverrideDisplay; + + [Resolved] + private EditorBeatmap beatmap { get; set; } + + private DifficultyControlPoint difficultyControlPoint; + private SampleControlPoint sampleControlPoint; + protected override void Update() { base.Update(); @@ -194,6 +205,36 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline if (Item is IHasRepeats repeats) updateRepeats(repeats); } + + if (difficultyControlPoint != Item.DifficultyControlPoint) + { + difficultyControlPoint = Item.DifficultyControlPoint; + difficultyOverrideDisplay?.Expire(); + + if (Item.DifficultyControlPoint != null && Item is IHasDistance) + { + AddInternal(difficultyOverrideDisplay = new DifficultyPointPiece(Item) + { + Anchor = Anchor.TopLeft, + Origin = Anchor.BottomCentre + }); + } + } + + if (sampleControlPoint != Item.SampleControlPoint) + { + sampleControlPoint = Item.SampleControlPoint; + sampleOverrideDisplay?.Expire(); + + if (Item.SampleControlPoint != null) + { + AddInternal(sampleOverrideDisplay = new SamplePointPiece(Item) + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.TopCentre + }); + } + } } private void updateRepeats(IHasRepeats repeats) @@ -331,39 +372,66 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline return true; } + private ScheduledDelegate dragOperation; + protected override void OnDrag(DragEvent e) { base.OnDrag(e); - OnDragHandled?.Invoke(e); - - if (timeline.SnapScreenSpacePositionToValidTime(e.ScreenSpaceMousePosition).Time is double time) + // schedule is temporary to ensure we don't process multiple times on a single update frame. we need to find a better method of doing this. + // without it, a hitobject's endtime may not always be in a valid state (ie. sliders, which needs to recompute their path). + dragOperation?.Cancel(); + dragOperation = Scheduler.Add(() => { - switch (hitObject) + OnDragHandled?.Invoke(e); + + if (timeline.SnapScreenSpacePositionToValidTime(e.ScreenSpaceMousePosition).Time is double time) { - case IHasRepeats repeatHitObject: - // find the number of repeats which can fit in the requested time. - var lengthOfOneRepeat = repeatHitObject.Duration / (repeatHitObject.RepeatCount + 1); - var proposedCount = Math.Max(0, (int)Math.Round((time - hitObject.StartTime) / lengthOfOneRepeat) - 1); + switch (hitObject) + { + case IHasRepeats repeatHitObject: + double proposedDuration = time - hitObject.StartTime; - if (proposedCount == repeatHitObject.RepeatCount) - return; + if (e.CurrentState.Keyboard.ShiftPressed) + { + if (hitObject.DifficultyControlPoint == DifficultyControlPoint.DEFAULT) + hitObject.DifficultyControlPoint = new DifficultyControlPoint(); - repeatHitObject.RepeatCount = proposedCount; - beatmap.Update(hitObject); - break; + var newVelocity = hitObject.DifficultyControlPoint.SliderVelocity * (repeatHitObject.Duration / proposedDuration); - case IHasDuration endTimeHitObject: - var snappedTime = Math.Max(hitObject.StartTime, beatSnapProvider.SnapTime(time)); + if (Precision.AlmostEquals(newVelocity, hitObject.DifficultyControlPoint.SliderVelocity)) + return; - if (endTimeHitObject.EndTime == snappedTime || Precision.AlmostEquals(snappedTime, hitObject.StartTime, beatmap.GetBeatLengthAtTime(snappedTime))) - return; + hitObject.DifficultyControlPoint.SliderVelocity = newVelocity; + beatmap.Update(hitObject); + } + else + { + // find the number of repeats which can fit in the requested time. + var lengthOfOneRepeat = repeatHitObject.Duration / (repeatHitObject.RepeatCount + 1); + var proposedCount = Math.Max(0, (int)Math.Round(proposedDuration / lengthOfOneRepeat) - 1); - endTimeHitObject.Duration = snappedTime - hitObject.StartTime; - beatmap.Update(hitObject); - break; + if (proposedCount == repeatHitObject.RepeatCount) + return; + + repeatHitObject.RepeatCount = proposedCount; + beatmap.Update(hitObject); + } + + break; + + case IHasDuration endTimeHitObject: + var snappedTime = Math.Max(hitObject.StartTime, beatSnapProvider.SnapTime(time)); + + if (endTimeHitObject.EndTime == snappedTime || Precision.AlmostEquals(snappedTime, hitObject.StartTime, beatmap.GetBeatLengthAtTime(snappedTime))) + return; + + endTimeHitObject.Duration = snappedTime - hitObject.StartTime; + beatmap.Update(hitObject); + break; + } } - } + }); } protected override void OnDragEnd(DragEndEvent e) diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index c96c17326d..2e84ef437a 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -10,6 +10,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Beatmaps.Legacy; using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; @@ -71,6 +72,31 @@ namespace osu.Game.Screens.Edit { PlayableBeatmap = playableBeatmap; + // ensure we are not working with legacy control points. + // if we leave the legacy points around they will be applied over any local changes on + // ApplyDefaults calls. this should eventually be removed once the default logic is moved to the decoder/converter. + if (PlayableBeatmap.ControlPointInfo is LegacyControlPointInfo) + { + var newControlPoints = new ControlPointInfo(); + + foreach (var controlPoint in PlayableBeatmap.ControlPointInfo.AllControlPoints) + { + switch (controlPoint) + { + case DifficultyControlPoint _: + case SampleControlPoint _: + // skip legacy types. + continue; + + default: + newControlPoints.Add(controlPoint.Time, controlPoint); + break; + } + } + + playableBeatmap.ControlPointInfo = newControlPoints; + } + this.beatmapInfo = beatmapInfo ?? playableBeatmap.BeatmapInfo; if (beatmapSkin is Skin skin) diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index ba83261731..86e5729196 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -25,7 +25,9 @@ namespace osu.Game.Screens.Edit public double TrackLength => track.Value?.Length ?? 60000; - public ControlPointInfo ControlPointInfo; + public ControlPointInfo ControlPointInfo => Beatmap.ControlPointInfo; + + public IBeatmap Beatmap { get; set; } private readonly BindableBeatDivisor beatDivisor; @@ -42,25 +44,15 @@ namespace osu.Game.Screens.Edit /// public bool IsSeeking { get; private set; } - public EditorClock(IBeatmap beatmap, BindableBeatDivisor beatDivisor) - : this(beatmap.ControlPointInfo, beatDivisor) + public EditorClock(IBeatmap beatmap = null, BindableBeatDivisor beatDivisor = null) { - } + Beatmap = beatmap ?? new Beatmap(); - public EditorClock(ControlPointInfo controlPointInfo, BindableBeatDivisor beatDivisor) - { - this.beatDivisor = beatDivisor; - - ControlPointInfo = controlPointInfo; + this.beatDivisor = beatDivisor ?? new BindableBeatDivisor(); underlyingClock = new DecoupleableInterpolatingFramedClock(); } - public EditorClock() - : this(new ControlPointInfo(), new BindableBeatDivisor()) - { - } - /// /// Seek to the closest snappable beat from a time. /// diff --git a/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs b/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs index 48639789af..938c7f9cf0 100644 --- a/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs +++ b/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs @@ -12,8 +12,6 @@ namespace osu.Game.Screens.Edit.Timing { new GroupSection(), new TimingSection(), - new DifficultySection(), - new SampleSection(), new EffectSection(), }; } diff --git a/osu.Game/Screens/Edit/Timing/DifficultySection.cs b/osu.Game/Screens/Edit/Timing/DifficultySection.cs deleted file mode 100644 index 52d38f19f6..0000000000 --- a/osu.Game/Screens/Edit/Timing/DifficultySection.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Beatmaps.Legacy; - -namespace osu.Game.Screens.Edit.Timing -{ - internal class DifficultySection : Section - { - private SliderWithTextBoxInput sliderVelocitySlider; - - [BackgroundDependencyLoader] - private void load() - { - Flow.AddRange(new[] - { - sliderVelocitySlider = new SliderWithTextBoxInput("Slider Velocity") - { - Current = new DifficultyControlPoint().SliderVelocityBindable, - KeyboardStep = 0.1f - } - }); - } - - protected override void OnControlPointChanged(ValueChangedEvent point) - { - if (point.NewValue != null) - { - var selectedPointBindable = point.NewValue.SliderVelocityBindable; - - // there may be legacy control points, which contain infinite precision for compatibility reasons (see LegacyDifficultyControlPoint). - // generally that level of precision could only be set by externally editing the .osu file, so at the point - // a user is looking to update this within the editor it should be safe to obliterate this additional precision. - double expectedPrecision = new DifficultyControlPoint().SliderVelocityBindable.Precision; - if (selectedPointBindable.Precision < expectedPrecision) - selectedPointBindable.Precision = expectedPrecision; - - sliderVelocitySlider.Current = selectedPointBindable; - sliderVelocitySlider.Current.BindValueChanged(_ => ChangeHandler?.SaveState()); - } - } - - protected override DifficultyControlPoint CreatePoint() - { - var reference = (Beatmap.ControlPointInfo as LegacyControlPointInfo)?.DifficultyPointAt(SelectedGroup.Value.Time) ?? DifficultyControlPoint.DEFAULT; - - return new DifficultyControlPoint - { - SliderVelocity = reference.SliderVelocity, - }; - } - } -} diff --git a/osu.Game/Screens/Edit/Timing/SampleSection.cs b/osu.Game/Screens/Edit/Timing/SampleSection.cs deleted file mode 100644 index 96a67ab046..0000000000 --- a/osu.Game/Screens/Edit/Timing/SampleSection.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Beatmaps.Legacy; -using osu.Game.Graphics.UserInterfaceV2; - -namespace osu.Game.Screens.Edit.Timing -{ - internal class SampleSection : Section - { - private LabelledTextBox bank; - private SliderWithTextBoxInput volume; - - [BackgroundDependencyLoader] - private void load() - { - Flow.AddRange(new Drawable[] - { - bank = new LabelledTextBox - { - Label = "Bank Name", - }, - volume = new SliderWithTextBoxInput("Volume") - { - Current = new SampleControlPoint().SampleVolumeBindable, - } - }); - } - - protected override void OnControlPointChanged(ValueChangedEvent point) - { - if (point.NewValue != null) - { - bank.Current = point.NewValue.SampleBankBindable; - bank.Current.BindValueChanged(_ => ChangeHandler?.SaveState()); - - volume.Current = point.NewValue.SampleVolumeBindable; - volume.Current.BindValueChanged(_ => ChangeHandler?.SaveState()); - } - } - - protected override SampleControlPoint CreatePoint() - { - var reference = (Beatmap.ControlPointInfo as LegacyControlPointInfo)?.SamplePointAt(SelectedGroup.Value.Time) ?? SampleControlPoint.DEFAULT; - - return new SampleControlPoint - { - SampleBank = reference.SampleBank, - SampleVolume = reference.SampleVolume, - }; - } - } -} diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 34393fba7d..c2e9892735 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Input.Events; using osu.Game.Beatmaps; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Screens.Edit; namespace osu.Game.Tests.Visual @@ -23,7 +22,7 @@ namespace osu.Game.Tests.Visual protected EditorClockTestScene() { - Clock = new EditorClock(new ControlPointInfo(), BeatDivisor) { IsCoupled = false }; + Clock = new EditorClock(new Beatmap(), BeatDivisor) { IsCoupled = false }; } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) @@ -44,7 +43,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { - Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; + Clock.Beatmap = e.NewValue.Beatmap; Clock.ChangeSource(e.NewValue.Track); Clock.ProcessFrame(); }