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:
parent
e3af32ad2f
commit
074dee3a83
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user