From 7c2884700eaffe391e37fa79a80deb3a30a431aa Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Dec 2019 19:29:27 +0900 Subject: [PATCH] Fix various display issues by abstracting further --- osu.Game.Rulesets.Osu/Mods/OsuModTraceable.cs | 5 +- .../Objects/Drawables/DrawableRepeatPoint.cs | 3 +- .../Objects/Drawables/DrawableSlider.cs | 52 +++++------------ .../Drawables/Pieces/PlaySliderBody.cs | 57 +++++++++++++++++++ .../Objects/Drawables/Pieces/SliderBody.cs | 2 +- .../Skinning/LegacySliderBody.cs | 2 +- 6 files changed, 78 insertions(+), 43 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/PlaySliderBody.cs diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTraceable.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTraceable.cs index 7e20feba02..0cca3ae40c 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModTraceable.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModTraceable.cs @@ -11,6 +11,7 @@ using osu.Game.Configuration; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; namespace osu.Game.Rulesets.Osu.Mods { @@ -57,8 +58,8 @@ namespace osu.Game.Rulesets.Osu.Mods slider.AccentColour.BindValueChanged(_ => { //will trigger on skin change. - slider.Body.AccentColour = slider.AccentColour.Value.Opacity(0); - slider.Body.BorderColour = slider.AccentColour.Value; + ((PlaySliderBody)slider.Body.Drawable).AccentColour = slider.AccentColour.Value.Opacity(0); + ((PlaySliderBody)slider.Body.Drawable).BorderColour = slider.AccentColour.Value; }, true); break; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs index 71cb9a9691..b81d94a673 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.MathUtils; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; using osu.Game.Rulesets.Scoring; using osuTK; using osu.Game.Skinning; @@ -98,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public void UpdateSnakingPosition(Vector2 start, Vector2 end) { bool isRepeatAtEnd = repeatPoint.RepeatIndex % 2 == 0; - List curve = drawableSlider.Body.CurrentCurve; + List curve = ((PlaySliderBody)drawableSlider.Body.Drawable).CurrentCurve; Position = isRepeatAtEnd ? end : start; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 46a219a69c..03183beff1 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -11,7 +11,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.Osu.Skinning; using osu.Game.Rulesets.Scoring; using osuTK.Graphics; @@ -25,10 +24,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public DrawableSliderTail TailCircle => tailContainer.Child; public readonly SliderBall Ball; + public readonly SkinnableDrawable Body; - public SnakingSliderBody Body => (SnakingSliderBody)skinnedBody.Drawable; + private PlaySliderBody sliderBody => (PlaySliderBody)Body.Drawable; - private readonly SkinnableDrawable skinnedBody; private readonly Container headContainer; private readonly Container tailContainer; private readonly Container tickContainer; @@ -39,10 +38,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly IBindable positionBindable = new Bindable(); private readonly IBindable stackHeightBindable = new Bindable(); private readonly IBindable scaleBindable = new Bindable(); - private readonly IBindable pathVersion = new Bindable(); - - [Resolved(CanBeNull = true)] - private OsuRulesetConfigManager config { get; set; } public DrawableSlider(Slider s) : base(s) @@ -53,7 +48,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables InternalChildren = new Drawable[] { - skinnedBody = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderBody), _ => new SnakingSliderBody(), confineMode: ConfineMode.NoScaling), + Body = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderBody), _ => new DefaultSliderBody(), confineMode: ConfineMode.NoScaling), tickContainer = new Container { RelativeSizeAxes = Axes.Both }, repeatContainer = new Container { RelativeSizeAxes = Axes.Both }, Ball = new SliderBall(s, this) @@ -72,28 +67,16 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables [BackgroundDependencyLoader] private void load() { - config?.BindWith(OsuRulesetSetting.SnakingInSliders, Body.SnakingIn); - config?.BindWith(OsuRulesetSetting.SnakingOutSliders, Body.SnakingOut); - positionBindable.BindValueChanged(_ => Position = HitObject.StackedPosition); stackHeightBindable.BindValueChanged(_ => Position = HitObject.StackedPosition); - scaleBindable.BindValueChanged(scale => - { - updatePathRadius(); - Ball.Scale = new Vector2(scale.NewValue); - }); + scaleBindable.BindValueChanged(scale => Ball.Scale = new Vector2(scale.NewValue)); positionBindable.BindTo(HitObject.PositionBindable); stackHeightBindable.BindTo(HitObject.StackHeightBindable); scaleBindable.BindTo(HitObject.ScaleBindable); - pathVersion.BindTo(slider.Path.Version); - - pathVersion.BindValueChanged(_ => Body.Refresh()); AccentColour.BindValueChanged(colour => { - Body.AccentColour = colour.NewValue; - foreach (var drawableHitObject in NestedHitObjects) drawableHitObject.AccentColour.Value = colour.NewValue; }, true); @@ -171,16 +154,16 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables double completionProgress = Math.Clamp((Time.Current - slider.StartTime) / slider.Duration, 0, 1); Ball.UpdateProgress(completionProgress); - Body.UpdateProgress(completionProgress); + sliderBody.UpdateProgress(completionProgress); foreach (DrawableHitObject hitObject in NestedHitObjects) { - if (hitObject is ITrackSnaking s) s.UpdateSnakingPosition(slider.Path.PositionAt(Body.SnakedStart ?? 0), slider.Path.PositionAt(Body.SnakedEnd ?? 0)); + if (hitObject is ITrackSnaking s) s.UpdateSnakingPosition(slider.Path.PositionAt(sliderBody.SnakedStart ?? 0), slider.Path.PositionAt(sliderBody.SnakedEnd ?? 0)); if (hitObject is IRequireTracking t) t.Tracking = Ball.Tracking; } - Size = Body.Size; - OriginPosition = Body.PathOffset; + Size = sliderBody.Size; + OriginPosition = sliderBody.PathOffset; if (DrawSize != Vector2.Zero) { @@ -194,28 +177,17 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public override void OnKilled() { base.OnKilled(); - Body.RecyclePath(); + sliderBody.RecyclePath(); } - private float sliderPathRadius; - protected override void ApplySkin(ISkinSource skin, bool allowFallback) { base.ApplySkin(skin, allowFallback); - Body.BorderSize = skin.GetConfig(OsuSkinConfiguration.SliderBorderSize)?.Value ?? 1; - sliderPathRadius = skin.GetConfig(OsuSkinConfiguration.SliderPathRadius)?.Value ?? OsuHitObject.OBJECT_RADIUS; - updatePathRadius(); - - Body.AccentColour = skin.GetConfig(OsuSkinColour.SliderTrackOverride)?.Value ?? AccentColour.Value; - Body.BorderColour = skin.GetConfig(OsuSkinColour.SliderBorder)?.Value ?? Color4.White; - bool allowBallTint = skin.GetConfig(OsuSkinConfiguration.AllowSliderBallTint)?.Value ?? false; Ball.Colour = allowBallTint ? AccentColour.Value : Color4.White; } - private void updatePathRadius() => Body.PathRadius = slider.Scale * sliderPathRadius; - protected override void CheckForResult(bool userTriggered, double timeOffset) { if (userTriggered || Time.Current < slider.EndTime) @@ -266,6 +238,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public Drawable ProxiedLayer => HeadCircle.ProxiedLayer; - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Body.ReceivePositionalInputAt(screenSpacePos); + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => sliderBody.ReceivePositionalInputAt(screenSpacePos); + + private class DefaultSliderBody : PlaySliderBody + { + } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/PlaySliderBody.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/PlaySliderBody.cs new file mode 100644 index 0000000000..aa9caf193e --- /dev/null +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/PlaySliderBody.cs @@ -0,0 +1,57 @@ +// 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.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Osu.Configuration; +using osu.Game.Rulesets.Osu.Skinning; +using osu.Game.Skinning; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces +{ + public abstract class PlaySliderBody : SnakingSliderBody + { + private IBindable scaleBindable; + private IBindable pathVersion; + private IBindable accentColour; + + [Resolved] + private DrawableHitObject drawableObject { get; set; } + + [Resolved(CanBeNull = true)] + private OsuRulesetConfigManager config { get; set; } + + private Slider slider; + private float defaultPathRadius; + + [BackgroundDependencyLoader] + private void load(ISkinSource skin) + { + slider = (Slider)drawableObject.HitObject; + defaultPathRadius = skin.GetConfig(OsuSkinConfiguration.SliderPathRadius)?.Value ?? OsuHitObject.OBJECT_RADIUS; + + scaleBindable = slider.ScaleBindable.GetBoundCopy(); + scaleBindable.BindValueChanged(_ => updatePathRadius(), true); + + pathVersion = slider.Path.Version.GetBoundCopy(); + pathVersion.BindValueChanged(_ => Refresh()); + + accentColour = drawableObject.AccentColour.GetBoundCopy(); + accentColour.BindValueChanged(accent => updateAccentColour(skin, accent.NewValue), true); + + config?.BindWith(OsuRulesetSetting.SnakingInSliders, SnakingIn); + config?.BindWith(OsuRulesetSetting.SnakingOutSliders, SnakingOut); + + BorderSize = skin.GetConfig(OsuSkinConfiguration.SliderBorderSize)?.Value ?? 1; + BorderColour = skin.GetConfig(OsuSkinColour.SliderBorder)?.Value ?? Color4.White; + } + + private void updatePathRadius() + => PathRadius = defaultPathRadius * scaleBindable.Value; + + private void updateAccentColour(ISkinSource skin, Color4 defaultAccentColour) + => AccentColour = skin.GetConfig(OsuSkinColour.SliderTrackOverride)?.Value ?? defaultAccentColour; + } +} diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs index dcaa9748e9..8758a4a066 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs @@ -104,7 +104,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces protected virtual DrawableSliderPath CreateSliderPath() => new DefaultDrawableSliderPath(); - protected class DefaultDrawableSliderPath : DrawableSliderPath + private class DefaultDrawableSliderPath : DrawableSliderPath { private const float opacity_at_centre = 0.3f; private const float opacity_at_edge = 0.8f; diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs index 6a26529f4c..18a5d7a320 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacySliderBody.cs @@ -9,7 +9,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning { - public class LegacySliderBody : SnakingSliderBody + public class LegacySliderBody : PlaySliderBody { protected override DrawableSliderPath CreateSliderPath() => new LegacyDrawableSliderPath();