1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-27 18:32:56 +08:00

Merge branch 'master' of https://github.com/ppy/osu into mania_stage_fix

# Conflicts:
#	osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
#	osu.Game/Rulesets/UI/Playfield.cs
This commit is contained in:
ANDY840119-PC\andy840119 2018-01-17 22:27:32 +09:00
commit 3b291abf60
61 changed files with 566 additions and 152 deletions

@ -1 +1 @@
Subproject commit 49b563e2cf170eb19006b98dd5b69c2398362d9e
Subproject commit 8f36ddab946ff538620081ede7719461d4732b79

View File

@ -45,7 +45,7 @@ namespace osu.Desktop
{
protected override string LocateBasePath()
{
Func<string, bool> checkExists = p => Directory.Exists(Path.Combine(p, "Songs"));
bool checkExists(string p) => Directory.Exists(Path.Combine(p, "Songs"));
string stableInstallPath;

View File

@ -31,7 +31,8 @@ namespace osu.Desktop.Overlays
private OsuConfigManager config;
private OsuGameBase game;
public override bool HandleInput => false;
public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
[BackgroundDependencyLoader]
private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config)

View File

@ -58,6 +58,7 @@ namespace osu.Game.Rulesets.Catch.UI
public override void Add(DrawableHitObject h)
{
h.Depth = (float)h.HitObject.StartTime;
h.OnJudgement += onJudgement;
base.Add(h);
@ -65,6 +66,6 @@ namespace osu.Game.Rulesets.Catch.UI
fruit.CheckPosition = CheckIfWeCanCatch;
}
public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) => catcherArea.OnJudgement((DrawableCatchHitObject)judgedObject, judgement);
private void onJudgement(DrawableHitObject judgedObject, Judgement judgement) => catcherArea.OnJudgement((DrawableCatchHitObject)judgedObject, judgement);
}
}

View File

@ -321,7 +321,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
break;
}
Func<SampleInfo, bool> isDoubleSample = sample => sample.Name == SampleInfo.HIT_CLAP && sample.Name == SampleInfo.HIT_FINISH;
bool isDoubleSample(SampleInfo sample) => sample.Name == SampleInfo.HIT_CLAP && sample.Name == SampleInfo.HIT_FINISH;
bool canGenerateTwoNotes = (convertType & PatternType.LowProbability) == 0;
canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(HitObject.StartTime).Any(isDoubleSample);

View File

@ -12,7 +12,7 @@ using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Mania.Mods
{
public class ManiaModKeyCoop : Mod, IKeyBindingMod, IApplicableToBeatmapConverter<ManiaHitObject>, IApplicableToRulesetContainer<ManiaHitObject>
public class ManiaModKeyCoop : Mod, IApplicableToBeatmapConverter<ManiaHitObject>, IApplicableToRulesetContainer<ManiaHitObject>
{
public override string Name => "KeyCoop";
public override string ShortenedName => "2P";

View File

@ -150,7 +150,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
holdStartTime = null;
// If the key has been released too early, the user should not receive full score for the release
if (!tail.AllJudged)
if (!tail.IsHit)
hasBroken = true;
return true;

View File

@ -205,12 +205,13 @@ namespace osu.Game.Rulesets.Mania.UI
public override void Add(DrawableHitObject hitObject)
{
hitObject.Depth = (float)hitObject.HitObject.StartTime;
hitObject.AccentColour = AccentColour;
hitObject.OnJudgement += onJudgement;
HitObjects.Add(hitObject);
}
public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
private void onJudgement(DrawableHitObject judgedObject, Judgement judgement)
{
if (!judgement.IsHit)
return;

View File

@ -8,6 +8,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Configuration;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling;
@ -80,5 +81,10 @@ namespace osu.Game.Rulesets.Mania.UI
return null;
}
internal void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
{
getStageByColumn(((ManiaHitObject)judgedObject.HitObject).Column).OnJudgement(judgedObject, judgement);
}
}
}

View File

@ -186,15 +186,16 @@ namespace osu.Game.Rulesets.Mania.UI
var maniaObject = (ManiaHitObject)h.HitObject;
int columnIndex = maniaObject.Column - firstColumnIndex;
Columns.ElementAt(columnIndex).Add(h);
h.OnJudgement += OnJudgement;
}
public void Add(BarLine barline) => base.Add(new DrawableBarLine(barline));
public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
internal void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
{
var maniaObject = (ManiaHitObject)judgedObject.HitObject;
int columnIndex = maniaObject.Column - firstColumnIndex;
Columns[columnIndex].OnJudgement(judgedObject, judgement);
//Columns[columnIndex].OnJudgement(judgedObject, judgement);
judgements.Clear();
judgements.Add(new DrawableManiaJudgement(judgement)

View File

@ -1,15 +1,12 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics.Cursor;
using osu.Game.Rulesets.Osu.UI;
namespace osu.Game.Rulesets.Osu.Edit
{
public class OsuEditPlayfield : OsuPlayfield
{
protected override CursorContainer CreateCursor() => null;
protected override bool ProxyApproachCircles => false;
}
}

View File

@ -1,6 +1,7 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics.Cursor;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Osu.UI;
using osu.Game.Rulesets.UI;
@ -15,5 +16,7 @@ namespace osu.Game.Rulesets.Osu.Edit
}
protected override Playfield CreatePlayfield() => new OsuEditPlayfield();
protected override CursorContainer CreateCursor() => null;
}
}

View File

@ -11,7 +11,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class SpinnerBackground : CircularContainer, IHasAccentColour
{
public override bool HandleInput => false;
public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
protected Box Disc;

View File

@ -159,5 +159,17 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
return false;
}
protected override void PopIn()
{
ActiveCursor.FadeTo(1, 250, Easing.OutQuint);
ActiveCursor.ScaleTo(1, 400, Easing.OutQuint);
}
protected override void PopOut()
{
ActiveCursor.FadeTo(0, 250, Easing.OutQuint);
ActiveCursor.ScaleTo(0.6f, 250, Easing.In);
}
}
}

View File

@ -12,8 +12,6 @@ using osu.Game.Rulesets.UI;
using System.Linq;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Osu.Judgements;
using osu.Game.Rulesets.Osu.UI.Cursor;
using osu.Framework.Graphics.Cursor;
namespace osu.Game.Rulesets.Osu.UI
{
@ -23,8 +21,6 @@ namespace osu.Game.Rulesets.Osu.UI
private readonly Container judgementLayer;
private readonly ConnectionRenderer<OsuHitObject> connectionLayer;
public override bool ProvidingUserCursor => true;
// Todo: This should not be a thing, but is currently required for the editor
// https://github.com/ppy/osu-framework/issues/1283
protected virtual bool ProxyApproachCircles => true;
@ -70,19 +66,12 @@ namespace osu.Game.Rulesets.Osu.UI
});
}
protected override void LoadComplete()
{
base.LoadComplete();
var cursor = CreateCursor();
if (cursor != null)
AddInternal(cursor);
}
public override void Add(DrawableHitObject h)
{
h.Depth = (float)h.HitObject.StartTime;
h.OnJudgement += onJudgement;
var c = h as IDrawableHitObjectWithProxiedApproach;
if (c != null && ProxyApproachCircles)
approachCircles.Add(c.ProxiedLayer.CreateProxy());
@ -97,7 +86,7 @@ namespace osu.Game.Rulesets.Osu.UI
.OrderBy(h => h.StartTime).OfType<OsuHitObject>();
}
public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
private void onJudgement(DrawableHitObject judgedObject, Judgement judgement)
{
var osuJudgement = (OsuJudgement)judgement;
var osuObject = (OsuHitObject)judgedObject.HitObject;
@ -113,7 +102,5 @@ namespace osu.Game.Rulesets.Osu.UI
judgementLayer.Add(explosion);
}
protected virtual CursorContainer CreateCursor() => new GameplayCursor();
}
}

View File

@ -1,6 +1,7 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics.Cursor;
using osu.Framework.Input;
using OpenTK;
using osu.Game.Beatmaps;
@ -10,6 +11,7 @@ using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Osu.Replays;
using osu.Game.Rulesets.Osu.Scoring;
using osu.Game.Rulesets.Osu.UI.Cursor;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.Replays;
@ -49,5 +51,7 @@ namespace osu.Game.Rulesets.Osu.UI
protected override FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new OsuReplayInputHandler(replay);
protected override Vector2 GetPlayfieldAspectAdjust() => new Vector2(0.75f);
protected override CursorContainer CreateCursor() => new GameplayCursor();
}
}

View File

@ -81,7 +81,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
if (timeOffset < 0)
return;
int countHit = NestedHitObjects.Count(o => o.AllJudged);
int countHit = NestedHitObjects.Count(o => o.IsHit);
if (countHit > HitObject.RequiredGoodHits)
{

View File

@ -143,18 +143,18 @@ namespace osu.Game.Rulesets.Taiko.Tests
var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) };
rulesetContainer.Playfield.OnJudgement(h, new TaikoJudgement { Result = hitResult });
((TaikoPlayfield)rulesetContainer.Playfield).OnJudgement(h, new TaikoJudgement { Result = hitResult });
if (RNG.Next(10) == 0)
{
rulesetContainer.Playfield.OnJudgement(h, new TaikoJudgement { Result = hitResult });
rulesetContainer.Playfield.OnJudgement(h, new TaikoStrongHitJudgement());
((TaikoPlayfield)rulesetContainer.Playfield).OnJudgement(h, new TaikoJudgement { Result = hitResult });
((TaikoPlayfield)rulesetContainer.Playfield).OnJudgement(h, new TaikoStrongHitJudgement());
}
}
private void addMissJudgement()
{
rulesetContainer.Playfield.OnJudgement(new DrawableTestHit(new Hit()), new TaikoJudgement { Result = HitResult.Miss });
((TaikoPlayfield)rulesetContainer.Playfield).OnJudgement(new DrawableTestHit(new Hit()), new TaikoJudgement { Result = HitResult.Miss });
}
private void addBarLine(bool major, double delay = scroll_time)

View File

@ -209,6 +209,8 @@ namespace osu.Game.Rulesets.Taiko.UI
{
h.Depth = (float)h.HitObject.StartTime;
h.OnJudgement += OnJudgement;
base.Add(h);
var barline = h as DrawableBarLine;
@ -221,7 +223,7 @@ namespace osu.Game.Rulesets.Taiko.UI
swell.OnStart += () => topLevelHitContainer.Add(swell.CreateProxy());
}
public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
internal void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
{
if (judgedObject.DisplayJudgement && judgementContainer.FirstOrDefault(j => j.JudgedObject == judgedObject) == null)
{

View File

@ -117,8 +117,8 @@ namespace osu.Game.Tests.Beatmaps.IO
//ensure we were stored to beatmap database backing...
Assert.IsTrue(resultSets.Count() == 1, $@"Incorrect result count found ({resultSets.Count()} but should be 1).");
Func<IEnumerable<BeatmapInfo>> queryBeatmaps = () => store.QueryBeatmaps(s => s.BeatmapSet.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0);
Func<IEnumerable<BeatmapSetInfo>> queryBeatmapSets = () => store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526);
IEnumerable<BeatmapInfo> queryBeatmaps() => store.QueryBeatmaps(s => s.BeatmapSet.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0);
IEnumerable<BeatmapSetInfo> queryBeatmapSets() => store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526);
//if we don't re-check here, the set will be inserted but the beatmaps won't be present yet.
waitForOrAssert(() => queryBeatmaps().Count() == 12,

View File

@ -0,0 +1,274 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Framework.MathUtils;
using osu.Framework.Testing.Input;
using osu.Game.Graphics.Cursor;
using osu.Game.Graphics.Sprites;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Tests.Visual
{
public class TestCaseCursors : OsuTestCase
{
private readonly ManualInputManager inputManager;
private readonly CursorOverrideContainer cursorOverrideContainer;
private readonly CustomCursorBox[] cursorBoxes = new CustomCursorBox[6];
public TestCaseCursors()
{
Child = inputManager = new ManualInputManager
{
Child = cursorOverrideContainer = new CursorOverrideContainer
{
RelativeSizeAxes = Axes.Both,
Children = new[]
{
// Middle user
cursorBoxes[0] = new CustomCursorBox(Color4.Green)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.5f),
},
// Top-left user
cursorBoxes[1] = new CustomCursorBox(Color4.Blue)
{
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.4f)
},
// Bottom-right user
cursorBoxes[2] = new CustomCursorBox(Color4.Red)
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.4f)
},
// Bottom-left local
cursorBoxes[3] = new CustomCursorBox(Color4.Magenta, false)
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.4f)
},
// Top-right local
cursorBoxes[4] = new CustomCursorBox(Color4.Cyan, false)
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.4f)
},
// Left-local
cursorBoxes[5] = new CustomCursorBox(Color4.Yellow, false)
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.2f, 1),
},
}
}
};
returnUserInput();
AddToggleStep("Smooth transitions", b => cursorBoxes.ForEach(box => box.SmoothTransition = b));
testUserCursor();
testLocalCursor();
testUserCursorOverride();
testMultipleLocalCursors();
returnUserInput();
}
/// <summary>
/// Returns input back to the user.
/// </summary>
private void returnUserInput()
{
AddStep("Return user input", () => inputManager.UseParentState = true);
}
/// <summary>
/// -- Green Box --
/// Tests whether hovering in and out of a drawable that provides the user cursor (green)
/// results in the correct visibility state for that cursor.
/// </summary>
private void testUserCursor()
{
AddStep("Move to green area", () => inputManager.MoveMouseTo(cursorBoxes[0]));
AddAssert("Check green cursor visible", () => checkVisible(cursorBoxes[0].Cursor));
AddAssert("Check green cursor at mouse", () => checkAtMouse(cursorBoxes[0].Cursor));
AddStep("Move out", moveOut);
AddAssert("Check green cursor invisible", () => !checkVisible(cursorBoxes[0].Cursor));
AddAssert("Check global cursor visible", () => checkVisible(cursorOverrideContainer.Cursor));
}
/// <summary>
/// -- Purple Box --
/// Tests whether hovering in and out of a drawable that provides a local cursor (purple)
/// results in the correct visibility and state for that cursor.
/// </summary>
private void testLocalCursor()
{
AddStep("Move to purple area", () => inputManager.MoveMouseTo(cursorBoxes[3]));
AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor));
AddAssert("Check purple cursor at mouse", () => checkAtMouse(cursorBoxes[3].Cursor));
AddAssert("Check global cursor visible", () => checkVisible(cursorOverrideContainer.Cursor));
AddAssert("Check global cursor at mouse", () => checkAtMouse(cursorOverrideContainer.Cursor));
AddStep("Move out", moveOut);
AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor));
AddAssert("Check global cursor visible", () => checkVisible(cursorOverrideContainer.Cursor));
}
/// <summary>
/// -- Blue-Green Box Boundary --
/// Tests whether overriding a user cursor (green) with another user cursor (blue)
/// results in the correct visibility and states for the cursors.
/// </summary>
private void testUserCursorOverride()
{
AddStep("Move to blue-green boundary", () => inputManager.MoveMouseTo(cursorBoxes[1].ScreenSpaceDrawQuad.BottomRight - new Vector2(10)));
AddAssert("Check blue cursor visible", () => checkVisible(cursorBoxes[1].Cursor));
AddAssert("Check green cursor invisible", () => !checkVisible(cursorBoxes[0].Cursor));
AddAssert("Check blue cursor at mouse", () => checkAtMouse(cursorBoxes[1].Cursor));
AddStep("Move out", moveOut);
AddAssert("Check blue cursor not visible", () => !checkVisible(cursorBoxes[1].Cursor));
AddAssert("Check green cursor not visible", () => !checkVisible(cursorBoxes[0].Cursor));
}
/// <summary>
/// -- Yellow-Purple Box Boundary --
/// Tests whether multiple local cursors (purple + yellow) may be visible and at the mouse position at the same time.
/// </summary>
private void testMultipleLocalCursors()
{
AddStep("Move to yellow-purple boundary", () => inputManager.MoveMouseTo(cursorBoxes[5].ScreenSpaceDrawQuad.BottomRight - new Vector2(10)));
AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor));
AddAssert("Check purple cursor at mouse", () => checkAtMouse(cursorBoxes[3].Cursor));
AddAssert("Check yellow cursor visible", () => checkVisible(cursorBoxes[5].Cursor));
AddAssert("Check yellow cursor at mouse", () => checkAtMouse(cursorBoxes[5].Cursor));
AddStep("Move out", moveOut);
AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor));
AddAssert("Check yellow cursor visible", () => checkVisible(cursorBoxes[5].Cursor));
}
/// <summary>
/// -- Yellow-Blue Box Boundary --
/// Tests whether a local cursor (yellow) may be displayed along with a user cursor override (blue).
/// </summary>
private void testUserOverrideWithLocal()
{
AddStep("Move to yellow-blue boundary", () => inputManager.MoveMouseTo(cursorBoxes[5].ScreenSpaceDrawQuad.TopRight - new Vector2(10)));
AddAssert("Check blue cursor visible", () => checkVisible(cursorBoxes[1].Cursor));
AddAssert("Check blue cursor at mouse", () => checkAtMouse(cursorBoxes[1].Cursor));
AddAssert("Check yellow cursor visible", () => checkVisible(cursorBoxes[5].Cursor));
AddAssert("Check yellow cursor at mouse", () => checkAtMouse(cursorBoxes[5].Cursor));
AddStep("Move out", moveOut);
AddAssert("Check blue cursor invisible", () => !checkVisible(cursorBoxes[1].Cursor));
AddAssert("Check yellow cursor visible", () => checkVisible(cursorBoxes[5].Cursor));
}
/// <summary>
/// Moves the cursor to a point not covered by any cursor containers.
/// </summary>
private void moveOut()
=> inputManager.MoveMouseTo(new Vector2(inputManager.ScreenSpaceDrawQuad.Centre.X, inputManager.ScreenSpaceDrawQuad.TopLeft.Y));
/// <summary>
/// Checks if a cursor is visible.
/// </summary>
/// <param name="cursorContainer">The cursor to check.</param>
private bool checkVisible(CursorContainer cursorContainer) => cursorContainer.State == Visibility.Visible;
/// <summary>
/// Checks if a cursor is at the current inputmanager screen position.
/// </summary>
/// <param name="cursorContainer">The cursor to check.</param>
private bool checkAtMouse(CursorContainer cursorContainer)
=> Precision.AlmostEquals(inputManager.CurrentState.Mouse.NativeState.Position, cursorContainer.ToScreenSpace(cursorContainer.ActiveCursor.DrawPosition));
private class CustomCursorBox : Container, IProvideCursor
{
public bool SmoothTransition;
public CursorContainer Cursor { get; }
public bool ProvidingUserCursor { get; }
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => base.ReceiveMouseInputAt(screenSpacePos) || SmoothTransition && !ProvidingUserCursor;
private readonly Box background;
public CustomCursorBox(Color4 cursorColour, bool providesUserCursor = true)
{
ProvidingUserCursor = providesUserCursor;
Colour = cursorColour;
Masking = true;
Children = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0.1f
},
new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Text = providesUserCursor ? "User cursor" : "Local cursor"
},
Cursor = new TestCursorContainer
{
State = providesUserCursor ? Visibility.Hidden : Visibility.Visible,
}
};
}
protected override bool OnHover(InputState state)
{
background.FadeTo(0.4f, 250, Easing.OutQuint);
return false;
}
protected override void OnHoverLost(InputState state)
{
background.FadeTo(0.1f, 250);
base.OnHoverLost(state);
}
}
private class TestCursorContainer : CursorContainer
{
protected override Drawable CreateCursor() => new TestCursor();
private class TestCursor : CircularContainer
{
public TestCursor()
{
Origin = Anchor.Centre;
Size = new Vector2(50);
Masking = true;
Blending = BlendingMode.Additive;
Alpha = 0.5f;
Child = new Box { RelativeSizeAxes = Axes.Both };
}
}
}
}
}

View File

@ -65,7 +65,7 @@ namespace osu.Game.Tests.Visual
// this is by no means clean. should be replacing inside of OsuGameBase somehow.
var context = new OsuDbContext();
Func<OsuDbContext> contextFactory = () => context;
OsuDbContext contextFactory() => context;
dependencies.Cache(rulesets = new RulesetStore(contextFactory));
dependencies.Cache(manager = new BeatmapManager(storage, contextFactory, rulesets, null)

View File

@ -104,6 +104,7 @@
<Compile Include="Visual\TestCaseBreakOverlay.cs" />
<Compile Include="Visual\TestCaseChatDisplay.cs" />
<Compile Include="Visual\TestCaseContextMenu.cs" />
<Compile Include="Visual\TestCaseCursors.cs" />
<Compile Include="Visual\TestCaseDialogOverlay.cs" />
<Compile Include="Visual\TestCaseDirect.cs" />
<Compile Include="Visual\TestCaseDrawableRoom.cs" />

View File

@ -30,7 +30,9 @@ namespace osu.Game.Graphics.Backgrounds
/// </summary>
private const float edge_smoothness = 1;
public override bool HandleInput => false;
public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
public Color4 ColourLight = Color4.White;
public Color4 ColourDark = Color4.Black;

View File

@ -0,0 +1,67 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Input;
namespace osu.Game.Graphics.Cursor
{
/// <summary>
/// A container which provides a <see cref="MenuCursor"/> which can be overridden by hovered <see cref="Drawable"/>s.
/// </summary>
public class CursorOverrideContainer : Container, IProvideCursor
{
protected override Container<Drawable> Content => content;
private readonly Container content;
/// <summary>
/// Whether any cursors can be displayed.
/// </summary>
public bool CanShowCursor = true;
public CursorContainer Cursor { get; }
public bool ProvidingUserCursor => true;
public CursorOverrideContainer()
{
AddRangeInternal(new Drawable[]
{
Cursor = new MenuCursor { State = Visibility.Hidden },
content = new Container { RelativeSizeAxes = Axes.Both }
});
}
private InputManager inputManager;
protected override void LoadComplete()
{
base.LoadComplete();
inputManager = GetContainingInputManager();
}
private IProvideCursor currentTarget;
protected override void Update()
{
base.Update();
if (!CanShowCursor)
{
currentTarget?.Cursor?.Hide();
return;
}
var newTarget = inputManager.HoveredDrawables.OfType<IProvideCursor>().FirstOrDefault(t => t.ProvidingUserCursor) ?? this;
if (currentTarget == newTarget)
return;
currentTarget?.Cursor?.Hide();
newTarget.Cursor?.Show();
currentTarget = newTarget;
}
}
}

View File

@ -0,0 +1,26 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
using osu.Framework.Graphics.Cursor;
namespace osu.Game.Graphics.Cursor
{
/// <summary>
/// Interface for <see cref="IDrawable"/>s that display cursors which can replace the user's cursor.
/// </summary>
public interface IProvideCursor : IDrawable
{
/// <summary>
/// The cursor provided by this <see cref="IDrawable"/>.
/// May be null if no cursor should be visible.
/// </summary>
CursorContainer Cursor { get; }
/// <summary>
/// Whether <see cref="Cursor"/> should be displayed as the singular user cursor. This will temporarily hide any other user cursor.
/// This value is checked every frame and may be used to control whether multiple cursors are displayed (e.g. watching replays).
/// </summary>
bool ProvidingUserCursor { get; }
}
}

View File

@ -99,8 +99,8 @@ namespace osu.Game.Graphics.Cursor
protected override void PopOut()
{
ActiveCursor.FadeTo(0, 900, Easing.OutQuint);
ActiveCursor.ScaleTo(0, 500, Easing.In);
ActiveCursor.FadeTo(0, 250, Easing.OutQuint);
ActiveCursor.ScaleTo(0.6f, 250, Easing.In);
}
[BackgroundDependencyLoader]

View File

@ -42,7 +42,9 @@ namespace osu.Game.Graphics.UserInterface
//don't allow clicking between transitions and don't make the chevron clickable
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => Alpha == 1f && Text.ReceiveMouseInputAt(screenSpacePos);
public override bool HandleInput => State == Visibility.Visible;
public override bool HandleKeyboardInput => State == Visibility.Visible;
public override bool HandleMouseInput => State == Visibility.Visible;
private Visibility state;

View File

@ -157,6 +157,11 @@ namespace osu.Game
{
base.LoadComplete();
// The next time this is updated is in UpdateAfterChildren, which occurs too late and results
// in the cursor being shown for a few frames during the intro.
// This prevents the cursor from showing until we have a screen with CursorVisible = true
CursorOverrideContainer.CanShowCursor = currentScreen?.CursorVisible ?? false;
// hook up notifications to components.
BeatmapManager.PostNotification = n => notifications?.Post(n);
BeatmapManager.GetStableStorage = GetStorageForStableInstall;
@ -297,8 +302,6 @@ namespace osu.Game
else
Toolbar.State = Visibility.Visible;
};
Cursor.State = Visibility.Hidden;
}
private void forwardLoggedErrorsToNotifications()
@ -447,7 +450,7 @@ namespace osu.Game
mainContent.Padding = new MarginPadding { Top = ToolbarOffset };
Cursor.State = currentScreen?.HasLocalCursorDisplayed == false ? Visibility.Visible : Visibility.Hidden;
CursorOverrideContainer.CanShowCursor = currentScreen?.CursorVisible ?? false;
}
private void screenAdded(Screen newScreen)

View File

@ -44,6 +44,8 @@ namespace osu.Game
protected KeyBindingStore KeyBindingStore;
protected CursorOverrideContainer CursorOverrideContainer;
protected override string MainResourceFile => @"osu.Game.Resources.dll";
public APIAccess API;
@ -52,8 +54,6 @@ namespace osu.Game
protected override Container<Drawable> Content => content;
protected MenuCursor Cursor;
public Bindable<WorkingBeatmap> Beatmap { get; private set; }
private Bindable<bool> fpsDisplayVisible;
@ -211,21 +211,14 @@ namespace osu.Game
GlobalKeyBindingInputManager globalBinding;
base.Content.Add(new DrawSizePreservingFillContainer
CursorOverrideContainer = new CursorOverrideContainer { RelativeSizeAxes = Axes.Both };
CursorOverrideContainer.Child = globalBinding = new GlobalKeyBindingInputManager(this)
{
Children = new Drawable[]
{
Cursor = new MenuCursor(),
globalBinding = new GlobalKeyBindingInputManager(this)
{
RelativeSizeAxes = Axes.Both,
Child = content = new OsuTooltipContainer(Cursor)
{
RelativeSizeAxes = Axes.Both,
}
}
}
});
RelativeSizeAxes = Axes.Both,
Child = content = new OsuTooltipContainer(CursorOverrideContainer.Cursor) { RelativeSizeAxes = Axes.Both }
};
base.Content.Add(new DrawSizePreservingFillContainer { Child = CursorOverrideContainer });
KeyBindingStore.Register(globalBinding);
dependencies.Cache(globalBinding);

View File

@ -22,7 +22,8 @@ namespace osu.Game.Overlays
{
private readonly Container box;
public override bool HandleInput => false;
public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
private readonly SpriteText textLine1;
private readonly SpriteText textLine2;
@ -121,7 +122,7 @@ namespace osu.Game.Overlays
trackSetting(frameworkConfig.GetBindable<string>(FrameworkSetting.AudioDevice), v => display(v, "Audio Device", string.IsNullOrEmpty(v) ? "Default" : v, v));
trackSetting(frameworkConfig.GetBindable<bool>(FrameworkSetting.ShowLogOverlay), v => display(v, "Debug Logs", v ? "visible" : "hidden", "Ctrl+F10"));
Action displayResolution = delegate { display(null, "Screen Resolution", frameworkConfig.Get<int>(FrameworkSetting.Width) + "x" + frameworkConfig.Get<int>(FrameworkSetting.Height)); };
void displayResolution() => display(null, "Screen Resolution", frameworkConfig.Get<int>(FrameworkSetting.Width) + "x" + frameworkConfig.Get<int>(FrameworkSetting.Height));
trackSetting(frameworkConfig.GetBindable<int>(FrameworkSetting.Width), v => displayResolution());
trackSetting(frameworkConfig.GetBindable<int>(FrameworkSetting.Height), v => displayResolution());

View File

@ -319,11 +319,11 @@ namespace osu.Game.Overlays.Profile
colourBar.Show();
}
Action<SpriteText> boldItalic = t =>
void boldItalic(SpriteText t)
{
t.Font = @"Exo2.0-BoldItalic";
t.Alpha = 1;
};
}
if (user.Age != null)
{
@ -474,7 +474,8 @@ namespace osu.Game.Overlays.Profile
private class LinkFlowContainer : OsuTextFlowContainer
{
public override bool HandleInput => true;
public override bool HandleKeyboardInput => true;
public override bool HandleMouseInput => true;
public LinkFlowContainer(Action<SpriteText> defaultCreationParameters = null) : base(defaultCreationParameters)
{
@ -488,7 +489,8 @@ namespace osu.Game.Overlays.Profile
{
private readonly OsuHoverContainer content;
public override bool HandleInput => content.Action != null;
public override bool HandleKeyboardInput => content.Action != null;
public override bool HandleMouseInput => content.Action != null;
protected override Container<Drawable> Content => content ?? (Container<Drawable>)this;

View File

@ -87,7 +87,8 @@ namespace osu.Game.Overlays.Toolbar
ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault();
}
public override bool HandleInput => !ruleset.Disabled;
public override bool HandleKeyboardInput => !ruleset.Disabled;
public override bool HandleMouseInput => !ruleset.Disabled;
private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300);

View File

@ -165,7 +165,8 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
}
private bool isActive = true;
public override bool HandleInput => isActive;
public override bool HandleKeyboardInput => isActive;
public override bool HandleMouseInput => isActive;
public override void Hide()
{

View File

@ -40,7 +40,8 @@ namespace osu.Game.Rulesets.Judgements
Anchor = Anchor.Centre,
Text = judgement.Result.GetDescription().ToUpper(),
Font = @"Venera",
TextSize = 16
Scale = new Vector2(0.85f, 1),
TextSize = 12
}
};
}

View File

@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Mods
{
const float ratio = 1.4f;
difficulty.CircleSize *= 1.3f; // CS uses a custom 1.3 ratio.
difficulty.ApproachRate *= ratio;
difficulty.ApproachRate = Math.Min(difficulty.ApproachRate * ratio, 10.0f);
difficulty.DrainRate *= ratio;
difficulty.OverallDifficulty *= ratio;
}

View File

@ -68,7 +68,8 @@ namespace osu.Game.Rulesets.Objects.Drawables
private bool judgementFinalized => judgements.LastOrDefault()?.Final == true;
public bool Interactive = true;
public override bool HandleInput => Interactive;
public override bool HandleKeyboardInput => Interactive;
public override bool HandleMouseInput => Interactive;
public override bool RemoveWhenNotAlive => false;
public override bool RemoveCompletedTransforms => false;
@ -167,6 +168,11 @@ namespace osu.Game.Rulesets.Objects.Drawables
{
if (nestedHitObjects == null)
nestedHitObjects = new List<DrawableHitObject>();
h.OnJudgement += (d, j) => OnJudgement?.Invoke(d, j);
h.OnJudgementRemoved += (d, j) => OnJudgementRemoved?.Invoke(d, j);
h.ApplyCustomUpdateState += (d, j) => ApplyCustomUpdateState?.Invoke(d, j);
nestedHitObjects.Add(h);
}

View File

@ -1,11 +1,12 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Objects.Drawables;
using OpenTK;
using osu.Game.Rulesets.Judgements;
using osu.Framework.Allocation;
namespace osu.Game.Rulesets.UI
@ -19,14 +20,16 @@ namespace osu.Game.Rulesets.UI
public Container<Drawable> ScaledContent;
/// <summary>
/// Whether we are currently providing the local user a gameplay cursor.
/// </summary>
public virtual bool ProvidingUserCursor => false;
protected override Container<Drawable> Content => content;
private readonly Container<Drawable> content;
private List<Playfield> nestedPlayfields;
/// <summary>
/// All the <see cref="Playfield"/>s nested inside this playfield.
/// </summary>
public IReadOnlyList<Playfield> NestedPlayfields => nestedPlayfields;
/// <summary>
/// A container for keeping track of DrawableHitObjects.
/// </summary>
@ -61,7 +64,7 @@ namespace osu.Game.Rulesets.UI
/// <summary>
/// Performs post-processing tasks (if any) after all DrawableHitObjects are loaded into this Playfield.
/// </summary>
public virtual void PostProcess() { }
public virtual void PostProcess() => nestedPlayfields?.ForEach(p => p.PostProcess());
/// <summary>
/// Adds a DrawableHitObject to this Playfield.
@ -76,11 +79,17 @@ namespace osu.Game.Rulesets.UI
public virtual void Remove(DrawableHitObject h) => HitObjects.Remove(h);
/// <summary>
/// Triggered when a new <see cref="Judgement"/> occurs on a <see cref="DrawableHitObject"/>.
/// Registers a <see cref="Playfield"/> as a nested <see cref="Playfield"/>.
/// This does not add the <see cref="Playfield"/> to the draw hierarchy.
/// </summary>
/// <param name="judgedObject">The object that <paramref name="judgement"/> occured for.</param>
/// <param name="judgement">The <see cref="Judgement"/> that occurred.</param>
public virtual void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { }
/// <param name="otherPlayfield">The <see cref="Playfield"/> to add.</param>
protected void AddNested(Playfield otherPlayfield)
{
if (nestedPlayfields == null)
nestedPlayfields = new List<Playfield>();
nestedPlayfields.Add(otherPlayfield);
}
/// <summary>
/// Creates the container that will be used to contain the <see cref="DrawableHitObject"/>s.

View File

@ -13,6 +13,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Input;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Scoring;
@ -43,11 +44,6 @@ namespace osu.Game.Rulesets.UI
/// </summary>
public PassThroughInputManager KeyBindingInputManager;
/// <summary>
/// Whether we are currently providing the local user a gameplay cursor.
/// </summary>
public virtual bool ProvidingUserCursor => false;
/// <summary>
/// Whether we have a replay loaded currently.
/// </summary>
@ -61,6 +57,11 @@ namespace osu.Game.Rulesets.UI
/// </summary>
public Playfield Playfield => playfield.Value;
/// <summary>
/// The cursor provided by this <see cref="RulesetContainer"/>. May be null if no cursor is provided.
/// </summary>
public readonly CursorContainer Cursor;
protected readonly Ruleset Ruleset;
/// <summary>
@ -71,6 +72,8 @@ namespace osu.Game.Rulesets.UI
{
Ruleset = ruleset;
playfield = new Lazy<Playfield>(CreatePlayfield);
Cursor = CreateCursor();
}
public abstract ScoreProcessor CreateScoreProcessor();
@ -98,6 +101,12 @@ namespace osu.Game.Rulesets.UI
ReplayInputManager.ReplayInputHandler = replay != null ? CreateReplayInputHandler(replay) : null;
}
/// <summary>
/// Creates the cursor. May be null if the <see cref="RulesetContainer"/> doesn't provide a custom cursor.
/// </summary>
protected virtual CursorContainer CreateCursor() => null;
/// <summary>
/// Creates a Playfield.
/// </summary>
@ -144,8 +153,6 @@ namespace osu.Game.Rulesets.UI
/// </summary>
protected readonly bool IsForCurrentRuleset;
public sealed override bool ProvidingUserCursor => !HasReplayLoaded && Playfield.ProvidingUserCursor;
public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor<TObject>(this);
protected override Container<Drawable> Content => content;
@ -212,6 +219,9 @@ namespace osu.Game.Rulesets.UI
AddInternal(KeyBindingInputManager);
KeyBindingInputManager.Add(Playfield);
if (Cursor != null)
KeyBindingInputManager.Add(Cursor);
loadObjects();
}
@ -252,12 +262,7 @@ namespace osu.Game.Rulesets.UI
if (drawableObject == null)
continue;
drawableObject.OnJudgement += (d, j) =>
{
Playfield.OnJudgement(d, j);
OnJudgement?.Invoke(j);
};
drawableObject.OnJudgement += (d, j) => OnJudgement?.Invoke(j);
drawableObject.OnJudgementRemoved += (d, j) => OnJudgementRemoved?.Invoke(j);
Playfield.Add(drawableObject);

View File

@ -1,7 +1,6 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
@ -76,25 +75,6 @@ namespace osu.Game.Rulesets.UI.Scrolling
HitObjects.TimeRange.BindTo(VisibleTimeRange);
}
private List<ScrollingPlayfield> nestedPlayfields;
/// <summary>
/// All the <see cref="ScrollingPlayfield"/>s nested inside this playfield.
/// </summary>
public IEnumerable<ScrollingPlayfield> NestedPlayfields => nestedPlayfields;
/// <summary>
/// Adds a <see cref="ScrollingPlayfield"/> to this playfield. The nested <see cref="ScrollingPlayfield"/>
/// will be given all of the same speed adjustments as this playfield.
/// </summary>
/// <param name="otherPlayfield">The <see cref="ScrollingPlayfield"/> to add.</param>
protected void AddNested(ScrollingPlayfield otherPlayfield)
{
if (nestedPlayfields == null)
nestedPlayfields = new List<ScrollingPlayfield>();
nestedPlayfields.Add(otherPlayfield);
}
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{
if (!UserScrollSpeedAdjustment)

View File

@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
private void applySpeedAdjustment(MultiplierControlPoint controlPoint, ScrollingPlayfield playfield)
{
playfield.HitObjects.AddControlPoint(controlPoint);
playfield.NestedPlayfields.ForEach(p => applySpeedAdjustment(controlPoint, p));
playfield.NestedPlayfields?.OfType<ScrollingPlayfield>().ForEach(p => applySpeedAdjustment(controlPoint, p));
}
/// <summary>

View File

@ -222,7 +222,8 @@ namespace osu.Game.Screens.Menu
boxHoverLayer.FadeOut(800, Easing.OutExpo);
}
public override bool HandleInput => state != ButtonState.Exploded && box.Scale.X >= 0.8f;
public override bool HandleKeyboardInput => state != ButtonState.Exploded;
public override bool HandleMouseInput => state != ButtonState.Exploded && box.Scale.X >= 0.8f;
protected override void Update()
{

View File

@ -199,7 +199,8 @@ namespace osu.Game.Screens.Menu
private MenuState state;
public override bool HandleInput => state != MenuState.Exit;
public override bool HandleKeyboardInput => state != MenuState.Exit;
public override bool HandleMouseInput => state != MenuState.Exit;
public MenuState State
{

View File

@ -19,8 +19,7 @@ namespace osu.Game.Screens.Menu
private Color4 iconColour;
public override bool ShowOverlaysOnEnter => false;
public override bool HasLocalCursorDisplayed => true;
public override bool CursorVisible => false;
public Disclaimer()
{

View File

@ -31,9 +31,8 @@ namespace osu.Game.Screens.Menu
private SampleChannel welcome;
private SampleChannel seeya;
public override bool HasLocalCursorDisplayed => true;
public override bool ShowOverlaysOnEnter => false;
public override bool CursorVisible => false;
protected override BackgroundScreen CreateBackground() => new BackgroundScreenEmpty();

View File

@ -1,7 +1,6 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Linq;
using OpenTK;
using OpenTK.Graphics;
@ -188,7 +187,7 @@ namespace osu.Game.Screens.Menu
mediumRing.ResizeTo(130, 340, Easing.OutQuad);
mediumRing.Foreground.ResizeTo(1, 880, Easing.Out);
Func<double> remainingTime = () => length - TransformDelay;
double remainingTime() => length - TransformDelay;
using (BeginDelayedSequence(250, true))
{

View File

@ -64,7 +64,8 @@ namespace osu.Game.Screens.Menu
private readonly float[] frequencyAmplitudes = new float[256];
public override bool HandleInput => false;
public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
private Shader shader;
private readonly Texture texture;

View File

@ -19,7 +19,8 @@ namespace osu.Game.Screens.Menu
{
public class MenuSideFlashes : BeatSyncedContainer
{
public override bool HandleInput => false;
public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();

View File

@ -231,7 +231,7 @@ namespace osu.Game.Screens.Menu
/// <param name="waitForPrevious">If true, the new animation is delayed until all previous transforms finish. If false, existing transformed are cleared.</param>
public void AppendAnimatingAction(Action action, bool waitForPrevious)
{
Action runnableAction = () =>
void runnableAction()
{
if (waitForPrevious)
this.DelayUntilTransformsFinished().Schedule(action);
@ -240,12 +240,12 @@ namespace osu.Game.Screens.Menu
ClearTransforms();
action();
}
};
}
if (IsLoaded)
runnableAction();
else
Schedule(() => runnableAction());
Schedule(runnableAction);
}
[BackgroundDependencyLoader]

View File

@ -35,9 +35,12 @@ namespace osu.Game.Screens
/// </summary>
public virtual bool ShowOverlaysOnEnter => true;
protected new OsuGameBase Game => base.Game as OsuGameBase;
/// <summary>
/// Whether this <see cref="OsuScreen"/> allows the cursor to be displayed.
/// </summary>
public virtual bool CursorVisible => true;
public virtual bool HasLocalCursorDisplayed => false;
protected new OsuGameBase Game => base.Game as OsuGameBase;
private OsuLogo logo;

View File

@ -142,8 +142,6 @@ namespace osu.Game.Screens.Play
}
}
public override bool HandleInput => State == Visibility.Visible;
protected override void PopIn() => this.FadeIn(transition_duration, Easing.In);
protected override void PopOut() => this.FadeOut(transition_duration, Easing.In);

View File

@ -111,7 +111,8 @@ namespace osu.Game.Screens.Play
}
}
public override bool HandleInput => receptor == null;
public override bool HandleKeyboardInput => receptor == null;
public override bool HandleMouseInput => receptor == null;
private Receptor receptor;

View File

@ -23,22 +23,22 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Ranking;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics.Cursor;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Cursor;
using osu.Game.Online.API;
using osu.Game.Screens.Play.BreaksOverlay;
using osu.Game.Storyboards.Drawables;
namespace osu.Game.Screens.Play
{
public class Player : OsuScreen
public class Player : OsuScreen, IProvideCursor
{
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap);
public override bool ShowOverlaysOnEnter => false;
public override bool HasLocalCursorDisplayed => !pauseContainer.IsPaused && !HasFailed && RulesetContainer.ProvidingUserCursor;
public Action RestartRequested;
public override bool AllowBeatmapRulesetChange => false;
@ -51,6 +51,9 @@ namespace osu.Game.Screens.Play
public int RestartCount;
public CursorContainer Cursor => RulesetContainer.Cursor;
public bool ProvidingUserCursor => RulesetContainer?.Cursor != null && !RulesetContainer.HasReplayLoaded;
private IAdjustableClock adjustableSourceClock;
private FramedOffsetClock offsetClock;
private DecoupleableInterpolatingFramedClock decoupledClock;
@ -176,13 +179,13 @@ namespace osu.Game.Screens.Play
},
Children = new Drawable[]
{
new SkipButton(firstObjectTime) { AudioClock = decoupledClock },
new Container
{
RelativeSizeAxes = Axes.Both,
Clock = offsetClock,
Child = RulesetContainer,
},
new SkipButton(firstObjectTime) { AudioClock = decoupledClock },
hudOverlay = new HUDOverlay
{
Anchor = Anchor.Centre,
@ -194,7 +197,7 @@ namespace osu.Game.Screens.Play
Origin = Anchor.Centre,
Clock = decoupledClock,
Breaks = beatmap.Breaks
},
}
}
},
failOverlay = new FailOverlay

View File

@ -21,7 +21,7 @@ using osu.Game.Input.Bindings;
namespace osu.Game.Screens.Play
{
public class SkipButton : Container, IKeyBindingHandler<GlobalAction>
public class SkipButton : OverlayContainer, IKeyBindingHandler<GlobalAction>
{
private readonly double startTime;
public IAdjustableClock AudioClock;
@ -36,6 +36,8 @@ namespace osu.Game.Screens.Play
{
this.startTime = startTime;
State = Visibility.Visible;
RelativePositionAxes = Axes.Both;
RelativeSizeAxes = Axes.Both;
@ -112,6 +114,16 @@ namespace osu.Game.Screens.Play
Expire();
}
protected override void PopIn()
{
this.FadeIn();
}
protected override void PopOut()
{
this.FadeOut();
}
protected override void Update()
{
base.Update();

View File

@ -28,7 +28,8 @@ namespace osu.Game.Screens.Play
public Action<double> OnSeek;
public override bool HandleInput => AllowSeeking;
public override bool HandleKeyboardInput => AllowSeeking;
public override bool HandleMouseInput => AllowSeeking;
private IClock audioClock;
public IClock AudioClock { set { audioClock = info.AudioClock = value; } }

View File

@ -21,7 +21,8 @@ namespace osu.Game.Screens.Play
public int ColumnCount => columns.Length;
public override bool HandleInput => false;
public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
private int progress;
public int Progress

View File

@ -51,7 +51,8 @@ namespace osu.Game.Screens.Select
/// </summary>
public Action<BeatmapInfo> SelectionChanged;
public override bool HandleInput => AllowSelection;
public override bool HandleKeyboardInput => AllowSelection;
public override bool HandleMouseInput => AllowSelection;
/// <summary>
/// Used to avoid firing null selections before the initial beatmaps have been loaded via <see cref="BeatmapSets"/>.

View File

@ -266,7 +266,7 @@ namespace osu.Game.Screens.Select
/// </summary>
private void carouselSelectionChanged(BeatmapInfo beatmap)
{
Action performLoad = delegate
void performLoad()
{
// We may be arriving here due to another component changing the bindable Beatmap.
// In these cases, the other component has already loaded the beatmap, so we don't need to do so again.
@ -279,7 +279,7 @@ namespace osu.Game.Screens.Select
}
UpdateBeatmap(Beatmap.Value);
};
}
if (beatmap?.Equals(beatmapNoDebounce) == true)
return;

View File

@ -265,7 +265,7 @@ namespace osu.Game.Screens.Tournament
private void writeResults(string text)
{
Action writeAction = () =>
void writeAction()
{
try
{
@ -280,9 +280,9 @@ namespace osu.Game.Screens.Tournament
{
Logger.Error(ex, "Failed to write results.");
}
};
}
writeOp = writeOp?.ContinueWith(t => { writeAction(); }) ?? Task.Run(writeAction);
writeOp = writeOp?.ContinueWith(t => { writeAction(); }) ?? Task.Run((Action)writeAction);
}
private void reloadTeams()

View File

@ -26,7 +26,8 @@ namespace osu.Game.Storyboards.Drawables
protected override Container<DrawableStoryboardLayer> Content => content;
protected override Vector2 DrawScale => new Vector2(Parent.DrawHeight / 480);
public override bool HandleInput => false;
public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
private bool passing = true;
public bool Passing

View File

@ -388,8 +388,10 @@
<Compile Include="Graphics\Containers\ParallaxContainer.cs" />
<Compile Include="Graphics\Containers\ReverseChildIDFillFlowContainer.cs" />
<Compile Include="Graphics\Containers\SectionsContainer.cs" />
<Compile Include="Graphics\Cursor\IProvideCursor.cs" />
<Compile Include="Graphics\Cursor\MenuCursor.cs" />
<Compile Include="Graphics\Cursor\OsuContextMenuContainer.cs" />
<Compile Include="Graphics\Cursor\CursorOverrideContainer.cs" />
<Compile Include="Graphics\Cursor\OsuTooltipContainer.cs" />
<Compile Include="Graphics\IHasAccentColour.cs" />
<Compile Include="Graphics\OsuColour.cs" />