mirror of
https://github.com/ppy/osu
synced 2024-12-26 08:53:10 +00:00
Replace abstract class with interface, attached to the actual components (not skinnable wrapper)
This commit is contained in:
parent
defa350aa7
commit
fd587a82ff
@ -9,16 +9,12 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osuTK.Graphics;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
@ -78,29 +74,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddAssert("key counter flow not affected", () => keyCounterFlow.IsPresent);
|
||||
}
|
||||
|
||||
private IReadOnlyList<Drawable> createSkinSourceComponents()
|
||||
{
|
||||
Drawable[] hudComponents = typeof(SkinnableHUDComponent).Assembly
|
||||
.GetTypes()
|
||||
.Where(t => typeof(SkinnableHUDComponent).IsAssignableFrom(t))
|
||||
.Where(t => !t.IsAbstract)
|
||||
.Select(t => Activator.CreateInstance(t) as Drawable)
|
||||
.ToArray();
|
||||
|
||||
List<Drawable> drawables = new List<Drawable>();
|
||||
|
||||
foreach (var component in hudComponents)
|
||||
{
|
||||
drawables.Add(new OsuSpriteText
|
||||
{
|
||||
Text = component.GetType().Name
|
||||
});
|
||||
drawables.AddRange(component.CreateSettingsControls());
|
||||
}
|
||||
|
||||
return drawables;
|
||||
}
|
||||
|
||||
private void createNew(Action<HUDOverlay> action = null)
|
||||
{
|
||||
AddStep("create overlay", () =>
|
||||
|
@ -9,7 +9,7 @@ using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
public class DefaultAccuracyCounter : PercentageCounter, IAccuracyCounter
|
||||
public class DefaultAccuracyCounter : PercentageCounter, IAccuracyCounter, ISkinnableComponent
|
||||
{
|
||||
private readonly Vector2 offset = new Vector2(-20, 5);
|
||||
|
||||
|
@ -11,7 +11,7 @@ using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
public class DefaultComboCounter : RollingCounter<int>, IComboCounter
|
||||
public class DefaultComboCounter : RollingCounter<int>, IComboCounter, ISkinnableComponent
|
||||
{
|
||||
private readonly Vector2 offset = new Vector2(20, 5);
|
||||
|
||||
|
@ -16,7 +16,7 @@ using osu.Framework.Utils;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
public class DefaultHealthDisplay : HealthDisplay, IHasAccentColour
|
||||
public class DefaultHealthDisplay : HealthDisplay, IHasAccentColour, ISkinnableComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// The base opacity of the glow.
|
||||
|
@ -8,7 +8,7 @@ using osu.Game.Graphics.UserInterface;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
public class DefaultScoreCounter : ScoreCounter
|
||||
public class DefaultScoreCounter : ScoreCounter, ISkinnableComponent
|
||||
{
|
||||
public DefaultScoreCounter()
|
||||
: base(6)
|
||||
|
@ -18,7 +18,7 @@ using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD.HitErrorMeters
|
||||
{
|
||||
public class BarHitErrorMeter : HitErrorMeter
|
||||
public class BarHitErrorMeter : HitErrorMeter, ISkinnableComponent
|
||||
{
|
||||
private readonly Anchor alignment;
|
||||
|
||||
|
14
osu.Game/Screens/Play/HUD/ISkinnableComponent.cs
Normal file
14
osu.Game/Screens/Play/HUD/ISkinnableComponent.cs
Normal file
@ -0,0 +1,14 @@
|
||||
// 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 osu.Framework.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
/// <summary>
|
||||
/// Denotes a drawable which, as a drawable, can be adjusted via skinning specifications.
|
||||
/// </summary>
|
||||
public interface ISkinnableComponent : IDrawable
|
||||
{
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ namespace osu.Game.Screens.Play.HUD
|
||||
/// <summary>
|
||||
/// Uses the 'x' symbol and has a pop-out effect while rolling over.
|
||||
/// </summary>
|
||||
public class LegacyComboCounter : CompositeDrawable, IComboCounter
|
||||
public class LegacyComboCounter : CompositeDrawable, IComboCounter, ISkinnableComponent
|
||||
{
|
||||
public Bindable<int> Current { get; } = new BindableInt { MinValue = 0, };
|
||||
|
||||
|
@ -2,12 +2,11 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
public class SkinnableAccuracyCounter : SkinnableHUDComponent, IAccuracyCounter
|
||||
public class SkinnableAccuracyCounter : SkinnableDrawable, IAccuracyCounter
|
||||
{
|
||||
public Bindable<double> Current { get; } = new Bindable<double>();
|
||||
|
||||
@ -15,7 +14,6 @@ namespace osu.Game.Screens.Play.HUD
|
||||
: base(new HUDSkinComponent(HUDSkinComponents.AccuracyCounter), _ => new DefaultAccuracyCounter())
|
||||
{
|
||||
CentreComponent = false;
|
||||
AutoSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
private IAccuracyCounter skinnedCounter;
|
||||
|
@ -2,12 +2,11 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
public class SkinnableComboCounter : SkinnableHUDComponent, IComboCounter
|
||||
public class SkinnableComboCounter : SkinnableDrawable, IComboCounter
|
||||
{
|
||||
public Bindable<int> Current { get; } = new Bindable<int>();
|
||||
|
||||
@ -15,7 +14,6 @@ namespace osu.Game.Screens.Play.HUD
|
||||
: base(new HUDSkinComponent(HUDSkinComponents.ComboCounter), skinComponent => new DefaultComboCounter())
|
||||
{
|
||||
CentreComponent = false;
|
||||
AutoSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
private IComboCounter skinnedCounter;
|
||||
|
@ -1,68 +0,0 @@
|
||||
// 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 osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Layout;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
/// <summary>
|
||||
/// A skinnable HUD component which can be scaled and repositioned at a skinner/user's will.
|
||||
/// </summary>
|
||||
public abstract class SkinnableHUDComponent : SkinnableDrawable
|
||||
{
|
||||
[SettingSource("ScaleX", "The horizontal scale at which this component should be displayed.")]
|
||||
public BindableNumber<float> SkinScaleX { get; } = new BindableFloat(1);
|
||||
|
||||
[SettingSource("ScaleY", "The vertical scale at which this component should be displayed.")]
|
||||
public BindableNumber<float> SkinScaleY { get; } = new BindableFloat(1);
|
||||
|
||||
[SettingSource("PositionX", "The horizontal position at which this component should be displayed.")]
|
||||
public BindableNumber<float> SkinPositionX { get; } = new BindableFloat();
|
||||
|
||||
[SettingSource("PositionY", "The vertical position at which this component should be displayed.")]
|
||||
public BindableNumber<float> SkinPositionY { get; } = new BindableFloat();
|
||||
|
||||
[SettingSource("Rotation", "The rotation at which this component should be displayed.")]
|
||||
public BindableNumber<float> SkinRotation { get; } = new BindableFloat();
|
||||
|
||||
[SettingSource("Anchor", "The screen edge this component should align to.")]
|
||||
public Bindable<Anchor> SkinAnchor { get; } = new Bindable<Anchor>();
|
||||
|
||||
protected SkinnableHUDComponent(ISkinComponent component, Func<ISkinComponent, Drawable> defaultImplementation, Func<ISkinSource, bool> allowFallback = null, ConfineMode confineMode = ConfineMode.NoScaling)
|
||||
: base(component, defaultImplementation, allowFallback, confineMode)
|
||||
{
|
||||
SkinScaleX.BindValueChanged(x => Scale = new Vector2(x.NewValue, Scale.Y));
|
||||
SkinScaleY.BindValueChanged(y => Scale = new Vector2(Scale.X, y.NewValue));
|
||||
|
||||
SkinPositionX.BindValueChanged(x => Position = new Vector2(x.NewValue, Position.Y));
|
||||
SkinPositionY.BindValueChanged(y => Position = new Vector2(Position.X, y.NewValue));
|
||||
|
||||
SkinRotation.BindValueChanged(rotation => Rotation = rotation.NewValue);
|
||||
SkinAnchor.BindValueChanged(anchor => { Anchor = anchor.NewValue; });
|
||||
|
||||
// reset everything and require each component to specify what they want,
|
||||
// as if they were just drawables. maybe we want to change SkinnableDrawable to not default
|
||||
// to RelativeSizeAxes.Both...
|
||||
RelativeSizeAxes = Axes.None;
|
||||
AutoSizeAxes = Axes.None;
|
||||
}
|
||||
|
||||
protected override bool OnInvalidate(Invalidation invalidation, InvalidationSource source)
|
||||
{
|
||||
SkinScaleX.Value = Scale.X;
|
||||
SkinScaleY.Value = Scale.Y;
|
||||
SkinPositionX.Value = Position.X;
|
||||
SkinPositionY.Value = Position.Y;
|
||||
SkinRotation.Value = Rotation;
|
||||
SkinAnchor.Value = Anchor;
|
||||
|
||||
return base.OnInvalidate(invalidation, source);
|
||||
}
|
||||
}
|
||||
}
|
@ -3,14 +3,13 @@
|
||||
|
||||
using System;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
public class SkinnableHealthDisplay : SkinnableHUDComponent, IHealthDisplay
|
||||
public class SkinnableHealthDisplay : SkinnableDrawable, IHealthDisplay
|
||||
{
|
||||
public Bindable<double> Current { get; } = new BindableDouble(1)
|
||||
{
|
||||
@ -36,8 +35,6 @@ namespace osu.Game.Screens.Play.HUD
|
||||
: base(new HUDSkinComponent(HUDSkinComponents.HealthDisplay), _ => new DefaultHealthDisplay())
|
||||
{
|
||||
CentreComponent = false;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
}
|
||||
|
||||
private IHealthDisplay skinnedCounter;
|
||||
|
@ -4,14 +4,13 @@
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD
|
||||
{
|
||||
public class SkinnableScoreCounter : SkinnableHUDComponent, IScoreCounter
|
||||
public class SkinnableScoreCounter : SkinnableDrawable, IScoreCounter
|
||||
{
|
||||
public Bindable<double> Current { get; } = new Bindable<double>();
|
||||
|
||||
@ -23,7 +22,6 @@ namespace osu.Game.Screens.Play.HUD
|
||||
: base(new HUDSkinComponent(HUDSkinComponents.ScoreCounter), _ => new DefaultScoreCounter())
|
||||
{
|
||||
CentreComponent = false;
|
||||
AutoSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
|
@ -15,24 +15,25 @@ using osuTK;
|
||||
|
||||
namespace osu.Game.Skinning.Editor
|
||||
{
|
||||
public class SkinBlueprint : SelectionBlueprint<SkinnableHUDComponent>
|
||||
public class SkinBlueprint : SelectionBlueprint<ISkinnableComponent>
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="DrawableHitObject"/> which this <see cref="OverlaySelectionBlueprint"/> applies to.
|
||||
/// </summary>
|
||||
public readonly SkinnableHUDComponent Component;
|
||||
public readonly ISkinnableComponent Component;
|
||||
|
||||
private Container box;
|
||||
private Drawable drawable => Component.Drawable;
|
||||
|
||||
private Drawable drawable => (Drawable)Component;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the blueprint should be shown even when the <see cref="Component"/> is not alive.
|
||||
/// </summary>
|
||||
protected virtual bool AlwaysShowWhenSelected => false;
|
||||
|
||||
protected override bool ShouldBeAlive => (Component.IsAlive && Component.IsPresent) || (AlwaysShowWhenSelected && State == SelectionState.Selected);
|
||||
protected override bool ShouldBeAlive => (drawable.IsAlive && Component.IsPresent) || (AlwaysShowWhenSelected && State == SelectionState.Selected);
|
||||
|
||||
public SkinBlueprint(SkinnableHUDComponent component)
|
||||
public SkinBlueprint(ISkinnableComponent component)
|
||||
: base(component)
|
||||
{
|
||||
Component = component;
|
||||
@ -72,15 +73,15 @@ namespace osu.Game.Skinning.Editor
|
||||
|
||||
box.Position = quad.TopLeft;
|
||||
box.Size = quad.Size;
|
||||
box.Rotation = Component.Rotation;
|
||||
box.Rotation = drawable.Rotation;
|
||||
}
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => drawable.ReceivePositionalInputAt(screenSpacePos);
|
||||
|
||||
public override Vector2 ScreenSpaceSelectionPoint => Component.ToScreenSpace(Vector2.Zero);
|
||||
public override Vector2 ScreenSpaceSelectionPoint => drawable.ToScreenSpace(Vector2.Zero);
|
||||
|
||||
public override Quad SelectionQuad => drawable.ScreenSpaceDrawQuad;
|
||||
|
||||
public override Vector2 GetInstantDelta(Vector2 screenSpacePosition) => Component.Parent.ToLocalSpace(screenSpacePosition) - Component.Position;
|
||||
public override Vector2 GetInstantDelta(Vector2 screenSpacePosition) => Component.Parent.ToLocalSpace(screenSpacePosition) - drawable.Position;
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ using osu.Game.Screens.Play.HUD;
|
||||
|
||||
namespace osu.Game.Skinning.Editor
|
||||
{
|
||||
public class SkinBlueprintContainer : BlueprintContainer<SkinnableHUDComponent>
|
||||
public class SkinBlueprintContainer : BlueprintContainer<ISkinnableComponent>
|
||||
{
|
||||
private readonly Drawable target;
|
||||
|
||||
@ -23,14 +23,14 @@ namespace osu.Game.Skinning.Editor
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
SkinnableHUDComponent[] components = target.ChildrenOfType<SkinnableHUDComponent>().ToArray();
|
||||
ISkinnableComponent[] components = target.ChildrenOfType<ISkinnableComponent>().ToArray();
|
||||
|
||||
foreach (var c in components) AddBlueprintFor(c);
|
||||
}
|
||||
|
||||
protected override SelectionHandler<SkinnableHUDComponent> CreateSelectionHandler() => new SkinSelectionHandler();
|
||||
protected override SelectionHandler<ISkinnableComponent> CreateSelectionHandler() => new SkinSelectionHandler();
|
||||
|
||||
protected override SelectionBlueprint<SkinnableHUDComponent> CreateBlueprintFor(SkinnableHUDComponent component)
|
||||
protected override SelectionBlueprint<ISkinnableComponent> CreateBlueprintFor(ISkinnableComponent component)
|
||||
=> new SkinBlueprint(component);
|
||||
}
|
||||
}
|
||||
|
@ -14,15 +14,15 @@ using osuTK;
|
||||
|
||||
namespace osu.Game.Skinning.Editor
|
||||
{
|
||||
public class SkinSelectionHandler : SelectionHandler<SkinnableHUDComponent>
|
||||
public class SkinSelectionHandler : SelectionHandler<ISkinnableComponent>
|
||||
{
|
||||
protected override void DeleteItems(IEnumerable<SkinnableHUDComponent> items)
|
||||
protected override void DeleteItems(IEnumerable<ISkinnableComponent> items)
|
||||
{
|
||||
foreach (var i in items)
|
||||
i.Drawable.Expire();
|
||||
i.Hide();
|
||||
}
|
||||
|
||||
protected override IEnumerable<MenuItem> GetContextMenuItemsForSelection(IEnumerable<SelectionBlueprint<SkinnableHUDComponent>> selection)
|
||||
protected override IEnumerable<MenuItem> GetContextMenuItemsForSelection(IEnumerable<SelectionBlueprint<ISkinnableComponent>> selection)
|
||||
{
|
||||
yield return new OsuMenuItem("Anchor")
|
||||
{
|
||||
@ -49,7 +49,7 @@ namespace osu.Game.Skinning.Editor
|
||||
|
||||
return displayableAnchors.Select(a =>
|
||||
{
|
||||
var countExisting = selection.Count(b => b.Item.SkinAnchor.Value == a);
|
||||
var countExisting = selection.Count(b => ((Drawable)b.Item).Anchor == a);
|
||||
var countTotal = selection.Count();
|
||||
|
||||
TernaryState state;
|
||||
@ -72,7 +72,7 @@ namespace osu.Game.Skinning.Editor
|
||||
private void applyAnchor(Anchor anchor)
|
||||
{
|
||||
foreach (var item in SelectedItems)
|
||||
item.SkinAnchor.Value = anchor;
|
||||
((Drawable)item).Anchor = anchor;
|
||||
}
|
||||
|
||||
protected override void OnSelectionChanged()
|
||||
@ -88,7 +88,7 @@ namespace osu.Game.Skinning.Editor
|
||||
public override bool HandleRotation(float angle)
|
||||
{
|
||||
foreach (var c in SelectedBlueprints)
|
||||
c.Item.SkinRotation.Value += angle;
|
||||
((Drawable)c.Item).Rotation += angle;
|
||||
|
||||
return base.HandleRotation(angle);
|
||||
}
|
||||
@ -98,20 +98,16 @@ namespace osu.Game.Skinning.Editor
|
||||
adjustScaleFromAnchor(ref scale, anchor);
|
||||
|
||||
foreach (var c in SelectedBlueprints)
|
||||
{
|
||||
c.Item.SkinScaleX.Value += scale.X * 0.01f;
|
||||
c.Item.SkinScaleY.Value += scale.Y * 0.01f;
|
||||
}
|
||||
((Drawable)c.Item).Scale += scale * 0.01f;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool HandleMovement(MoveSelectionEvent<SkinnableHUDComponent> moveEvent)
|
||||
public override bool HandleMovement(MoveSelectionEvent<ISkinnableComponent> moveEvent)
|
||||
{
|
||||
foreach (var c in SelectedBlueprints)
|
||||
{
|
||||
c.Item.SkinPositionX.Value += moveEvent.InstantDelta.X;
|
||||
c.Item.SkinPositionY.Value += moveEvent.InstantDelta.Y;
|
||||
((Drawable)c.Item).Position += moveEvent.InstantDelta;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -130,7 +126,7 @@ namespace osu.Game.Skinning.Editor
|
||||
|
||||
public class AnchorMenuItem : TernaryStateMenuItem
|
||||
{
|
||||
public AnchorMenuItem(Anchor anchor, IEnumerable<SelectionBlueprint<SkinnableHUDComponent>> selection, Action<TernaryState> action)
|
||||
public AnchorMenuItem(Anchor anchor, IEnumerable<SelectionBlueprint<ISkinnableComponent>> selection, Action<TernaryState> action)
|
||||
: base(anchor.ToString(), getNextState, MenuItemType.Standard, action)
|
||||
{
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ using osuTK;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
public class LegacyAccuracyCounter : PercentageCounter, IAccuracyCounter
|
||||
public class LegacyAccuracyCounter : PercentageCounter, IAccuracyCounter, ISkinnableComponent
|
||||
{
|
||||
private readonly ISkin skin;
|
||||
|
||||
|
@ -16,7 +16,7 @@ using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
public class LegacyHealthDisplay : CompositeDrawable, IHealthDisplay
|
||||
public class LegacyHealthDisplay : CompositeDrawable, IHealthDisplay, ISkinnableComponent
|
||||
{
|
||||
private const double epic_cutoff = 0.5;
|
||||
|
||||
|
@ -5,11 +5,12 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
public class LegacyScoreCounter : ScoreCounter
|
||||
public class LegacyScoreCounter : ScoreCounter, ISkinnableComponent
|
||||
{
|
||||
private readonly ISkin skin;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user