mirror of
https://github.com/osukey/osukey.git
synced 2025-08-07 00:23:59 +09:00
Merge pull request #18462 from frenzibyte/fix-timeline-zooming
Fix timeline objects disappearing prematurely on wide-screens
This commit is contained in:
48
osu.Game.Tests/Visual/Editing/TestSceneTimelineZoom.cs
Normal file
48
osu.Game.Tests/Visual/Editing/TestSceneTimelineZoom.cs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Utils;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Editing
|
||||||
|
{
|
||||||
|
public class TestSceneTimelineZoom : TimelineTestScene
|
||||||
|
{
|
||||||
|
public override Drawable CreateTestComponent() => Empty();
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestVisibleRangeUpdatesOnZoomChange()
|
||||||
|
{
|
||||||
|
double initialVisibleRange = 0;
|
||||||
|
|
||||||
|
AddStep("reset zoom", () => TimelineArea.Timeline.Zoom = 100);
|
||||||
|
AddStep("get initial range", () => initialVisibleRange = TimelineArea.Timeline.VisibleRange);
|
||||||
|
|
||||||
|
AddStep("scale zoom", () => TimelineArea.Timeline.Zoom = 200);
|
||||||
|
AddAssert("range halved", () => Precision.AlmostEquals(TimelineArea.Timeline.VisibleRange, initialVisibleRange / 2, 1));
|
||||||
|
AddStep("descale zoom", () => TimelineArea.Timeline.Zoom = 50);
|
||||||
|
AddAssert("range doubled", () => Precision.AlmostEquals(TimelineArea.Timeline.VisibleRange, initialVisibleRange * 2, 1));
|
||||||
|
|
||||||
|
AddStep("restore zoom", () => TimelineArea.Timeline.Zoom = 100);
|
||||||
|
AddAssert("range restored", () => Precision.AlmostEquals(TimelineArea.Timeline.VisibleRange, initialVisibleRange, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestVisibleRangeConstantOnSizeChange()
|
||||||
|
{
|
||||||
|
double initialVisibleRange = 0;
|
||||||
|
|
||||||
|
AddStep("reset timeline size", () => TimelineArea.Timeline.Width = 1);
|
||||||
|
AddStep("get initial range", () => initialVisibleRange = TimelineArea.Timeline.VisibleRange);
|
||||||
|
|
||||||
|
AddStep("scale timeline size", () => TimelineArea.Timeline.Width = 2);
|
||||||
|
AddAssert("same range", () => TimelineArea.Timeline.VisibleRange == initialVisibleRange);
|
||||||
|
AddStep("descale timeline size", () => TimelineArea.Timeline.Width = 0.5f);
|
||||||
|
AddAssert("same range", () => TimelineArea.Timeline.VisibleRange == initialVisibleRange);
|
||||||
|
|
||||||
|
AddStep("restore timeline size", () => TimelineArea.Timeline.Width = 1);
|
||||||
|
AddAssert("same range", () => TimelineArea.Timeline.VisibleRange == initialVisibleRange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -44,7 +44,12 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = OsuColour.Gray(30)
|
Colour = OsuColour.Gray(30)
|
||||||
},
|
},
|
||||||
scrollContainer = new ZoomableScrollContainer { RelativeSizeAxes = Axes.Both }
|
scrollContainer = new ZoomableScrollContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new MenuCursor()
|
new MenuCursor()
|
||||||
@ -62,7 +67,15 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestWidthInitialization()
|
public void TestWidthInitialization()
|
||||||
{
|
{
|
||||||
AddAssert("Inner container width was initialized", () => innerBox.DrawWidth > 0);
|
AddAssert("Inner container width was initialized", () => innerBox.DrawWidth == scrollContainer.DrawWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestWidthUpdatesOnDrawSizeChanges()
|
||||||
|
{
|
||||||
|
AddStep("Shrink scroll container", () => scrollContainer.Width = 0.5f);
|
||||||
|
AddAssert("Scroll container width shrunk", () => scrollContainer.DrawWidth == scrollContainer.Parent.DrawWidth / 2);
|
||||||
|
AddAssert("Inner container width matches scroll container", () => innerBox.DrawWidth == scrollContainer.DrawWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -7,6 +7,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Transforms;
|
using osu.Framework.Graphics.Transforms;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Framework.Layout;
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
@ -40,10 +41,14 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
[Resolved(canBeNull: true)]
|
[Resolved(canBeNull: true)]
|
||||||
private IFrameBasedClock editorClock { get; set; }
|
private IFrameBasedClock editorClock { get; set; }
|
||||||
|
|
||||||
|
private readonly LayoutValue zoomedContentWidthCache = new LayoutValue(Invalidation.DrawSize);
|
||||||
|
|
||||||
public ZoomableScrollContainer()
|
public ZoomableScrollContainer()
|
||||||
: base(Direction.Horizontal)
|
: base(Direction.Horizontal)
|
||||||
{
|
{
|
||||||
base.Content.Add(zoomedContent = new Container { RelativeSizeAxes = Axes.Y });
|
base.Content.Add(zoomedContent = new Container { RelativeSizeAxes = Axes.Y });
|
||||||
|
|
||||||
|
AddLayout(zoomedContentWidthCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
private float minZoom = 1;
|
private float minZoom = 1;
|
||||||
@ -103,11 +108,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.Update();
|
||||||
|
|
||||||
// This width only gets updated on the application of a transform, so this needs to be initialized here.
|
if (!zoomedContentWidthCache.IsValid)
|
||||||
updateZoomedContentWidth();
|
updateZoomedContentWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +133,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
return base.OnScroll(e);
|
return base.OnScroll(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateZoomedContentWidth() => zoomedContent.Width = DrawWidth * currentZoom;
|
private void updateZoomedContentWidth()
|
||||||
|
{
|
||||||
|
zoomedContent.Width = DrawWidth * currentZoom;
|
||||||
|
zoomedContentWidthCache.Validate();
|
||||||
|
}
|
||||||
|
|
||||||
private float zoomTarget = 1;
|
private float zoomTarget = 1;
|
||||||
|
|
||||||
@ -199,8 +208,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
float targetOffset = expectedWidth * (focusPoint / contentSize) - focusOffset;
|
float targetOffset = expectedWidth * (focusPoint / contentSize) - focusOffset;
|
||||||
|
|
||||||
d.currentZoom = newZoom;
|
d.currentZoom = newZoom;
|
||||||
|
|
||||||
d.updateZoomedContentWidth();
|
d.updateZoomedContentWidth();
|
||||||
|
|
||||||
// Temporarily here to make sure ScrollTo gets the correct DrawSize for scrollable area.
|
// Temporarily here to make sure ScrollTo gets the correct DrawSize for scrollable area.
|
||||||
// TODO: Make sure draw size gets invalidated properly on the framework side, and remove this once it is.
|
// TODO: Make sure draw size gets invalidated properly on the framework side, and remove this once it is.
|
||||||
d.Invalidate(Invalidation.DrawSize);
|
d.Invalidate(Invalidation.DrawSize);
|
||||||
|
Reference in New Issue
Block a user