1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 22:27:25 +08:00

Implement column display for new mod design

This commit is contained in:
Bartłomiej Dach 2022-02-19 17:52:16 +01:00
parent 6eb79c37d8
commit 2e04a83554
No known key found for this signature in database
GPG Key ID: BCECCD4FA41F6497
3 changed files with 246 additions and 2 deletions

View 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.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Overlays;
using osu.Game.Overlays.Mods;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Taiko;
namespace osu.Game.Tests.Visual.UserInterface
{
[TestFixture]
public class TestSceneModColumn : OsuTestScene
{
[Cached]
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green);
[TestCase(ModType.DifficultyReduction)]
[TestCase(ModType.DifficultyIncrease)]
[TestCase(ModType.Conversion)]
[TestCase(ModType.Automation)]
[TestCase(ModType.Fun)]
public void TestBasic(ModType modType)
{
AddStep("create content", () => Child = new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(30),
Child = new ModColumn(modType)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre
}
});
AddStep("change ruleset to osu!", () => Ruleset.Value = new OsuRuleset().RulesetInfo);
AddStep("change ruleset to taiko", () => Ruleset.Value = new TaikoRuleset().RulesetInfo);
AddStep("change ruleset to catch", () => Ruleset.Value = new CatchRuleset().RulesetInfo);
AddStep("change ruleset to mania", () => Ruleset.Value = new ManiaRuleset().RulesetInfo);
}
}
}

View File

@ -0,0 +1,196 @@
// 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.Collections.Generic;
using System.Linq;
using System.Threading;
using Humanizer;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Rulesets.Mods;
using osu.Game.Utils;
using osuTK;
#nullable enable
namespace osu.Game.Overlays.Mods
{
public class ModColumn : CompositeDrawable
{
private readonly ModType modType;
private readonly Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> availableMods = new Bindable<Dictionary<ModType, IReadOnlyList<Mod>>>();
private readonly TextFlowContainer headerText;
private readonly Box headerBackground;
private readonly Container contentContainer;
private readonly Box contentBackground;
private readonly FillFlowContainer<ModPanel> panelFlow;
private Colour4 accentColour;
private const float header_height = 60;
public ModColumn(ModType modType)
{
this.modType = modType;
Width = 450;
RelativeSizeAxes = Axes.Y;
Shear = new Vector2(ModPanel.SHEAR_X, 0);
CornerRadius = ModPanel.CORNER_RADIUS;
Masking = true;
InternalChildren = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.X,
Height = header_height + ModPanel.CORNER_RADIUS,
Children = new Drawable[]
{
headerBackground = new Box
{
RelativeSizeAxes = Axes.X,
Height = header_height + ModPanel.CORNER_RADIUS
},
headerText = new OsuTextFlowContainer(t =>
{
t.Font = OsuFont.TorusAlternate.With(size: 24);
t.Shadow = false;
t.Colour = Colour4.Black;
})
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Shear = new Vector2(-ModPanel.SHEAR_X, 0),
Padding = new MarginPadding
{
Horizontal = 15,
Bottom = ModPanel.CORNER_RADIUS
}
}
}
},
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Top = header_height },
Child = contentContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Masking = true,
CornerRadius = ModPanel.CORNER_RADIUS,
BorderThickness = 4,
Children = new Drawable[]
{
contentBackground = new Box
{
RelativeSizeAxes = Axes.Both
},
new GridContainer
{
RelativeSizeAxes = Axes.Both,
RowDimensions = new[]
{
new Dimension(GridSizeMode.Absolute, 50),
new Dimension(),
new Dimension(GridSizeMode.Absolute, 10)
},
Content = new[]
{
new[]
{
Empty()
},
new Drawable[]
{
new OsuScrollContainer
{
RelativeSizeAxes = Axes.Both,
ScrollbarOverlapsContent = false,
Child = panelFlow = new FillFlowContainer<ModPanel>
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(0, 10),
Padding = new MarginPadding
{
Horizontal = 10
},
}
}
},
new[] { Empty() }
}
}
}
}
}
};
createHeaderText();
}
private void createHeaderText()
{
IEnumerable<string> headerTextWords = modType.Humanize(LetterCasing.Title).Split(' ');
if (headerTextWords.Count() > 1)
{
headerText.AddText($"{headerTextWords.First()} ", t => t.Font = t.Font.With(weight: FontWeight.SemiBold));
headerTextWords = headerTextWords.Skip(1);
}
headerText.AddText(string.Join(' ', headerTextWords));
}
[BackgroundDependencyLoader]
private void load(OsuGameBase game, OverlayColourProvider colourProvider, OsuColour colours)
{
availableMods.BindTo(game.AvailableMods);
headerBackground.Colour = accentColour = colours.ForModType(modType);
contentContainer.BorderColour = ColourInfo.GradientVertical(colourProvider.Background4, colourProvider.Background3);
contentBackground.Colour = colourProvider.Background4;
}
protected override void LoadComplete()
{
base.LoadComplete();
availableMods.BindValueChanged(_ => Scheduler.AddOnce(updateMods), true);
}
private CancellationTokenSource? cancellationTokenSource;
private void updateMods()
{
var newMods = ModUtils.FlattenMods(availableMods.Value.GetValueOrDefault(modType) ?? Array.Empty<Mod>()).ToList();
if (newMods.SequenceEqual(panelFlow.Children.Select(p => p.Mod)))
return;
cancellationTokenSource?.Cancel();
var panels = newMods.Select(mod => new ModPanel(mod)
{
Shear = new Vector2(-ModPanel.SHEAR_X, 0)
});
LoadComponentsAsync(panels, loaded =>
{
panelFlow.ChildrenEnumerable = loaded;
}, (cancellationTokenSource = new CancellationTokenSource()).Token);
}
}
}

View File

@ -40,10 +40,10 @@ namespace osu.Game.Overlays.Mods
protected const double TRANSITION_DURATION = 150; protected const double TRANSITION_DURATION = 150;
protected const float SHEAR_X = 0.2f; public const float SHEAR_X = 0.2f;
public const float CORNER_RADIUS = 7;
protected const float HEIGHT = 42; protected const float HEIGHT = 42;
protected const float CORNER_RADIUS = 7;
protected const float IDLE_SWITCH_WIDTH = 54; protected const float IDLE_SWITCH_WIDTH = 54;
protected const float EXPANDED_SWITCH_WIDTH = 70; protected const float EXPANDED_SWITCH_WIDTH = 70;