diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 35a0282611..5722174490 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -24,7 +24,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Cached] public class Timeline : ZoomableScrollContainer, IPositionSnapProvider { + private const float timeline_height = 72; + private const float timeline_expanded_height = 94; + private readonly Drawable userContent; + public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable ControlPointsVisible = new Bindable(); @@ -58,8 +62,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private Track track; - private const float timeline_height = 72; - private const float timeline_expanded_height = 94; + /// + /// The timeline zoom level at a 1x zoom scale. + /// + private float defaultTimelineZoom; + + private readonly Bindable timelineZoomScale = new BindableDouble(1.0); public Timeline(Drawable userContent) { @@ -84,7 +92,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private Bindable waveformOpacity; [BackgroundDependencyLoader] - private void load(IBindable beatmap, OsuColour colours, OsuConfigManager config) + private void load(IBindable beatmap, EditorBeatmap editorBeatmap, OsuColour colours, OsuConfigManager config) { CentreMarker centreMarker; @@ -141,9 +149,16 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { MaxZoom = getZoomLevelForVisibleMilliseconds(500); MinZoom = getZoomLevelForVisibleMilliseconds(10000); - Zoom = getZoomLevelForVisibleMilliseconds(6000); + defaultTimelineZoom = getZoomLevelForVisibleMilliseconds(6000); } }, true); + + timelineZoomScale.Value = editorBeatmap.BeatmapInfo.TimelineZoom; + timelineZoomScale.BindValueChanged(scale => + { + Zoom = (float)(defaultTimelineZoom * scale.NewValue); + editorBeatmap.BeatmapInfo.TimelineZoom = scale.NewValue; + }, true); } protected override void LoadComplete() @@ -201,6 +216,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline return base.OnScroll(e); } + protected override void OnZoomChange() + { + base.OnZoomChange(); + timelineZoomScale.Value = Zoom / defaultTimelineZoom; + } + protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs index f10eb0d284..6dea99f1c8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs @@ -136,11 +136,20 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { zoomTarget = Math.Clamp(newZoom, MinZoom, MaxZoom); transformZoomTo(zoomTarget, focusPoint, ZoomDuration, ZoomEasing); + + OnZoomChange(); } private void transformZoomTo(float newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth, Current), newZoom, duration, easing)); + /// + /// Invoked when the zoom target has changed. + /// + protected virtual void OnZoomChange() + { + } + private class TransformZoom : Transform { ///