mirror of
https://github.com/ppy/osu.git
synced 2026-06-04 11:44:27 +08:00
Maintain scroll position relative to hovered drawable in ExpandingToolboxContainer
This commit is contained in:
@@ -40,21 +40,22 @@ namespace osu.Game.Graphics.Containers
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
Width = contractedWidth;
|
||||
|
||||
InternalChild = new OsuScrollContainer
|
||||
InternalChild = CreateScrollContainer().With(s =>
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
ScrollbarVisible = false,
|
||||
Child = FillFlow = new FillFlowContainer
|
||||
{
|
||||
Origin = Anchor.CentreLeft,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
},
|
||||
};
|
||||
s.RelativeSizeAxes = Axes.Both;
|
||||
s.ScrollbarVisible = false;
|
||||
}).WithChild(FillFlow = new FillFlowContainer
|
||||
{
|
||||
Origin = Anchor.CentreLeft,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
});
|
||||
}
|
||||
|
||||
protected virtual OsuScrollContainer CreateScrollContainer() => new OsuScrollContainer();
|
||||
|
||||
private ScheduledDelegate? hoverExpandEvent;
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
// 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 System;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Screens.Edit;
|
||||
@@ -21,6 +24,7 @@ namespace osu.Game.Rulesets.Edit
|
||||
private readonly Bindable<bool> contractSidebars = new Bindable<bool>();
|
||||
|
||||
private bool expandOnHover;
|
||||
private OffsetMaintainingScrollContainer scrollContainer = null!;
|
||||
|
||||
[Resolved]
|
||||
private Editor? editor { get; set; }
|
||||
@@ -42,6 +46,25 @@ namespace osu.Game.Rulesets.Edit
|
||||
config.BindWith(OsuSetting.EditorContractSidebars, contractSidebars);
|
||||
}
|
||||
|
||||
protected override OsuScrollContainer CreateScrollContainer() => scrollContainer = new OffsetMaintainingScrollContainer();
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
var inputManager = GetContainingInputManager();
|
||||
|
||||
if (inputManager != null)
|
||||
{
|
||||
Expanded.BindValueChanged(_ =>
|
||||
{
|
||||
var position = new Vector2(ScreenSpaceDrawQuad.Centre.X, inputManager.CurrentState.Mouse.Position.Y);
|
||||
|
||||
scrollContainer.TargetDrawable = Children.FirstOrDefault(it => it.Contains(position));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
@@ -53,10 +76,57 @@ namespace osu.Game.Rulesets.Edit
|
||||
expandOnHover = requireContracting;
|
||||
Expanded.Value = !expandOnHover;
|
||||
}
|
||||
|
||||
if (scrollContainer.TargetDrawable != null && !TransformsForTargetMember(nameof(Width)).Any())
|
||||
scrollContainer.TargetDrawable = null;
|
||||
}
|
||||
|
||||
protected override bool OnMouseDown(MouseDownEvent e) => true;
|
||||
|
||||
protected override bool OnClick(ClickEvent e) => true;
|
||||
|
||||
private partial class OffsetMaintainingScrollContainer : OsuScrollContainer
|
||||
{
|
||||
private Drawable? targetDrawable;
|
||||
private float targetPosition;
|
||||
|
||||
public Drawable? TargetDrawable
|
||||
{
|
||||
get => targetDrawable;
|
||||
set
|
||||
{
|
||||
targetDrawable = value;
|
||||
|
||||
if (value != null)
|
||||
targetPosition = ToLocalSpace(value.ScreenSpaceDrawQuad.TopLeft).Y;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
{
|
||||
if (targetDrawable != null)
|
||||
{
|
||||
float currentPosition = ToLocalSpace(targetDrawable.ScreenSpaceDrawQuad.TopLeft).Y;
|
||||
|
||||
if (!Precision.AlmostEquals(targetPosition, currentPosition))
|
||||
{
|
||||
double offset = currentPosition - targetPosition;
|
||||
|
||||
double scrollTarget = Math.Clamp(Current + offset, 0, ScrollableExtent);
|
||||
|
||||
ScrollTo(scrollTarget, false, double.PositiveInfinity);
|
||||
}
|
||||
}
|
||||
|
||||
base.UpdateAfterChildren();
|
||||
}
|
||||
|
||||
protected override void OnUserScroll(double value, bool animated = true, double? distanceDecay = null)
|
||||
{
|
||||
targetDrawable = null;
|
||||
|
||||
base.OnUserScroll(value, animated, distanceDecay);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user