1
0
mirror of https://github.com/ppy/osu.git synced 2026-06-03 22:14:57 +08:00

Merge pull request #32847 from frenzibyte/song-select-v2-sheared-components-changes

Fixes and improvements to existing sheared components
This commit is contained in:
Dean Herbert
2025-04-30 14:25:28 +09:00
committed by GitHub
Unverified
9 changed files with 179 additions and 105 deletions
@@ -13,7 +13,6 @@ using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
using osuTK;
using osuTK.Input;
namespace osu.Game.Tests.Visual.UserInterface
@@ -183,32 +182,31 @@ namespace osu.Game.Tests.Visual.UserInterface
Origin = Anchor.Centre,
Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both,
Scale = new Vector2(2.5f),
Children = new Drawable[]
{
new ShearedButton(120)
new ShearedButton
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Text = "Test",
Text = "Button",
Action = () => { },
Padding = new MarginPadding(),
Height = 30,
},
new ShearedButton(120, 40)
new ShearedButton
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Text = "Test",
Text = "Button",
Action = () => { },
Padding = new MarginPadding { Left = -1f },
Height = 30,
},
new ShearedButton(120, 70)
new ShearedButton
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Text = "Test",
Text = "Button",
Action = () => { },
Padding = new MarginPadding { Left = 3f },
Height = 30,
},
}
}
@@ -3,38 +3,50 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
using osuTK.Graphics;
using osuTK.Input;
namespace osu.Game.Tests.Visual.UserInterface
{
public partial class TestSceneShearedSliderBar : OsuManualInputManagerTestScene
public partial class TestSceneShearedSliderBar : ThemeComparisonTestScene
{
[Cached]
private OverlayColourProvider colourProvider { get; set; } = new OverlayColourProvider(OverlayColourScheme.Purple);
private TestSliderBar slider = null!;
private ShearedSliderBar<double> slider = null!;
[SetUpSteps]
public void SetUpSteps()
protected override Drawable CreateContent() => slider = new TestSliderBar
{
AddStep("create slider", () => Child = slider = new ShearedSliderBar<double>
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Current = new BindableDouble(5)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Current = new BindableDouble(5)
Precision = 0.1,
MinValue = 0,
MaxValue = 15
},
RelativeSizeAxes = Axes.X,
Width = 0.4f
};
[Test]
public void TestNubDisplay()
{
AddSliderStep("nub width", 20, 80, 50, v =>
{
if (slider.IsNotNull())
{
Precision = 0.1,
MinValue = 0,
MaxValue = 15
},
RelativeSizeAxes = Axes.X,
Width = 0.4f
slider.Nub.Width = v;
slider.RangePadding = v / 2f;
}
});
AddToggleStep("nub shadow", v =>
{
if (slider.IsNotNull())
slider.NubShadowColour = v ? Color4.Black.Opacity(0.2f) : Color4.Black.Opacity(0f);
});
}
@@ -69,6 +81,12 @@ namespace osu.Game.Tests.Visual.UserInterface
});
AddAssert("slider is still at 1", () => slider.Current.Value, () => Is.EqualTo(1));
AddStep("enable slider", () => slider.Current.Disabled = false);
}
public partial class TestSliderBar : ShearedSliderBar<double>
{
public new ShearedNub Nub => base.Nub;
}
}
}
@@ -88,12 +88,12 @@ namespace osu.Game.Graphics.UserInterface
public ShearedButton(float? width = null, float height = DEFAULT_HEIGHT)
{
Height = height;
Padding = new MarginPadding { Horizontal = OsuGame.SHEAR.X * height };
Content.CornerRadius = CORNER_RADIUS;
Content.Shear = OsuGame.SHEAR;
Content.Masking = true;
Shear = OsuGame.SHEAR;
Content.Anchor = Content.Origin = Anchor.Centre;
Content.CornerRadius = CORNER_RADIUS;
Content.Masking = true;
Children = new Drawable[]
{
+74 -42
View File
@@ -21,37 +21,54 @@ namespace osu.Game.Graphics.UserInterface
{
public Action? OnDoubleClicked { get; init; }
protected const float BORDER_WIDTH = 3;
public const int HEIGHT = 30;
public const float EXPANDED_SIZE = 50;
public const float CORNER_RADIUS = 5;
private readonly Box fill;
private readonly Container main;
private readonly Container shadow;
/// <summary>
/// Implements the shape for the nub, allowing for any type of container to be used.
/// </summary>
/// <returns></returns>
public ShearedNub()
{
Size = new Vector2(EXPANDED_SIZE, HEIGHT);
InternalChild = main = new Container
InternalChildren = new Drawable[]
{
Shear = OsuGame.SHEAR,
BorderColour = Colour4.White,
BorderThickness = BORDER_WIDTH,
Masking = true,
CornerRadius = 5,
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Child = fill = new Box
shadow = new Container
{
Shear = OsuGame.SHEAR,
Masking = true,
CornerRadius = CORNER_RADIUS,
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true,
}
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Shadow,
Radius = 20f,
},
Child = new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true,
}
},
main = new Container
{
Shear = OsuGame.SHEAR,
BorderColour = Colour4.White,
BorderThickness = 8f,
Masking = true,
CornerRadius = CORNER_RADIUS,
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Child = fill = new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true,
}
},
};
}
@@ -76,6 +93,7 @@ namespace osu.Game.Graphics.UserInterface
base.LoadComplete();
Current.BindValueChanged(onCurrentValueChanged, true);
FinishTransforms(true);
}
private bool glowing;
@@ -89,22 +107,22 @@ namespace osu.Game.Graphics.UserInterface
return;
glowing = value;
updateDisplay();
}
}
if (value)
{
main.FadeColour(GlowingAccentColour.Lighten(0.1f), 40, Easing.OutQuint)
.Then()
.FadeColour(GlowingAccentColour, 800, Easing.OutQuint);
private Color4 shadowColour = Color4.Black.Opacity(0f);
main.FadeEdgeEffectTo(Color4.White.Opacity(0.1f), 40, Easing.OutQuint)
.Then()
.FadeEdgeEffectTo(GlowColour.Opacity(0.1f), 800, Easing.OutQuint);
}
else
{
main.FadeEdgeEffectTo(GlowColour.Opacity(0), 800, Easing.OutQuint);
main.FadeColour(AccentColour, 800, Easing.OutQuint);
}
public Color4 ShadowColour
{
get => shadowColour;
set
{
if (shadowColour == value)
return;
shadowColour = value;
shadow.FadeEdgeEffectTo(value, 800, Easing.OutQuint);
}
}
@@ -130,8 +148,7 @@ namespace osu.Game.Graphics.UserInterface
set
{
accentColour = value;
if (!Glowing)
main.Colour = value;
updateDisplay();
}
}
@@ -143,8 +160,7 @@ namespace osu.Game.Graphics.UserInterface
set
{
glowingAccentColour = value;
if (Glowing)
main.Colour = value;
updateDisplay();
}
}
@@ -156,10 +172,7 @@ namespace osu.Game.Graphics.UserInterface
set
{
glowColour = value;
var effect = main.EdgeEffect;
effect.Colour = Glowing ? value : value.Opacity(0);
main.EdgeEffect = effect;
updateDisplay();
}
}
@@ -177,7 +190,26 @@ namespace osu.Game.Graphics.UserInterface
else
{
main.ResizeWidthTo(0.75f, duration, Easing.OutQuint);
main.TransformTo(nameof(BorderThickness), BORDER_WIDTH, duration, Easing.OutQuint);
main.TransformTo(nameof(BorderThickness), 8f, duration, Easing.OutQuint);
}
}
private void updateDisplay()
{
if (Glowing)
{
main.FadeColour(GlowingAccentColour.Lighten(0.1f), 40, Easing.OutQuint)
.Then()
.FadeColour(GlowingAccentColour, 800, Easing.OutQuint);
main.FadeEdgeEffectTo(Color4.White.Opacity(0.1f), 40, Easing.OutQuint)
.Then()
.FadeEdgeEffectTo(GlowColour.Opacity(0.1f), 800, Easing.OutQuint);
}
else
{
main.FadeEdgeEffectTo(GlowColour.Opacity(0), 800, Easing.OutQuint);
main.FadeColour(AccentColour, 800, Easing.OutQuint);
}
}
@@ -12,7 +12,6 @@ using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
using osu.Game.Overlays;
using static osu.Game.Graphics.UserInterface.ShearedNub;
using Vector2 = osuTK.Vector2;
namespace osu.Game.Graphics.UserInterface
@@ -29,6 +28,8 @@ namespace osu.Game.Graphics.UserInterface
private readonly Container mainContent;
protected virtual bool FocusIndicator => true;
private Color4 accentColour;
public Color4 AccentColour
@@ -56,11 +57,17 @@ namespace osu.Game.Graphics.UserInterface
}
}
public Color4 NubShadowColour
{
get => Nub.ShadowColour;
set => Nub.ShadowColour = value;
}
public ShearedSliderBar()
{
Shear = OsuGame.SHEAR;
Height = HEIGHT;
RangePadding = EXPANDED_SIZE / 2;
Height = ShearedNub.HEIGHT;
RangePadding = ShearedNub.EXPANDED_SIZE / 2;
Children = new Drawable[]
{
mainContent = new Container
@@ -102,7 +109,6 @@ namespace osu.Game.Graphics.UserInterface
RelativeSizeAxes = Axes.Both,
Child = Nub = new ShearedNub
{
X = -OsuGame.SHEAR.X * HEIGHT / 2f,
Origin = Anchor.TopCentre,
RelativePositionAxes = Axes.X,
Current = { Value = true },
@@ -146,13 +152,16 @@ namespace osu.Game.Graphics.UserInterface
{
base.OnFocus(e);
mainContent.EdgeEffect = new EdgeEffectParameters
if (FocusIndicator)
{
Type = EdgeEffectType.Glow,
Colour = AccentColour.Darken(1),
Hollow = true,
Radius = 2,
};
mainContent.EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Colour = AccentColour.Darken(1),
Hollow = true,
Radius = 2,
};
}
}
protected override void OnFocusLost(FocusLostEvent e)
@@ -191,8 +200,8 @@ namespace osu.Game.Graphics.UserInterface
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
LeftBox.Scale = new Vector2(Math.Clamp(RangePadding + Nub.DrawPosition.X - Nub.DrawWidth / 2.3f, 0, Math.Max(0, DrawWidth)), 1);
RightBox.Scale = new Vector2(Math.Clamp(DrawWidth - Nub.DrawPosition.X - RangePadding - Nub.DrawWidth / 2.3f, 0, Math.Max(0, DrawWidth)), 1);
LeftBox.Scale = new Vector2(Math.Clamp(RangePadding + Nub.DrawPosition.X - Nub.DrawWidth / 2f + ShearedNub.CORNER_RADIUS - 0.5f, 0, Math.Max(0, DrawWidth)), 1);
RightBox.Scale = new Vector2(Math.Clamp(DrawWidth - RangePadding - Nub.DrawPosition.X - Nub.DrawWidth / 2f + ShearedNub.CORNER_RADIUS - 0.5f, 0, Math.Max(0, DrawWidth)), 1);
}
protected override void UpdateValue(float value)
+1 -1
View File
@@ -33,7 +33,7 @@ namespace osu.Game.Overlays.Mods
Height = ModSelectPanel.HEIGHT;
// shear will be applied at a higher level in `ModPresetColumn`.
Content.Shear = Vector2.Zero;
Shear = Vector2.Zero;
Padding = new MarginPadding();
Text = "+";
+18 -4
View File
@@ -40,11 +40,13 @@ namespace osu.Game.Overlays.Mods
public AddPresetPopover(AddPresetButton addPresetButton)
{
const float content_width = 300;
button = addPresetButton;
Child = new FillFlowContainer
{
Width = 300,
Width = content_width,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(7),
Children = new Drawable[]
@@ -63,12 +65,24 @@ namespace osu.Game.Overlays.Mods
Label = CommonStrings.Description,
TabbableContentContainer = this
},
createButton = new ShearedButton
new FillFlowContainer
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = ModSelectOverlayStrings.AddPreset,
Action = createPreset
AutoSizeAxes = Axes.Both,
Spacing = new Vector2(7),
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
createButton = new ShearedButton(content_width)
{
// todo: for some very odd reason, this needs to be anchored to topright for the fill flow to be correctly sized to the AABB of the sheared button
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Text = ModSelectOverlayStrings.AddPreset,
Action = createPreset
}
}
}
}
};
+13 -9
View File
@@ -52,9 +52,11 @@ namespace osu.Game.Overlays.Mods
[BackgroundDependencyLoader]
private void load()
{
const float content_width = 300;
Child = new FillFlowContainer
{
Width = 300,
Width = content_width,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(7),
Direction = FillDirection.Vertical,
@@ -107,25 +109,27 @@ namespace osu.Game.Overlays.Mods
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
AutoSizeAxes = Axes.Both,
Spacing = new Vector2(7),
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
useCurrentModsButton = new ShearedButton
useCurrentModsButton = new ShearedButton(content_width)
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
// todo: for some very odd reason, this needs to be anchored to topright for the fill flow to be correctly sized to the AABB of the sheared button
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Text = ModSelectOverlayStrings.UseCurrentMods,
DarkerColour = colours.Blue1,
LighterColour = colours.Blue0,
TextColour = colourProvider.Background6,
Action = useCurrentMods,
},
saveButton = new ShearedButton
saveButton = new ShearedButton(content_width)
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
// todo: for some very odd reason, this needs to be anchored to topright for the fill flow to be correctly sized to the AABB of the sheared button
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Text = Resources.Localisation.Web.CommonStrings.ButtonsSave,
DarkerColour = colours.Orange1,
LighterColour = colours.Orange0,
+2 -3
View File
@@ -243,11 +243,10 @@ namespace osu.Game.Overlays
{
RelativeSizeAxes = Axes.Both;
Padding = new MarginPadding { Right = OsuGame.SCREEN_EDGE_MARGIN };
InternalChild = NextButton = new ShearedButton(0)
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Margin = new MarginPadding { Right = 12f },
RelativeSizeAxes = Axes.X,
Width = 1,
Text = FirstRunSetupOverlayStrings.GetStarted,