Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix user-contracted toolbox groups in editor incorrectly expanding on hover #18120

Merged
merged 10 commits into from May 6, 2022
Expand Up @@ -99,15 +99,15 @@ public void TestHoveringExpandsContainer()
}

/// <summary>
/// Tests expanding a container will expand underlying groups if contracted.
/// Tests expanding a container will not expand underlying groups if they were manually contracted by the user.
/// </summary>
[Test]
public void TestExpandingContainerExpandsContractedGroup()
public void TestExpandingContainerDoesNotExpandContractedGroup()
{
AddStep("contract group", () => toolboxGroup.Expanded.Value = false);

AddStep("expand container", () => container.Expanded.Value = true);
AddAssert("group expanded", () => toolboxGroup.Expanded.Value);
AddAssert("group not expanded", () => !toolboxGroup.Expanded.Value);
AddAssert("controls expanded", () => slider1.Expanded.Value && slider2.Expanded.Value);

AddStep("contract container", () => container.Expanded.Value = false);
Expand Down
103 changes: 36 additions & 67 deletions osu.Game/Overlays/SettingsToolboxGroup.cs
@@ -1,7 +1,6 @@
// 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 osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Caching;
using osu.Framework.Extensions.EnumExtensions;
Expand Down Expand Up @@ -35,14 +34,13 @@ public class SettingsToolboxGroup : Container, IExpandable
private readonly Cached headerTextVisibilityCache = new Cached();

private readonly FillFlowContainer content;
private readonly IconButton button;

public BindableBool Expanded { get; } = new BindableBool(true);

private Color4 expandedColour;

private readonly OsuSpriteText headerText;

private readonly Container headerContent;

/// <summary>
/// Create a new instance.
/// </summary>
Expand Down Expand Up @@ -71,7 +69,7 @@ public SettingsToolboxGroup(string title)
AutoSizeAxes = Axes.Y,
Children = new Drawable[]
{
new Container
headerContent = new Container
{
Name = @"Header",
Origin = Anchor.TopCentre,
Expand All @@ -88,7 +86,7 @@ public SettingsToolboxGroup(string title)
Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 17),
Padding = new MarginPadding { Left = 10, Right = 30 },
},
button = new IconButton
new IconButton
{
Origin = Anchor.Centre,
Anchor = Anchor.CentreRight,
Expand Down Expand Up @@ -117,12 +115,25 @@ public SettingsToolboxGroup(string title)
};
}

protected override bool OnInvalidate(Invalidation invalidation, InvalidationSource source)
protected override void LoadComplete()
{
if (invalidation.HasFlagFast(Invalidation.DrawSize))
headerTextVisibilityCache.Invalidate();
base.LoadComplete();

return base.OnInvalidate(invalidation, source);
Expanded.BindValueChanged(updateExpandedState, true);

this.Delay(600).Schedule(updateFadeState);
}

protected override bool OnHover(HoverEvent e)
{
updateFadeState();
return false;
}

protected override void OnHoverLost(HoverLostEvent e)
{
updateFadeState();
base.OnHoverLost(e);
}

protected override void Update()
Expand All @@ -135,72 +146,30 @@ protected override void Update()
headerText.FadeTo(headerText.DrawWidth < DrawWidth ? 1 : 0, 150, Easing.OutQuint);
}

[Resolved(canBeNull: true)]
private IExpandingContainer expandingContainer { get; set; }

private bool expandedByContainer;

protected override void LoadComplete()
protected override bool OnInvalidate(Invalidation invalidation, InvalidationSource source)
{
base.LoadComplete();

expandingContainer?.Expanded.BindValueChanged(containerExpanded =>
{
if (containerExpanded.NewValue && !Expanded.Value)
{
Expanded.Value = true;
expandedByContainer = true;
}
else if (!containerExpanded.NewValue && expandedByContainer)
{
Expanded.Value = false;
expandedByContainer = false;
}

updateActiveState();
}, true);

Expanded.BindValueChanged(v =>
{
// clearing transforms can break autosizing, see: https://github.com/ppy/osu-framework/issues/5064
if (v.NewValue != v.OldValue)
content.ClearTransforms();

if (v.NewValue)
content.AutoSizeAxes = Axes.Y;
else
{
content.AutoSizeAxes = Axes.None;
content.ResizeHeightTo(0, transition_duration, Easing.OutQuint);
}

button.FadeColour(Expanded.Value ? expandedColour : Color4.White, 200, Easing.InOutQuint);
}, true);

this.Delay(600).Schedule(updateActiveState);
}
if (invalidation.HasFlagFast(Invalidation.DrawSize))
headerTextVisibilityCache.Invalidate();

protected override bool OnHover(HoverEvent e)
{
updateActiveState();
return false;
return base.OnInvalidate(invalidation, source);
}

protected override void OnHoverLost(HoverLostEvent e)
private void updateExpandedState(ValueChangedEvent<bool> expanded)
{
updateActiveState();
base.OnHoverLost(e);
}
if (expanded.NewValue)
content.AutoSizeAxes = Axes.Y;
else
{
content.AutoSizeAxes = Axes.None;
content.ResizeHeightTo(0, transition_duration, Easing.OutQuint);
}

[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
expandedColour = colours.Yellow;
headerContent.FadeColour(expanded.NewValue ? Color4.White : OsuColour.Gray(0.5f), 200, Easing.OutQuint);
}

private void updateActiveState()
private void updateFadeState()
{
this.FadeTo(IsHovered || expandingContainer?.Expanded.Value == true ? 1 : inactive_alpha, fade_duration, Easing.OutQuint);
this.FadeTo(IsHovered ? 1 : inactive_alpha, fade_duration, Easing.OutQuint);
}

protected override Container<Drawable> Content => content;
Expand Down