mirror of
https://github.com/ppy/osu.git
synced 2024-11-15 17:07:50 +08:00
contract sample point pieces based on smallest gap on the timeline
It finds the smallest distance between two sample point pieces on the alive timeline blueprints
This commit is contained in:
parent
9dcce67b81
commit
48da758c39
@ -42,7 +42,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
private Editor? editor { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private Timeline? timeline { get; set; }
|
||||
private TimelineBlueprintContainer? timelineBlueprintContainer { get; set; }
|
||||
|
||||
private Bindable<bool> samplesVisible = null!;
|
||||
|
||||
@ -72,9 +72,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
samplesVisible = config.GetBindable<bool>(OsuSetting.EditorTimelineShowSamples);
|
||||
}
|
||||
|
||||
private BindableNumber<float>? timelineZoom;
|
||||
|
||||
private bool contracted;
|
||||
private readonly Bindable<bool> contracted = new Bindable<bool>();
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
@ -83,21 +81,19 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
samplesVisible.BindValueChanged(visible => this.FadeTo(visible.NewValue ? 1 : 0, 200, Easing.OutQuint));
|
||||
this.FadeTo(samplesVisible.Value ? 1 : 0);
|
||||
|
||||
timelineZoom = timeline?.CurrentZoom.GetBoundCopy();
|
||||
timelineZoom?.BindValueChanged(zoom =>
|
||||
{
|
||||
const float zoom_threshold = 40f;
|
||||
if (timelineBlueprintContainer != null)
|
||||
contracted.BindTo(timelineBlueprintContainer.SamplePointContracted);
|
||||
|
||||
if (zoom.NewValue < zoom_threshold)
|
||||
contracted.BindValueChanged(v =>
|
||||
{
|
||||
if (v.NewValue)
|
||||
{
|
||||
contracted = true;
|
||||
Label.FadeOut(200, Easing.OutQuint);
|
||||
LabelContainer.ResizeTo(new Vector2(12), 200, Easing.OutQuint);
|
||||
LabelContainer.CornerRadius = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
contracted = false;
|
||||
Label.FadeIn(200, Easing.OutQuint);
|
||||
LabelContainer.ResizeTo(new Vector2(Label.Width, 16), 200, Easing.OutQuint);
|
||||
LabelContainer.CornerRadius = 8;
|
||||
@ -131,7 +127,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
{
|
||||
Label.Text = $"{abbreviateBank(GetBankValue(GetSamples()))} {GetVolumeValue(GetSamples())}";
|
||||
|
||||
if (!contracted)
|
||||
if (!contracted.Value)
|
||||
LabelContainer.ResizeWidthTo(Label.Width, 200, Easing.OutQuint);
|
||||
}
|
||||
|
||||
|
@ -15,16 +15,19 @@ using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Layout;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
{
|
||||
[Cached]
|
||||
internal partial class TimelineBlueprintContainer : EditorBlueprintContainer
|
||||
{
|
||||
[Resolved(CanBeNull = true)]
|
||||
@ -35,6 +38,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
|
||||
private bool hitObjectDragged;
|
||||
|
||||
private readonly LayoutValue samplePointContractedStateCache = new LayoutValue(Invalidation.DrawSize);
|
||||
|
||||
/// <remarks>
|
||||
/// Positional input must be received outside the container's bounds,
|
||||
/// in order to handle timeline blueprints which are stacked offscreen.
|
||||
@ -49,6 +54,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
Height = 0.6f;
|
||||
|
||||
AddLayout(samplePointContractedStateCache);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -116,11 +123,43 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
Composer.Playfield.FutureLifetimeExtension = timeline.VisibleRange / 2;
|
||||
}
|
||||
|
||||
updateSamplePointContractedState();
|
||||
|
||||
base.Update();
|
||||
|
||||
updateStacking();
|
||||
}
|
||||
|
||||
public Bindable<bool> SamplePointContracted = new Bindable<bool>();
|
||||
|
||||
private void updateSamplePointContractedState()
|
||||
{
|
||||
if (samplePointContractedStateCache.IsValid)
|
||||
return;
|
||||
|
||||
const double minimum_gap = 28;
|
||||
|
||||
// Find the smallest time gap between any two sample point pieces
|
||||
double smallestTimeGap = double.PositiveInfinity;
|
||||
double lastTime = double.PositiveInfinity;
|
||||
|
||||
// The blueprints are ordered in reverse chronological order
|
||||
foreach (var selectionBlueprint in SelectionBlueprints)
|
||||
{
|
||||
var hitObject = selectionBlueprint.Item;
|
||||
|
||||
if (hitObject is IHasRepeats hasRepeats)
|
||||
smallestTimeGap = Math.Min(smallestTimeGap, hasRepeats.Duration / hasRepeats.SpanCount() / 2);
|
||||
|
||||
smallestTimeGap = Math.Min(smallestTimeGap, lastTime - hitObject.GetEndTime());
|
||||
lastTime = hitObject.StartTime;
|
||||
}
|
||||
|
||||
double smallestAbsoluteGap = ((TimelineSelectionBlueprintContainer)SelectionBlueprints).ContentRelativeToAbsoluteFactor.X * smallestTimeGap;
|
||||
SamplePointContracted.Value = smallestAbsoluteGap < minimum_gap;
|
||||
samplePointContractedStateCache.Validate();
|
||||
}
|
||||
|
||||
private readonly Stack<HitObject> currentConcurrentObjects = new Stack<HitObject>();
|
||||
|
||||
private void updateStacking()
|
||||
@ -288,6 +327,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
{
|
||||
protected override Container<SelectionBlueprint<HitObject>> Content { get; }
|
||||
|
||||
public Vector2 ContentRelativeToAbsoluteFactor => Content.RelativeToAbsoluteFactor;
|
||||
|
||||
public TimelineSelectionBlueprintContainer()
|
||||
{
|
||||
AddInternal(new TimelinePart<SelectionBlueprint<HitObject>>(Content = new HitObjectOrderedSelectionContainer { RelativeSizeAxes = Axes.Both }) { RelativeSizeAxes = Axes.Both });
|
||||
|
Loading…
Reference in New Issue
Block a user