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:
@@ -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[]
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 = "+";
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user