Fix slider ball sizing when legacy skin falls back to default

This commit is contained in:
Dean Herbert 2019-07-25 15:35:51 +09:00
parent 73d79c2469
commit 6cc6aff66e
2 changed files with 76 additions and 56 deletions

View File

@ -115,7 +115,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
AccentColour.BindValueChanged(colour =>
{
Body.AccentColour = colour.NewValue;
Ball.AccentColour = colour.NewValue;
foreach (var drawableHitObject in NestedHitObjects)
drawableHitObject.AccentColour.Value = colour.NewValue;
@ -166,7 +165,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Body.AccentColour = skin.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.ContainsKey("SliderTrackOverride") ? s.CustomColours["SliderTrackOverride"] : (Color4?)null) ?? AccentColour.Value;
Body.BorderColour = skin.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.ContainsKey("SliderBorder") ? s.CustomColours["SliderBorder"] : (Color4?)null) ?? Color4.White;
Ball.AccentColour = skin.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? AccentColour.Value;
}
private void updatePathRadius() => Body.PathRadius = slider.Scale * sliderPathRadius;

View File

@ -3,11 +3,14 @@
using System;
using System.Linq;
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.Input;
using osu.Framework.Input.Events;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types;
using osuTK.Graphics;
using osu.Game.Skinning;
@ -17,88 +20,44 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class SliderBall : CircularContainer, ISliderProgress, IRequireHighFrequencyMousePosition
{
private Color4 accentColour = Color4.Black;
public Func<OsuAction?> GetInitialHitAction;
/// <summary>
/// The colour that is used for the slider ball.
/// </summary>
public Color4 AccentColour
{
get => accentColour;
set
{
accentColour = value;
if (drawableBall != null)
drawableBall.Colour = value;
}
}
private readonly Slider slider;
public readonly Drawable FollowCircle;
private Drawable drawableBall;
private readonly DrawableSlider drawableSlider;
public SliderBall(Slider slider, DrawableSlider drawableSlider = null)
{
this.drawableSlider = drawableSlider;
this.slider = slider;
Masking = true;
AutoSizeAxes = Axes.Both;
Blending = BlendingMode.Additive;
Origin = Anchor.Centre;
Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2);
Children = new[]
{
FollowCircle = new Container
FollowCircle = new FollowCircleContainer
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Width = OsuHitObject.OBJECT_RADIUS * 2,
Height = OsuHitObject.OBJECT_RADIUS * 2,
RelativeSizeAxes = Axes.Both,
Alpha = 0,
Child = new SkinnableDrawable("Play/osu/sliderfollowcircle", _ => new CircularContainer
{
RelativeSizeAxes = Axes.Both,
Masking = true,
BorderThickness = 5,
BorderColour = Color4.Orange,
Blending = BlendingMode.Additive,
Child = new Box
{
Colour = Color4.Orange,
RelativeSizeAxes = Axes.Both,
Alpha = 0.2f,
}
}),
Child = new SkinnableDrawable("Play/osu/sliderfollowcircle", _ => new DefaultFollowCircle()),
},
new CircularContainer
{
Masking = true,
AutoSizeAxes = Axes.Both,
RelativeSizeAxes = Axes.Both,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Alpha = 1,
Child = new Container
{
Width = OsuHitObject.OBJECT_RADIUS * 2,
Height = OsuHitObject.OBJECT_RADIUS * 2,
RelativeSizeAxes = Axes.Both,
// TODO: support skin filename animation (sliderb0, sliderb1...)
Child = new SkinnableDrawable("Play/osu/sliderb", _ => new CircularContainer
{
Masking = true,
RelativeSizeAxes = Axes.Both,
BorderThickness = 10,
BorderColour = Color4.White,
Alpha = 1,
Child = drawableBall = new Box
{
Colour = AccentColour,
RelativeSizeAxes = Axes.Both,
Alpha = 0.4f,
}
}),
Child = new SkinnableDrawable("Play/osu/sliderb", _ => new DefaultSliderBall()),
}
}
};
@ -191,7 +150,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
// in valid time range
Time.Current >= slider.StartTime && Time.Current < slider.EndTime &&
// in valid position range
lastScreenSpaceMousePosition.HasValue && base.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) &&
lastScreenSpaceMousePosition.HasValue && FollowCircle.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) &&
// valid action
(actions?.Any(isValidTrackingAction) ?? false);
}
@ -214,5 +173,68 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
Position = slider.CurvePositionAt(completionProgress);
}
private class FollowCircleContainer : Container
{
public override bool HandlePositionalInput => true;
}
public class DefaultFollowCircle : CompositeDrawable
{
public DefaultFollowCircle()
{
RelativeSizeAxes = Axes.Both;
InternalChild = new CircularContainer
{
RelativeSizeAxes = Axes.Both,
Masking = true,
BorderThickness = 5,
BorderColour = Color4.Orange,
Blending = BlendingMode.Additive,
Child = new Box
{
Colour = Color4.Orange,
RelativeSizeAxes = Axes.Both,
Alpha = 0.2f,
}
};
}
}
public class DefaultSliderBall : CompositeDrawable
{
private readonly Bindable<Color4> accentColour = new Bindable<Color4>();
private Drawable drawableBall;
[BackgroundDependencyLoader]
private void load(DrawableHitObject drawableObject, ISkinSource skin)
{
RelativeSizeAxes = Axes.Both;
float radius = skin.GetValue<SkinConfiguration, float?>(s => s.SliderPathRadius) ?? OsuHitObject.OBJECT_RADIUS;
InternalChild = new CircularContainer
{
Masking = true,
RelativeSizeAxes = Axes.Both,
Scale = new Vector2(radius / OsuHitObject.OBJECT_RADIUS),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
BorderThickness = 10,
BorderColour = Color4.White,
Alpha = 1,
Child = drawableBall = new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0.4f,
}
};
accentColour.BindTo(drawableObject.AccentColour);
accentColour.BindValueChanged(colour => drawableBall.Colour = colour.NewValue, true);
}
}
}
}