diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
index 9e89539e25..326791f506 100644
--- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
+++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
@@ -5,6 +5,7 @@
+
WinExe
diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
index 970dc2d630..925e7aaac9 100644
--- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
@@ -11,6 +11,7 @@ using osu.Game.Rulesets.Catch.Objects.Drawable;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling;
+using OpenTK;
namespace osu.Game.Rulesets.Catch.UI
{
@@ -18,9 +19,6 @@ namespace osu.Game.Rulesets.Catch.UI
{
public const float BASE_WIDTH = 512;
- protected override Container Content => content;
- private readonly Container content;
-
private readonly CatcherArea catcherArea;
protected override bool UserScrollSpeedAdjustment => false;
@@ -28,7 +26,6 @@ namespace osu.Game.Rulesets.Catch.UI
protected override SpeedChangeVisualisationMethod VisualisationMethod => SpeedChangeVisualisationMethod.Constant;
public CatchPlayfield(BeatmapDifficulty difficulty, Func> getVisualRepresentation)
- : base(BASE_WIDTH)
{
Direction.Value = ScrollingDirection.Down;
@@ -37,27 +34,27 @@ namespace osu.Game.Rulesets.Catch.UI
Anchor = Anchor.TopCentre;
Origin = Anchor.TopCentre;
- base.Content.Anchor = Anchor.BottomLeft;
- base.Content.Origin = Anchor.BottomLeft;
+ Size = new Vector2(0.86f); // matches stable's vertical offset for catcher plate
- base.Content.AddRange(new Drawable[]
+ InternalChild = new PlayfieldAdjustmentContainer
{
- explodingFruitContainer = new Container
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
{
- RelativeSizeAxes = Axes.Both,
- },
- catcherArea = new CatcherArea(difficulty)
- {
- GetVisualRepresentation = getVisualRepresentation,
- ExplodingFruitTarget = explodingFruitContainer,
- Anchor = Anchor.BottomLeft,
- Origin = Anchor.TopLeft,
- },
- content = new Container
- {
- RelativeSizeAxes = Axes.Both,
- },
- });
+ explodingFruitContainer = new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ catcherArea = new CatcherArea(difficulty)
+ {
+ GetVisualRepresentation = getVisualRepresentation,
+ ExplodingFruitTarget = explodingFruitContainer,
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.TopLeft,
+ },
+ HitObjectContainer
+ }
+ };
VisibleTimeRange.Value = BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450);
}
diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs
index 1ac052de4d..bd0fec43a1 100644
--- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs
@@ -13,7 +13,6 @@ using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling;
-using OpenTK;
namespace osu.Game.Rulesets.Catch.UI
{
@@ -32,8 +31,6 @@ namespace osu.Game.Rulesets.Catch.UI
public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo);
- protected override Vector2 PlayfieldArea => new Vector2(0.86f); // matches stable's vertical offset for catcher plate
-
protected override DrawableHitObject GetVisualRepresentation(CatchHitObject h)
{
switch (h)
diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
index be56ccf8c1..06453ac32d 100644
--- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
@@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.UI
{
public class CatcherArea : Container
{
- public const float CATCHER_SIZE = 84;
+ public const float CATCHER_SIZE = 100;
protected readonly Catcher MovableCatcher;
diff --git a/osu.Game.Rulesets.Catch/UI/PlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Catch/UI/PlayfieldAdjustmentContainer.cs
new file mode 100644
index 0000000000..ad0073ff12
--- /dev/null
+++ b/osu.Game.Rulesets.Catch/UI/PlayfieldAdjustmentContainer.cs
@@ -0,0 +1,42 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using OpenTK;
+
+namespace osu.Game.Rulesets.Catch.UI
+{
+ public class PlayfieldAdjustmentContainer : Container
+ {
+ protected override Container Content => content;
+ private readonly Container content;
+
+ public PlayfieldAdjustmentContainer()
+ {
+ InternalChild = new Container
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ FillMode = FillMode.Fit,
+ FillAspectRatio = 4f / 3,
+ Child = content = new ScalingContainer { RelativeSizeAxes = Axes.Both }
+ };
+ }
+
+ ///
+ /// A which scales its content relative to a target width.
+ ///
+ private class ScalingContainer : Container
+ {
+ protected override void Update()
+ {
+ base.Update();
+
+ Scale = new Vector2(Parent.ChildSize.X / CatchPlayfield.BASE_WIDTH);
+ Size = Vector2.Divide(Vector2.One, Scale);
+ }
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
index 724614e8d5..bf75ebbff8 100644
--- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
+++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
@@ -2,9 +2,10 @@
-
+
+
WinExe
diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaEditRulesetContainer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaEditRulesetContainer.cs
index a01947a60b..138a2c0273 100644
--- a/osu.Game.Rulesets.Mania/Edit/ManiaEditRulesetContainer.cs
+++ b/osu.Game.Rulesets.Mania/Edit/ManiaEditRulesetContainer.cs
@@ -20,8 +20,7 @@ namespace osu.Game.Rulesets.Mania.Edit
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
+ Size = Vector2.One
};
-
- protected override Vector2 PlayfieldArea => Vector2.One;
}
}
diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs
index d489d48fc3..09976e5994 100644
--- a/osu.Game.Rulesets.Mania/UI/Column.cs
+++ b/osu.Game.Rulesets.Mania/UI/Column.cs
@@ -30,8 +30,6 @@ namespace osu.Game.Rulesets.Mania.UI
internal readonly Container TopLevelContainer;
private readonly Container explosionContainer;
- protected override Container Content => hitObjectArea;
-
public Column()
{
RelativeSizeAxes = Axes.Y;
@@ -54,7 +52,10 @@ namespace osu.Game.Rulesets.Mania.UI
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
- hitObjectArea = new ColumnHitObjectArea { RelativeSizeAxes = Axes.Both },
+ hitObjectArea = new ColumnHitObjectArea(HitObjectContainer)
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
explosionContainer = new Container
{
Name = "Hit explosions",
diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
index b5dfb0949a..5a4adfd72e 100644
--- a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
+++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
@@ -8,28 +8,24 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
+using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling;
using OpenTK.Graphics;
namespace osu.Game.Rulesets.Mania.UI.Components
{
- public class ColumnHitObjectArea : Container, IHasAccentColour
+ public class ColumnHitObjectArea : CompositeDrawable, IHasAccentColour
{
private const float hit_target_height = 10;
private const float hit_target_bar_height = 2;
- private Container content;
- protected override Container Content => content;
-
private readonly IBindable direction = new Bindable();
- private Container hitTargetLine;
+ private readonly Container hitTargetLine;
+ private readonly Drawable hitTargetBar;
- [BackgroundDependencyLoader]
- private void load(IScrollingInfo scrollingInfo)
+ public ColumnHitObjectArea(HitObjectContainer hitObjectContainer)
{
- Drawable hitTargetBar;
-
InternalChildren = new[]
{
hitTargetBar = new Box
@@ -45,13 +41,13 @@ namespace osu.Game.Rulesets.Mania.UI.Components
Masking = true,
Child = new Box { RelativeSizeAxes = Axes.Both }
},
- content = new Container
- {
- Name = "Hit objects",
- RelativeSizeAxes = Axes.Both,
- },
+ hitObjectContainer
};
+ }
+ [BackgroundDependencyLoader]
+ private void load(IScrollingInfo scrollingInfo)
+ {
direction.BindTo(scrollingInfo.Direction);
direction.BindValueChanged(direction =>
{
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
index 999f84ed8e..5c3a618a19 100644
--- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
+++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
@@ -10,6 +10,7 @@ using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Configuration;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Objects.Drawables;
+using OpenTK;
namespace osu.Game.Rulesets.Mania.UI
{
@@ -25,6 +26,8 @@ namespace osu.Game.Rulesets.Mania.UI
if (stageDefinitions.Count <= 0)
throw new ArgumentException("Can't have zero or fewer stages.");
+ Size = new Vector2(1, 0.8f);
+
GridContainer playfieldGrid;
AddInternal(playfieldGrid = new GridContainer
{
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs
index 09ebde2799..49874f6dc1 100644
--- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs
+++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs
@@ -24,7 +24,6 @@ using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling;
-using OpenTK;
namespace osu.Game.Rulesets.Mania.UI
{
@@ -110,8 +109,6 @@ namespace osu.Game.Rulesets.Mania.UI
}
}
- protected override Vector2 PlayfieldArea => new Vector2(1, 0.8f);
-
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new ManiaFramedReplayInputHandler(replay);
}
}
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaScrollingPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaScrollingPlayfield.cs
index 4d6c5a747a..8ee0fbf7fe 100644
--- a/osu.Game.Rulesets.Mania/UI/ManiaScrollingPlayfield.cs
+++ b/osu.Game.Rulesets.Mania/UI/ManiaScrollingPlayfield.cs
@@ -7,7 +7,7 @@ using osu.Game.Rulesets.UI.Scrolling;
namespace osu.Game.Rulesets.Mania.UI
{
- public class ManiaScrollingPlayfield : ScrollingPlayfield
+ public abstract class ManiaScrollingPlayfield : ScrollingPlayfield
{
private readonly IBindable direction = new Bindable();
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaStage.cs b/osu.Game.Rulesets.Mania/UI/ManiaStage.cs
index f292d5ff16..8cf49686b9 100644
--- a/osu.Game.Rulesets.Mania/UI/ManiaStage.cs
+++ b/osu.Game.Rulesets.Mania/UI/ManiaStage.cs
@@ -30,8 +30,7 @@ namespace osu.Game.Rulesets.Mania.UI
public IReadOnlyList Columns => columnFlow.Children;
private readonly FillFlowContainer columnFlow;
- protected override Container Content => barLineContainer;
- private readonly Container barLineContainer;
+ private readonly Container barLineContainer;
public Container Judgements => judgements;
private readonly JudgementContainer judgements;
@@ -105,6 +104,7 @@ namespace osu.Game.Rulesets.Mania.UI
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.Y,
+ Child = HitObjectContainer
}
},
judgements = new JudgementContainer
diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj
index 69982b1914..23c6150b6a 100644
--- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj
+++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj
@@ -2,9 +2,10 @@
-
+
+
WinExe
diff --git a/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs
index 6efa16bf56..8571de39f4 100644
--- a/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs
+++ b/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs
@@ -4,6 +4,7 @@
using osu.Framework.Graphics.Cursor;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Osu.UI;
+using osu.Game.Rulesets.UI;
using OpenTK;
namespace osu.Game.Rulesets.Osu.Edit
@@ -15,8 +16,8 @@ namespace osu.Game.Rulesets.Osu.Edit
{
}
- protected override Vector2 PlayfieldArea => Vector2.One;
-
protected override CursorContainer CreateCursor() => null;
+
+ protected override Playfield CreatePlayfield() => new OsuPlayfield { Size = Vector2.One };
}
}
diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
index dce1fc2851..d6972d55d2 100644
--- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
+++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools;
@@ -31,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Edit
new HitObjectCompositionTool()
};
- protected override ScalableContainer CreateLayerContainer() => new ScalableContainer(OsuPlayfield.BASE_SIZE.X) { RelativeSizeAxes = Axes.Both };
+ protected override Container CreateLayerContainer() => new PlayfieldAdjustmentContainer { RelativeSizeAxes = Axes.Both };
public override HitObjectMask CreateMaskFor(DrawableHitObject hitObject)
{
diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs
index b0010ccbf6..398680cb8d 100644
--- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs
+++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs
@@ -23,29 +23,35 @@ namespace osu.Game.Rulesets.Osu.UI
public static readonly Vector2 BASE_SIZE = new Vector2(512, 384);
public OsuPlayfield()
- : base(BASE_SIZE.X)
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
- AddRange(new Drawable[]
+ Size = new Vector2(0.75f);
+
+ InternalChild = new PlayfieldAdjustmentContainer
{
- connectionLayer = new FollowPointRenderer
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
{
- RelativeSizeAxes = Axes.Both,
- Depth = 2,
- },
- judgementLayer = new JudgementContainer
- {
- RelativeSizeAxes = Axes.Both,
- Depth = 1,
- },
- approachCircles = new Container
- {
- RelativeSizeAxes = Axes.Both,
- Depth = -1,
- },
- });
+ connectionLayer = new FollowPointRenderer
+ {
+ RelativeSizeAxes = Axes.Both,
+ Depth = 2,
+ },
+ judgementLayer = new JudgementContainer
+ {
+ RelativeSizeAxes = Axes.Both,
+ Depth = 1,
+ },
+ HitObjectContainer,
+ approachCircles = new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Depth = -1,
+ },
+ }
+ };
}
public override void Add(DrawableHitObject h)
diff --git a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs
index 4bc6992445..0ea8d3ede8 100644
--- a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs
+++ b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs
@@ -4,7 +4,6 @@
using System.Linq;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Input;
-using OpenTK;
using osu.Game.Beatmaps;
using osu.Game.Input.Handlers;
using osu.Game.Rulesets.Objects.Drawables;
@@ -58,12 +57,6 @@ namespace osu.Game.Rulesets.Osu.UI
}
}
- protected override Vector2 GetAspectAdjustedSize()
- {
- var aspectSize = DrawSize.X * 0.75f < DrawSize.Y ? new Vector2(DrawSize.X, DrawSize.X * 0.75f) : new Vector2(DrawSize.Y * 4f / 3f, DrawSize.Y);
- return new Vector2(aspectSize.X / DrawSize.X, aspectSize.Y / DrawSize.Y);
- }
-
protected override CursorContainer CreateCursor() => new GameplayCursor();
}
}
diff --git a/osu.Game.Rulesets.Osu/UI/PlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Osu/UI/PlayfieldAdjustmentContainer.cs
new file mode 100644
index 0000000000..00d5692fda
--- /dev/null
+++ b/osu.Game.Rulesets.Osu/UI/PlayfieldAdjustmentContainer.cs
@@ -0,0 +1,42 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using OpenTK;
+
+namespace osu.Game.Rulesets.Osu.UI
+{
+ public class PlayfieldAdjustmentContainer : Container
+ {
+ protected override Container Content => content;
+ private readonly Container content;
+
+ public PlayfieldAdjustmentContainer()
+ {
+ InternalChild = new Container
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ FillMode = FillMode.Fit,
+ FillAspectRatio = 4f / 3,
+ Child = content = new ScalingContainer { RelativeSizeAxes = Axes.Both }
+ };
+ }
+
+ ///
+ /// A which scales its content relative to a target width.
+ ///
+ private class ScalingContainer : Container
+ {
+ protected override void Update()
+ {
+ base.Update();
+
+ Scale = new Vector2(Parent.ChildSize.X / OsuPlayfield.BASE_SIZE.X);
+ Size = Vector2.Divide(Vector2.One, Scale);
+ }
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
index 11d6025f6d..6ae9a018c5 100644
--- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
+++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
@@ -2,9 +2,10 @@
-
+
+
WinExe
diff --git a/osu.Game.Rulesets.Taiko/UI/PlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Taiko/UI/PlayfieldAdjustmentContainer.cs
new file mode 100644
index 0000000000..661a4e135c
--- /dev/null
+++ b/osu.Game.Rulesets.Taiko/UI/PlayfieldAdjustmentContainer.cs
@@ -0,0 +1,22 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Graphics.Containers;
+using OpenTK;
+
+namespace osu.Game.Rulesets.Taiko.UI
+{
+ public class PlayfieldAdjustmentContainer : Container
+ {
+ private const float default_relative_height = TaikoPlayfield.DEFAULT_HEIGHT / 768;
+ private const float default_aspect = 16f / 9f;
+
+ protected override void Update()
+ {
+ base.Update();
+
+ float aspectAdjust = MathHelper.Clamp(Parent.ChildSize.X / Parent.ChildSize.Y, 0.4f, 4) / default_aspect;
+ Size = new Vector2(1, default_relative_height * aspectAdjust);
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
index ee5324b007..40ed659bd6 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
@@ -47,9 +47,6 @@ namespace osu.Game.Rulesets.Taiko.UI
private readonly Container kiaiExplosionContainer;
private readonly JudgementContainer judgementContainer;
- protected override Container Content => content;
- private readonly Container content;
-
private readonly Container topLevelHitContainer;
private readonly Container barlineContainer;
@@ -64,138 +61,145 @@ namespace osu.Game.Rulesets.Taiko.UI
{
Direction.Value = ScrollingDirection.Left;
- AddRangeInternal(new Drawable[]
+ InternalChild = new PlayfieldAdjustmentContainer
{
- backgroundContainer = new Container
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
{
- Name = "Transparent playfield background",
- RelativeSizeAxes = Axes.Both,
- Masking = true,
- EdgeEffect = new EdgeEffectParameters
+ backgroundContainer = new Container
{
- Type = EdgeEffectType.Shadow,
- Colour = Color4.Black.Opacity(0.2f),
- Radius = 5,
- },
- Children = new Drawable[]
- {
- background = new Box
+ Name = "Transparent playfield background",
+ RelativeSizeAxes = Axes.Both,
+ Masking = true,
+ EdgeEffect = new EdgeEffectParameters
{
- RelativeSizeAxes = Axes.Both,
- Alpha = 0.6f
+ Type = EdgeEffectType.Shadow,
+ Colour = Color4.Black.Opacity(0.2f),
+ Radius = 5,
},
- }
- },
- new Container
- {
- Name = "Right area",
- RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding { Left = left_area_size },
- Children = new Drawable[]
- {
- new Container
+ Children = new Drawable[]
{
- Name = "Masked elements before hit objects",
- RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding { Left = HIT_TARGET_OFFSET },
- Masking = true,
- Children = new Drawable[]
+ background = new Box
{
- hitExplosionContainer = new Container
- {
- RelativeSizeAxes = Axes.Both,
- FillMode = FillMode.Fit,
- Blending = BlendingMode.Additive,
- },
- new HitTarget
- {
- Anchor = Anchor.CentreLeft,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- FillMode = FillMode.Fit
- }
- }
- },
- barlineContainer = new Container
- {
- RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding { Left = HIT_TARGET_OFFSET }
- },
- content = new Container
- {
- Name = "Hit objects",
- RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding { Left = HIT_TARGET_OFFSET },
- Masking = true
- },
- kiaiExplosionContainer = new Container
- {
- Name = "Kiai hit explosions",
- RelativeSizeAxes = Axes.Both,
- FillMode = FillMode.Fit,
- Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
- Blending = BlendingMode.Additive
- },
- judgementContainer = new JudgementContainer
- {
- Name = "Judgements",
- RelativeSizeAxes = Axes.Y,
- Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
- Blending = BlendingMode.Additive
- },
- }
- },
- overlayBackgroundContainer = new Container
- {
- Name = "Left overlay",
- RelativeSizeAxes = Axes.Y,
- Size = new Vector2(left_area_size, 1),
- Children = new Drawable[]
- {
- overlayBackground = new Box
- {
- RelativeSizeAxes = Axes.Both,
- },
- new InputDrum(controlPoints)
- {
- Anchor = Anchor.CentreRight,
- Origin = Anchor.CentreRight,
- Scale = new Vector2(0.9f),
- Margin = new MarginPadding { Right = 20 }
- },
- new Box
- {
- Anchor = Anchor.TopRight,
- RelativeSizeAxes = Axes.Y,
- Width = 10,
- Colour = Framework.Graphics.Colour.ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.6f), Color4.Black.Opacity(0)),
- },
- }
- },
- new Container
- {
- Name = "Border",
- RelativeSizeAxes = Axes.Both,
- Masking = true,
- MaskingSmoothness = 0,
- BorderThickness = 2,
- AlwaysPresent = true,
- Children = new[]
- {
- new Box
- {
- RelativeSizeAxes = Axes.Both,
- Alpha = 0,
- AlwaysPresent = true
+ RelativeSizeAxes = Axes.Both,
+ Alpha = 0.6f
+ },
}
+ },
+ new Container
+ {
+ Name = "Right area",
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Left = left_area_size },
+ Children = new Drawable[]
+ {
+ new Container
+ {
+ Name = "Masked elements before hit objects",
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Left = HIT_TARGET_OFFSET },
+ Masking = true,
+ Children = new Drawable[]
+ {
+ hitExplosionContainer = new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ FillMode = FillMode.Fit,
+ Blending = BlendingMode.Additive,
+ },
+ new HitTarget
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ FillMode = FillMode.Fit
+ }
+ }
+ },
+ barlineContainer = new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Left = HIT_TARGET_OFFSET }
+ },
+ new Container
+ {
+ Name = "Hit objects",
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Left = HIT_TARGET_OFFSET },
+ Masking = true,
+ Child = HitObjectContainer
+ },
+ kiaiExplosionContainer = new Container
+ {
+ Name = "Kiai hit explosions",
+ RelativeSizeAxes = Axes.Both,
+ FillMode = FillMode.Fit,
+ Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
+ Blending = BlendingMode.Additive
+ },
+ judgementContainer = new JudgementContainer
+ {
+ Name = "Judgements",
+ RelativeSizeAxes = Axes.Y,
+ Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
+ Blending = BlendingMode.Additive
+ },
+ }
+ },
+ overlayBackgroundContainer = new Container
+ {
+ Name = "Left overlay",
+ RelativeSizeAxes = Axes.Y,
+ Size = new Vector2(left_area_size, 1),
+ Children = new Drawable[]
+ {
+ overlayBackground = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ new InputDrum(controlPoints)
+ {
+ Anchor = Anchor.CentreRight,
+ Origin = Anchor.CentreRight,
+ Scale = new Vector2(0.9f),
+ Margin = new MarginPadding { Right = 20 }
+ },
+ new Box
+ {
+ Anchor = Anchor.TopRight,
+ RelativeSizeAxes = Axes.Y,
+ Width = 10,
+ Colour = Framework.Graphics.Colour.ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.6f), Color4.Black.Opacity(0)),
+ },
+ }
+ },
+ new Container
+ {
+ Name = "Border",
+ RelativeSizeAxes = Axes.Both,
+ Masking = true,
+ MaskingSmoothness = 0,
+ BorderThickness = 2,
+ AlwaysPresent = true,
+ Children = new[]
+ {
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Alpha = 0,
+ AlwaysPresent = true
+ }
+ }
+ },
+ topLevelHitContainer = new Container
+ {
+ Name = "Top level hit objects",
+ RelativeSizeAxes = Axes.Both,
}
- },
- topLevelHitContainer = new Container
- {
- Name = "Top level hit objects",
- RelativeSizeAxes = Axes.Both,
}
- });
+ };
VisibleTimeRange.Value = 7000;
}
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs
index 229ab69ceb..3d08bffe0f 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
-using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types;
@@ -13,7 +12,6 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Scoring;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.Taiko.Replays;
-using OpenTK;
using System.Linq;
using osu.Framework.Input;
using osu.Game.Input.Handlers;
@@ -74,27 +72,11 @@ namespace osu.Game.Rulesets.Taiko.UI
}
}
- protected override Vector2 GetAspectAdjustedSize()
- {
- const float default_relative_height = TaikoPlayfield.DEFAULT_HEIGHT / 768;
- const float default_aspect = 16f / 9f;
-
- float aspectAdjust = MathHelper.Clamp(DrawWidth / DrawHeight, 0.4f, 4) / default_aspect;
-
- return new Vector2(1, default_relative_height * aspectAdjust);
- }
-
- protected override Vector2 PlayfieldArea => Vector2.One;
-
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(this);
public override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo);
- protected override Playfield CreatePlayfield() => new TaikoPlayfield(Beatmap.ControlPointInfo)
- {
- Anchor = Anchor.CentreLeft,
- Origin = Anchor.CentreLeft
- };
+ protected override Playfield CreatePlayfield() => new TaikoPlayfield(Beatmap.ControlPointInfo);
protected override DrawableHitObject GetVisualRepresentation(TaikoHitObject h)
{
diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs
index bbc9d2b860..b254325472 100644
--- a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs
+++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs
@@ -121,14 +121,21 @@ namespace osu.Game.Tests.Visual
Direction = direction;
Padding = new MarginPadding(2);
- Content.Masking = true;
- AddInternal(new Box
+ InternalChildren = new Drawable[]
{
- RelativeSizeAxes = Axes.Both,
- Alpha = 0.5f,
- Depth = float.MaxValue
- });
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Alpha = 0.5f,
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Masking = true,
+ Child = HitObjectContainer
+ }
+ };
}
}
diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj
index eb9d819fcb..520e0b8940 100644
--- a/osu.Game.Tests/osu.Game.Tests.csproj
+++ b/osu.Game.Tests/osu.Game.Tests.csproj
@@ -2,9 +2,11 @@
-
+
+
+
WinExe
diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs
index a3253250f2..8060ac742a 100644
--- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs
+++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs
@@ -165,6 +165,6 @@ namespace osu.Game.Rulesets.Edit
///
/// Creates a which provides a layer above or below the .
///
- protected virtual ScalableContainer CreateLayerContainer() => new ScalableContainer { RelativeSizeAxes = Axes.Both };
+ protected virtual Container CreateLayerContainer() => new Container { RelativeSizeAxes = Axes.Both };
}
}
diff --git a/osu.Game/Rulesets/UI/HitObjectContainer.cs b/osu.Game/Rulesets/UI/HitObjectContainer.cs
index af18d98561..261132c56b 100644
--- a/osu.Game/Rulesets/UI/HitObjectContainer.cs
+++ b/osu.Game/Rulesets/UI/HitObjectContainer.cs
@@ -14,6 +14,11 @@ namespace osu.Game.Rulesets.UI
public IEnumerable Objects => InternalChildren.Cast().OrderBy(h => h.HitObject.StartTime);
public IEnumerable AliveObjects => AliveInternalChildren.Cast().OrderBy(h => h.HitObject.StartTime);
+ public HitObjectContainer()
+ {
+ RelativeSizeAxes = Axes.Both;
+ }
+
public virtual void Add(DrawableHitObject hitObject) => AddInternal(hitObject);
public virtual bool Remove(DrawableHitObject hitObject) => RemoveInternal(hitObject);
diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs
index e090a18eda..886eb3ac0e 100644
--- a/osu.Game/Rulesets/UI/Playfield.cs
+++ b/osu.Game/Rulesets/UI/Playfield.cs
@@ -9,17 +9,26 @@ using osu.Game.Rulesets.Objects.Drawables;
using osu.Framework.Allocation;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Configuration;
+using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods;
+using OpenTK;
namespace osu.Game.Rulesets.UI
{
- public abstract class Playfield : ScalableContainer
+ public abstract class Playfield : CompositeDrawable
{
///
/// The contained in this Playfield.
///
- public HitObjectContainer HitObjectContainer { get; private set; }
+ public HitObjectContainer HitObjectContainer => hitObjectContainerLazy.Value;
+
+ private readonly Lazy hitObjectContainerLazy;
+
+ ///
+ /// A function that converts gamefield coordinates to screen space.
+ ///
+ public Func GamefieldToScreenSpace => HitObjectContainer.ToScreenSpace;
///
/// All the s contained in this and all .
@@ -39,18 +48,13 @@ namespace osu.Game.Rulesets.UI
public readonly BindableBool DisplayJudgements = new BindableBool(true);
///
- /// A container for keeping track of DrawableHitObjects.
+ /// Creates a new .
///
- /// The width to scale the internal coordinate space to.
- /// May be null if scaling based on is desired. If is also null, no scaling will occur.
- ///
- /// The height to scale the internal coordinate space to.
- /// May be null if scaling based on is desired. If is also null, no scaling will occur.
- ///
- protected Playfield(float? customWidth = null, float? customHeight = null)
- : base(customWidth, customHeight)
+ protected Playfield()
{
RelativeSizeAxes = Axes.Both;
+
+ hitObjectContainerLazy = new Lazy(CreateHitObjectContainer);
}
private WorkingBeatmap beatmap;
@@ -59,11 +63,6 @@ namespace osu.Game.Rulesets.UI
private void load(IBindableBeatmap beatmap)
{
this.beatmap = beatmap.Value;
-
- HitObjectContainer = CreateHitObjectContainer();
- HitObjectContainer.RelativeSizeAxes = Axes.Both;
-
- Add(HitObjectContainer);
}
///
@@ -94,10 +93,14 @@ namespace osu.Game.Rulesets.UI
nestedPlayfields.Value.Add(otherPlayfield);
}
- ///
- /// Creates the container that will be used to contain the s.
- ///
- protected virtual HitObjectContainer CreateHitObjectContainer() => new HitObjectContainer();
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ // in the case a consumer forgets to add the HitObjectContainer, we will add it here.
+ if (HitObjectContainer.Parent == null)
+ AddInternal(HitObjectContainer);
+ }
protected override void Update()
{
@@ -108,5 +111,10 @@ namespace osu.Game.Rulesets.UI
if (mod is IUpdatableByPlayfield updatable)
updatable.Update(this);
}
+
+ ///
+ /// Creates the container that will be used to contain the s.
+ ///
+ protected virtual HitObjectContainer CreateHitObjectContainer() => new HitObjectContainer();
}
}
diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs
index a830803fb1..a23a5a78f7 100644
--- a/osu.Game/Rulesets/UI/RulesetContainer.cs
+++ b/osu.Game/Rulesets/UI/RulesetContainer.cs
@@ -22,7 +22,6 @@ using osu.Game.Overlays;
using osu.Game.Rulesets.Configuration;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Scoring;
-using OpenTK;
namespace osu.Game.Rulesets.UI
{
@@ -309,26 +308,6 @@ namespace osu.Game.Rulesets.UI
mod.ApplyToDrawableHitObjects(Playfield.HitObjectContainer.Objects);
}
- protected override void Update()
- {
- base.Update();
-
- Playfield.Size = GetAspectAdjustedSize() * PlayfieldArea;
- }
-
- ///
- /// Computes the size of the in relative coordinate space after aspect adjustments.
- ///
- /// The aspect-adjusted size.
- protected virtual Vector2 GetAspectAdjustedSize() => Vector2.One;
-
- ///
- /// The area of this that is available for the to use.
- /// Must be specified in relative coordinate space to this .
- /// This affects the final size of the but does not affect the 's scale.
- ///
- protected virtual Vector2 PlayfieldArea => new Vector2(0.75f); // A sane default
-
///
/// Creates a DrawableHitObject from a HitObject.
///
diff --git a/osu.Game/Rulesets/UI/ScalableContainer.cs b/osu.Game/Rulesets/UI/ScalableContainer.cs
deleted file mode 100644
index 5ee03be7ee..0000000000
--- a/osu.Game/Rulesets/UI/ScalableContainer.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using System;
-using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
-using OpenTK;
-
-namespace osu.Game.Rulesets.UI
-{
- ///
- /// A which can have its internal coordinate system scaled to a specific size.
- ///
- public class ScalableContainer : Container
- {
- ///
- /// A function that converts coordinates from gamefield to screen space.
- ///
- public Func GamefieldToScreenSpace => scaledContent.GamefieldToScreenSpace;
-
- ///
- /// The scaled content.
- ///
- private readonly ScaledContainer scaledContent;
- protected override Container Content => scaledContent;
-
- ///
- /// A which can have its internal coordinate system scaled to a specific size.
- ///
- /// The width to scale the internal coordinate space to.
- /// May be null if scaling based on is desired. If is also null, no scaling will occur.
- ///
- /// The height to scale the internal coordinate space to.
- /// May be null if scaling based on is desired. If is also null, no scaling will occur.
- ///
- public ScalableContainer(float? customWidth = null, float? customHeight = null)
- {
- AddInternal(scaledContent = new ScaledContainer
- {
- CustomWidth = customWidth,
- CustomHeight = customHeight,
- RelativeSizeAxes = Axes.Both,
- });
- }
-
- private class ScaledContainer : Container
- {
- ///
- /// A function that converts coordinates from gamefield to screen space.
- ///
- public Func GamefieldToScreenSpace => content.ToScreenSpace;
-
- ///
- /// The value to scale the width of the content to match.
- /// If null, is used.
- ///
- public float? CustomWidth;
-
- ///
- /// The value to scale the height of the content to match.
- /// if null, is used.
- ///
- public float? CustomHeight;
-
- private readonly Container content;
- protected override Container Content => content;
-
- public ScaledContainer()
- {
- AddInternal(content = new Container { RelativeSizeAxes = Axes.Both });
- }
-
- protected override void Update()
- {
- base.Update();
-
- content.Scale = sizeScale;
- content.Size = Vector2.Divide(Vector2.One, sizeScale);
- }
-
- ///
- /// The scale that is required for the size of the content to match and .
- ///
- private Vector2 sizeScale
- {
- get
- {
- if (CustomWidth.HasValue && CustomHeight.HasValue)
- return Vector2.Divide(DrawSize, new Vector2(CustomWidth.Value, CustomHeight.Value));
- if (CustomWidth.HasValue)
- return new Vector2(DrawSize.X / CustomWidth.Value);
- if (CustomHeight.HasValue)
- return new Vector2(DrawSize.Y / CustomHeight.Value);
- return Vector2.One;
- }
- }
- }
- }
-}
diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs
index b85531909c..a1fc13ce4d 100644
--- a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs
+++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs
@@ -65,20 +65,6 @@ namespace osu.Game.Rulesets.UI.Scrolling
protected virtual SpeedChangeVisualisationMethod VisualisationMethod => SpeedChangeVisualisationMethod.Sequential;
- ///
- /// Creates a new .
- ///
- /// The width to scale the internal coordinate space to.
- /// May be null if scaling based on is desired. If is also null, no scaling will occur.
- ///
- /// The height to scale the internal coordinate space to.
- /// May be null if scaling based on is desired. If is also null, no scaling will occur.
- ///
- protected ScrollingPlayfield(float? customWidth = null, float? customHeight = null)
- : base(customWidth, customHeight)
- {
- }
-
[BackgroundDependencyLoader]
private void load()
{
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 22e5901ed6..cc21f4f6a4 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -15,7 +15,7 @@
-
+
diff --git a/osu.TestProject.props b/osu.TestProject.props
index 506d634555..456ecfd468 100644
--- a/osu.TestProject.props
+++ b/osu.TestProject.props
@@ -10,10 +10,6 @@
-
-
-
-
VisualTestRunner.cs
diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings
index 404b19deda..345400305c 100644
--- a/osu.sln.DotSettings
+++ b/osu.sln.DotSettings
@@ -666,6 +666,7 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
True
True
True
+ True
True
True
True