From 44727eb2b831c51cb339ed1ca1c2dfd96387fbb4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 30 Mar 2020 23:14:30 +0900 Subject: [PATCH] Implement column background skinning --- .../Skinning/TestSceneColumnBackground.cs | 49 +++++++ osu.Game.Rulesets.Mania/ManiaSkinComponent.cs | 1 + .../Skinning/LegacyColumnBackground.cs | 133 ++++++++++++++++++ .../Skinning/ManiaLegacySkinTransformer.cs | 8 +- osu.Game.Rulesets.Mania/UI/Column.cs | 8 +- .../UI/Components/DefaultColumnBackground.cs | 90 ++++++++++++ .../LegacyManiaSkinConfigurationLookup.cs | 3 + 7 files changed, 288 insertions(+), 4 deletions(-) create mode 100644 osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs create mode 100644 osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs create mode 100644 osu.Game.Rulesets.Mania/UI/Components/DefaultColumnBackground.cs diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs new file mode 100644 index 0000000000..ca323b5911 --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs @@ -0,0 +1,49 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Mania.UI.Components; +using osu.Game.Skinning; +using osuTK; + +namespace osu.Game.Rulesets.Mania.Tests.Skinning +{ + public class TestSceneColumnBackground : ManiaSkinnableTestScene + { + [BackgroundDependencyLoader] + private void load() + { + SetContents(() => new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Size = new Vector2(0.8f), + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + new ColumnTestContainer(0, ManiaAction.Key1) + { + RelativeSizeAxes = Axes.Both, + Width = 0.5f, + Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) + { + RelativeSizeAxes = Axes.Both + } + }, + new ColumnTestContainer(1, ManiaAction.Key2) + { + RelativeSizeAxes = Axes.Both, + Width = 0.5f, + Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) + { + RelativeSizeAxes = Axes.Both + } + } + } + }); + } + } +} diff --git a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs b/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs index 5340ebc01f..ca932c5319 100644 --- a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs +++ b/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs @@ -19,5 +19,6 @@ namespace osu.Game.Rulesets.Mania public enum ManiaSkinComponents { + ColumnBackground } } diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs new file mode 100644 index 0000000000..96b28964d3 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyColumnBackground.cs @@ -0,0 +1,133 @@ +// Copyright (c) ppy Pty Ltd . 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Bindings; +using osu.Game.Rulesets.Mania.UI; +using osu.Game.Rulesets.UI.Scrolling; +using osu.Game.Skinning; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Mania.Skinning +{ + public class LegacyColumnBackground : CompositeDrawable, IKeyBindingHandler + { + private readonly IBindable direction = new Bindable(); + + private Container lightContainer; + private Sprite light; + + [Resolved] + private Column column { get; set; } + + [Resolved(CanBeNull = true)] + private ManiaStage stage { get; set; } + + public LegacyColumnBackground() + { + RelativeSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load(ISkinSource skin, IScrollingInfo scrollingInfo) + { + string lightImage = skin.GetConfig( + new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.LightImage, 0))?.Value + ?? "mania-stage-light"; + + float leftLineWidth = skin.GetConfig( + new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.LeftLineWidth, column.Index)) + ?.Value ?? 1; + float rightLineWidth = skin.GetConfig( + new LegacyManiaSkinConfigurationLookup(stage?.Columns.Count ?? 4, LegacyManiaSkinConfigurationLookups.RightLineWidth, column.Index)) + ?.Value ?? 1; + + bool hasLeftLine = leftLineWidth > 0; + bool hasRightLine = rightLineWidth > 0 && skin.GetConfig(LegacySkinConfiguration.LegacySetting.Version)?.Value >= 2.4m + || stage == null || column.Index == stage.Columns.Count - 1; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black + }, + new Box + { + RelativeSizeAxes = Axes.Y, + Width = leftLineWidth, + Alpha = hasLeftLine ? 1 : 0 + }, + new Box + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + RelativeSizeAxes = Axes.Y, + Width = rightLineWidth, + Alpha = hasRightLine ? 1 : 0 + }, + lightContainer = new Container + { + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.Both, + Child = light = new Sprite + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Texture = skin.GetTexture(lightImage), + RelativeSizeAxes = Axes.X, + Width = 1, + Alpha = 0 + } + } + }; + + direction.BindTo(scrollingInfo.Direction); + direction.BindValueChanged(onDirectionChanged, true); + } + + private void onDirectionChanged(ValueChangedEvent direction) + { + if (direction.NewValue == ScrollingDirection.Up) + { + lightContainer.Anchor = Anchor.TopCentre; + lightContainer.Scale = new Vector2(1, -1); + } + else + { + lightContainer.Anchor = Anchor.BottomCentre; + lightContainer.Scale = Vector2.One; + } + } + + public bool OnPressed(ManiaAction action) + { + if (action == column.Action.Value) + { + light.FadeIn(); + light.ScaleTo(Vector2.One); + } + + return false; + } + + public void OnReleased(ManiaAction action) + { + // Todo: Should be 400 * 100 / CurrentBPM + const double animation_length = 250; + + if (action == column.Action.Value) + { + light.FadeTo(0, animation_length); + light.ScaleTo(new Vector2(1, 0), animation_length); + } + } + } +} diff --git a/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs index ffc69fae49..12145975f1 100644 --- a/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs @@ -38,10 +38,16 @@ namespace osu.Game.Rulesets.Mania.Skinning case GameplaySkinComponent resultComponent: return getResult(resultComponent); - case ManiaSkinComponent _: + case ManiaSkinComponent maniaComponent: if (!isLegacySkin.Value) return null; + switch (maniaComponent.Component) + { + case ManiaSkinComponents.ColumnBackground: + return new LegacyColumnBackground(); + } + break; } diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 0eccd27944..70e2782a7b 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -15,6 +15,7 @@ using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; using osu.Game.Rulesets.Mania.UI.Components; using osu.Game.Rulesets.UI.Scrolling; +using osu.Game.Skinning; using osuTK; namespace osu.Game.Rulesets.Mania.UI @@ -32,7 +33,6 @@ namespace osu.Game.Rulesets.Mania.UI public readonly Bindable Action = new Bindable(); - private readonly ColumnBackground background; private readonly ColumnKeyArea keyArea; private readonly ColumnHitObjectArea hitObjectArea; @@ -46,7 +46,10 @@ namespace osu.Game.Rulesets.Mania.UI RelativeSizeAxes = Axes.Y; Width = COLUMN_WIDTH; - background = new ColumnBackground { RelativeSizeAxes = Axes.Both }; + Drawable background = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) + { + RelativeSizeAxes = Axes.Both + }; Container hitTargetContainer; @@ -130,7 +133,6 @@ namespace osu.Game.Rulesets.Mania.UI accentColour = value; - background.AccentColour = value; keyArea.AccentColour = value; hitObjectArea.AccentColour = value; } diff --git a/osu.Game.Rulesets.Mania/UI/Components/DefaultColumnBackground.cs b/osu.Game.Rulesets.Mania/UI/Components/DefaultColumnBackground.cs new file mode 100644 index 0000000000..4b4bc157d5 --- /dev/null +++ b/osu.Game.Rulesets.Mania/UI/Components/DefaultColumnBackground.cs @@ -0,0 +1,90 @@ +// Copyright (c) ppy Pty Ltd . 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.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input.Bindings; +using osu.Game.Rulesets.UI.Scrolling; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Mania.UI.Components +{ + public class DefaultColumnBackground : CompositeDrawable, IKeyBindingHandler + { + private readonly IBindable direction = new Bindable(); + + private Color4 brightColour; + private Color4 dimColour; + + private Box background; + private Box backgroundOverlay; + + [Resolved] + private Column column { get; set; } + + public DefaultColumnBackground() + { + RelativeSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load(IScrollingInfo scrollingInfo) + { + InternalChildren = new[] + { + background = new Box + { + Name = "Background", + RelativeSizeAxes = Axes.Both, + }, + backgroundOverlay = new Box + { + Name = "Background Gradient Overlay", + RelativeSizeAxes = Axes.Both, + Height = 0.5f, + Blending = BlendingParameters.Additive, + Alpha = 0 + } + }; + + background.Colour = column.AccentColour.Darken(5); + brightColour = column.AccentColour.Opacity(0.6f); + dimColour = column.AccentColour.Opacity(0); + + direction.BindTo(scrollingInfo.Direction); + direction.BindValueChanged(onDirectionChanged, true); + } + + private void onDirectionChanged(ValueChangedEvent direction) + { + if (direction.NewValue == ScrollingDirection.Up) + { + backgroundOverlay.Anchor = backgroundOverlay.Origin = Anchor.TopLeft; + backgroundOverlay.Colour = ColourInfo.GradientVertical(brightColour, dimColour); + } + else + { + backgroundOverlay.Anchor = backgroundOverlay.Origin = Anchor.BottomLeft; + backgroundOverlay.Colour = ColourInfo.GradientVertical(dimColour, brightColour); + } + } + + public bool OnPressed(ManiaAction action) + { + if (action == column.Action.Value) + backgroundOverlay.FadeTo(1, 50, Easing.OutQuint).Then().FadeTo(0.5f, 250, Easing.OutQuint); + return false; + } + + public void OnReleased(ManiaAction action) + { + if (action == column.Action.Value) + backgroundOverlay.FadeTo(0, 250, Easing.OutQuint); + } + } +} diff --git a/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs b/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs index bbdd445f66..9e83217afc 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfigurationLookup.cs @@ -19,5 +19,8 @@ namespace osu.Game.Skinning public enum LegacyManiaSkinConfigurationLookups { + LightImage, + LeftLineWidth, + RightLineWidth } }