1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-30 05:22:54 +08:00

Re-implement mousewheel zoom

This commit is contained in:
smoogipoo 2018-04-05 18:37:51 +09:00
parent e3af32ad2f
commit 074dee3a83

View File

@ -4,8 +4,12 @@
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Input;
using osu.Framework.MathUtils;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics; using osu.Game.Graphics;
using OpenTK;
namespace osu.Game.Screens.Edit.Screens.Compose.Timeline namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
{ {
@ -15,13 +19,15 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>(); public readonly Bindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
private readonly Container waveformContainer; private readonly Container waveformContainer;
private readonly BeatmapWaveformGraph waveform;
private float currentZoom = 10;
public ScrollingTimelineContainer() public ScrollingTimelineContainer()
: base(Direction.Horizontal) : base(Direction.Horizontal)
{ {
Masking = true; Masking = true;
BeatmapWaveformGraph waveform;
Child = waveformContainer = new Container Child = waveformContainer = new Container
{ {
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
@ -34,18 +40,75 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline
}; };
waveform.Beatmap.BindTo(Beatmap); waveform.Beatmap.BindTo(Beatmap);
WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint);
} }
private float zoom = 10;
protected override void Update() protected override void Update()
{ {
base.Update(); base.Update();
waveformContainer.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; waveformContainer.Margin = new MarginPadding { Horizontal = DrawWidth / 2 };
waveformContainer.Width = DrawWidth * zoom; waveformContainer.Width = DrawWidth * currentZoom;
}
protected override bool OnWheel(InputState state)
{
if (!state.Keyboard.ControlPressed)
return base.OnWheel(state);
setZoomTarget(zoomTarget + state.Mouse.WheelDelta, waveformContainer.ToLocalSpace(state.Mouse.NativeState.Position).X);
return true;
}
private float zoomTarget = 10;
private void setZoomTarget(float newZoom, float focusPoint)
{
zoomTarget = MathHelper.Clamp(newZoom, 1, 60);
transformZoomTo(zoomTarget, focusPoint, 200, Easing.OutQuint);
}
private void transformZoomTo(float newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None)
=> this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, waveformContainer.DrawWidth, DrawWidth, Current), newZoom, duration, easing));
private class TransformZoom : Transform<float, ScrollingTimelineContainer>
{
private readonly float focusPoint;
private readonly float focusSize;
private readonly float sizeReference;
private readonly float scrollOffset;
public TransformZoom(float focusPoint, float focusSize, float sizeReference, float scrollOffset)
{
this.focusPoint = focusPoint;
this.focusSize = focusSize;
this.sizeReference = sizeReference;
this.scrollOffset = scrollOffset;
}
public override string TargetMember => nameof(currentZoom);
private float valueAt(double time)
{
if (time < StartTime) return StartValue;
if (time >= EndTime) return EndValue;
return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing);
}
protected override void Apply(ScrollingTimelineContainer d, double time)
{
float newZoom = valueAt(time);
float focusOffset = focusPoint - scrollOffset;
float expectedWidth = sizeReference * newZoom;
float targetOffset = expectedWidth * (focusPoint / focusSize) - focusOffset;
d.currentZoom = newZoom;
d.ScrollTo(targetOffset, false);
}
protected override void ReadIntoStartValue(ScrollingTimelineContainer d) => StartValue = d.currentZoom;
} }
} }
} }