Merge branch 'master' into large-texture-store

This commit is contained in:
Dan Balasescu 2018-01-03 13:50:49 +09:00 committed by GitHub
commit d167663340
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 312 additions and 158 deletions

@ -1 +1 @@
Subproject commit 6134dafccb3368dac96d837537325c04b89fb8ee
Subproject commit 66421b894444cb9c4b792f9b93a786dcff5589dd

View File

@ -26,7 +26,7 @@ public DrawableHitCircle(HitCircle h) : base(h)
Origin = Anchor.Centre;
Position = HitObject.StackedPosition;
Scale = new Vector2(HitObject.Scale);
Scale = new Vector2(h.Scale);
Children = new Drawable[]
{

View File

@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
public class DrawableSpinner : DrawableOsuHitObject
{
private readonly Spinner spinner;
protected readonly Spinner Spinner;
public readonly SpinnerDisc Disc;
public readonly SpinnerTicks Ticks;
@ -50,7 +50,7 @@ public DrawableSpinner(Spinner s) : base(s)
// we are slightly bigger than our parent, to clip the top and bottom of the circle
Height = 1.3f;
spinner = s;
Spinner = s;
Children = new Drawable[]
{
@ -91,7 +91,7 @@ public DrawableSpinner(Spinner s) : base(s)
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
Disc = new SpinnerDisc(spinner)
Disc = new SpinnerDisc(Spinner)
{
Scale = Vector2.Zero,
Anchor = Anchor.Centre,
@ -115,7 +115,7 @@ public DrawableSpinner(Spinner s) : base(s)
};
}
public float Progress => MathHelper.Clamp(Disc.RotationAbsolute / 360 / spinner.SpinsRequired, 0, 1);
public float Progress => MathHelper.Clamp(Disc.RotationAbsolute / 360 / Spinner.SpinsRequired, 0, 1);
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
{
@ -136,7 +136,7 @@ protected override void CheckForJudgements(bool userTriggered, double timeOffset
glow.FadeColour(completeColour, duration);
}
if (!userTriggered && Time.Current >= spinner.EndTime)
if (!userTriggered && Time.Current >= Spinner.EndTime)
{
if (Progress >= 1)
AddJudgement(new OsuJudgement { Result = HitResult.Great });
@ -144,7 +144,7 @@ protected override void CheckForJudgements(bool userTriggered, double timeOffset
AddJudgement(new OsuJudgement { Result = HitResult.Good });
else if (Progress > .75)
AddJudgement(new OsuJudgement { Result = HitResult.Meh });
else if (Time.Current >= spinner.EndTime)
else if (Time.Current >= Spinner.EndTime)
AddJudgement(new OsuJudgement { Result = HitResult.Miss });
}
}
@ -180,7 +180,7 @@ protected override void UpdateAfterChildren()
Ticks.Rotation = Disc.Rotation;
spmCounter.SetRotation(Disc.RotationAbsolute);
float relativeCircleScale = spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight;
float relativeCircleScale = Spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight;
Disc.ScaleTo(relativeCircleScale + (1 - relativeCircleScale) * Progress, 200, Easing.OutQuint);
symbol.RotateTo(Disc.Rotation / 2, 500, Easing.OutQuint);
@ -190,22 +190,22 @@ protected override void UpdatePreemptState()
{
base.UpdatePreemptState();
circleContainer.ScaleTo(spinner.Scale * 0.3f);
circleContainer.ScaleTo(spinner.Scale, TIME_PREEMPT / 1.4f, Easing.OutQuint);
circleContainer.ScaleTo(Spinner.Scale * 0.3f);
circleContainer.ScaleTo(Spinner.Scale, TIME_PREEMPT / 1.4f, Easing.OutQuint);
Disc.RotateTo(-720);
symbol.RotateTo(-720);
mainContainer
.ScaleTo(0)
.ScaleTo(spinner.Scale * circle.DrawHeight / DrawHeight * 1.4f, TIME_PREEMPT - 150, Easing.OutQuint)
.ScaleTo(Spinner.Scale * circle.DrawHeight / DrawHeight * 1.4f, TIME_PREEMPT - 150, Easing.OutQuint)
.Then()
.ScaleTo(1, 500, Easing.OutQuint);
}
protected override void UpdateCurrentState(ArmedState state)
{
var sequence = this.Delay(spinner.Duration).FadeOut(160);
var sequence = this.Delay(Spinner.Duration).FadeOut(160);
switch (state)
{

View File

@ -11,11 +11,13 @@
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Tests.Visual;
using OpenTK;
using osu.Game.Rulesets.Osu.Mods;
using OpenTK.Graphics;
using osu.Game.Rulesets.Osu.Judgements;
using System.Collections.Generic;
using System;
using osu.Game.Rulesets.Mods;
using System.Linq;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Osu.Tests
{
@ -24,33 +26,34 @@ public class TestCaseHitCircle : OsuTestCase
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(HitCircle),
typeof(OsuModHidden),
typeof(DrawableHitCircle)
};
private readonly Container content;
protected override Container<Drawable> Content => content;
private bool auto;
private bool hidden;
private int depthIndex;
private int circleSize;
private float circleScale = 1;
protected readonly List<Mod> Mods = new List<Mod>();
public TestCaseHitCircle()
{
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
AddStep("Single", () => testSingle());
AddStep("Stream", testStream);
AddToggleStep("Auto", v => auto = v);
AddToggleStep("Hidden", v => hidden = v);
AddSliderStep("CircleSize", 0, 10, 0, s => circleSize = s);
AddSliderStep("CircleScale", 0.5f, 2, 1, s => circleScale = s);
AddStep("Miss Big Single", () => testSingle(2));
AddStep("Miss Medium Single", () => testSingle(5));
AddStep("Miss Small Single", () => testSingle(7));
AddStep("Hit Big Single", () => testSingle(2, true));
AddStep("Hit Medium Single", () => testSingle(5, true));
AddStep("Hit Small Single", () => testSingle(7, true));
AddStep("Miss Big Stream", () => testStream(2));
AddStep("Miss Medium Stream", () => testStream(5));
AddStep("Miss Small Stream", () => testStream(7));
AddStep("Hit Big Stream", () => testStream(2, true));
AddStep("Hit Medium Stream", () => testStream(5, true));
AddStep("Hit Small Stream", () => testStream(7, true));
}
private void testSingle(double timeOffset = 0, Vector2? positionOffset = null)
private void testSingle(float circleSize, bool auto = false, double timeOffset = 0, Vector2? positionOffset = null)
{
positionOffset = positionOffset ?? Vector2.Zero;
@ -66,27 +69,23 @@ private void testSingle(double timeOffset = 0, Vector2? positionOffset = null)
var drawable = new TestDrawableHitCircle(circle, auto)
{
Anchor = Anchor.Centre,
Scale = new Vector2(circleScale),
Depth = depthIndex++
};
if (auto)
drawable.State.Value = ArmedState.Hit;
if (hidden)
new OsuModHidden().ApplyToDrawableHitObjects(new [] { drawable });
foreach (var mod in Mods.OfType<IApplicableToDrawableHitObjects>())
mod.ApplyToDrawableHitObjects(new[] { drawable });
Add(drawable);
}
private void testStream()
private void testStream(float circleSize, bool auto = false)
{
Vector2 pos = Vector2.Zero;
Vector2 pos = new Vector2(-250, 0);
for (int i = 0; i <= 1000; i += 100)
{
testSingle(i, pos);
pos += new Vector2(10);
testSingle(circleSize, auto, i, pos);
pos.X += 50;
}
}
@ -103,13 +102,15 @@ protected override void CheckForJudgements(bool userTriggered, double timeOffset
{
if (auto && !userTriggered && timeOffset > 0)
{
// pretend we really hit it
// force success
AddJudgement(new OsuJudgement
{
Result = HitObject.ScoreResultForOffset(timeOffset)
Result = HitResult.Great
});
State.Value = ArmedState.Hit;
}
base.CheckForJudgements(userTriggered, timeOffset);
else
base.CheckForJudgements(userTriggered, timeOffset);
}
}
}

View File

@ -0,0 +1,22 @@
// Copyright (c) 2007-2017 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 System.Linq;
using NUnit.Framework;
using osu.Game.Rulesets.Osu.Mods;
namespace osu.Game.Rulesets.Osu.Tests
{
[Ignore("getting CI working")]
public class TestCaseHitCircleHidden : TestCaseHitCircle
{
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
public TestCaseHitCircleHidden()
{
Mods.Add(new OsuModHidden());
}
}
}

View File

@ -13,8 +13,10 @@
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Tests.Visual;
using OpenTK;
using osu.Game.Rulesets.Osu.Mods;
using OpenTK.Graphics;
using osu.Game.Rulesets.Mods;
using System.Linq;
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
namespace osu.Game.Rulesets.Osu.Tests
{
@ -23,70 +25,94 @@ public class TestCaseSlider : OsuTestCase
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(Slider),
typeof(HitCircle),
typeof(OsuModHidden),
typeof(SliderBall),
typeof(SliderBody),
typeof(DrawableSlider),
typeof(DrawableHitCircle),
typeof(DrawableSliderTick),
typeof(DrawableRepeatPoint)
typeof(DrawableRepeatPoint),
typeof(DrawableOsuHitObject)
};
private readonly Container content;
protected override Container<Drawable> Content => content;
private bool hidden;
private int repeats;
private int depthIndex;
private int circleSize;
private float circleScale = 1;
private double speedMultiplier = 2;
private double sliderMultiplier = 2;
protected readonly List<Mod> Mods = new List<Mod>();
public TestCaseSlider()
{
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
AddStep("Single", () => testSingle());
AddStep("Stream", testStream);
AddStep("Repeated", () => testRepeated(repeats));
AddToggleStep("Hidden", v => hidden = v);
AddSliderStep("Repeats", 1, 10, 1, s => repeats = s);
AddSliderStep("CircleSize", 0, 10, 0, s => circleSize = s);
AddSliderStep("CircleScale", 0.5f, 2, 1, s => circleScale = s);
AddSliderStep("SpeedMultiplier", 0.1, 10, 2, s => speedMultiplier = s);
AddSliderStep("SliderMultiplier", 0.1, 10, 2, s => sliderMultiplier = s);
AddStep("Big Single", () => testSimpleBig());
AddStep("Medium Single", () => testSimpleMedium());
AddStep("Small Single", () => testSimpleSmall());
AddStep("Big 1 Repeat", () => testSimpleBig(1));
AddStep("Medium 1 Repeat", () => testSimpleMedium(1));
AddStep("Small 1 Repeat", () => testSimpleSmall(1));
AddStep("Big 2 Repeats", () => testSimpleBig(2));
AddStep("Medium 2 Repeats", () => testSimpleMedium(2));
AddStep("Small 2 Repeats", () => testSimpleSmall(2));
AddStep("Slow Slider", testSlowSpeed); // slow long sliders take ages already so no repeat steps
AddStep("Slow Short Slider", () => testShortSlowSpeed());
AddStep("Slow Short Slider 1 Repeats", () => testShortSlowSpeed(1));
AddStep("Slow Short Slider 2 Repeats", () => testShortSlowSpeed(2));
AddStep("Fast Slider", () => testHighSpeed());
AddStep("Fast Slider 1 Repeat", () => testHighSpeed(1));
AddStep("Fast Slider 2 Repeats", () => testHighSpeed(2));
AddStep("Fast Short Slider", () => testShortHighSpeed());
AddStep("Fast Short Slider 1 Repeat", () => testShortHighSpeed(1));
AddStep("Fast Short Slider 2 Repeats", () => testShortHighSpeed(2));
AddStep("Perfect Curve", testCurve);
// TODO more curve types?
}
private void testSingle(double timeOffset = 0, Vector2? positionOffset = null)
private void testSimpleBig(int repeats = 0) => createSlider(2, repeats: repeats);
private void testSimpleMedium(int repeats = 0) => createSlider(5, repeats: repeats);
private void testSimpleSmall(int repeats = 0) => createSlider(7, repeats: repeats);
private void testSlowSpeed() => createSlider(speedMultiplier: 0.5);
private void testShortSlowSpeed(int repeats = 0) => createSlider(distance: 100, repeats: repeats, speedMultiplier: 0.5);
private void testHighSpeed(int repeats = 0) => createSlider(repeats: repeats, speedMultiplier: 15);
private void testShortHighSpeed(int repeats = 0) => createSlider(distance: 100, repeats: repeats, speedMultiplier: 15);
private void createSlider(float circleSize = 2, float distance = 400, int repeats = 0, double speedMultiplier = 2)
{
positionOffset = positionOffset ?? Vector2.Zero;
repeats++; // The first run through the slider is considered a repeat
var repeatSamples = new List<List<SampleInfo>>();
if (repeats > 1)
{
for (int i = 0; i < repeats; i++)
repeatSamples.Add(new List<SampleInfo>());
}
var slider = new Slider
{
StartTime = Time.Current + 1000 + timeOffset,
Position = new Vector2(-200, 0) + positionOffset.Value,
StartTime = Time.Current + 1000,
Position = new Vector2(-(distance / 2), 0),
ComboColour = Color4.LightSeaGreen,
ControlPoints = new List<Vector2>
{
new Vector2(-200, 0) + positionOffset.Value,
new Vector2(400, 0) + positionOffset.Value,
new Vector2(-(distance / 2), 0),
new Vector2(distance / 2, 0),
},
Distance = 400
Distance = distance,
RepeatCount = repeats,
RepeatSamples = repeatSamples
};
addSlider(slider);
addSlider(slider, circleSize, speedMultiplier);
}
private void testRepeated(int repeats)
private void testCurve()
{
// The first run through the slider is considered a repeat
repeats++;
var repeatSamples = new List<List<SampleInfo>>();
for (int i = 0; i < repeats; i++)
repeatSamples.Add(new List<SampleInfo>());
var slider = new Slider
{
StartTime = Time.Current + 1000,
@ -95,52 +121,32 @@ private void testRepeated(int repeats)
ControlPoints = new List<Vector2>
{
new Vector2(-200, 0),
new Vector2(400, 0),
new Vector2(0, 200),
new Vector2(200, 0)
},
Distance = 400,
RepeatCount = repeats,
RepeatSamples = repeatSamples
Distance = 600
};
addSlider(slider);
addSlider(slider, 2, 3);
}
private void testStream()
{
Vector2 pos = Vector2.Zero;
for (int i = 0; i <= 1000; i += 100)
{
testSingle(i, pos);
pos += new Vector2(10);
}
}
private void addSlider(Slider slider)
private void addSlider(Slider slider, float circleSize, double speedMultiplier)
{
var cpi = new ControlPointInfo();
cpi.DifficultyPoints.Add(new DifficultyControlPoint { SpeedMultiplier = speedMultiplier });
var difficulty = new BeatmapDifficulty
{
SliderMultiplier = (float)sliderMultiplier,
CircleSize = circleSize
};
slider.ApplyDefaults(cpi, difficulty);
slider.ApplyDefaults(cpi, new BeatmapDifficulty { CircleSize = circleSize });
var drawable = new DrawableSlider(slider)
{
Anchor = Anchor.Centre,
Scale = new Vector2(circleScale),
Depth = depthIndex++
};
if (hidden)
new OsuModHidden().ApplyToDrawableHitObjects(new [] { drawable });
foreach (var mod in Mods.OfType<IApplicableToDrawableHitObjects>())
mod.ApplyToDrawableHitObjects(new[] { drawable });
Add(drawable);
}
}
}

View File

@ -0,0 +1,22 @@
// Copyright (c) 2007-2017 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 System.Linq;
using NUnit.Framework;
using osu.Game.Rulesets.Osu.Mods;
namespace osu.Game.Rulesets.Osu.Tests
{
[Ignore("getting CI working")]
public class TestCaseSliderHidden : TestCaseSlider
{
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
public TestCaseSliderHidden()
{
Mods.Add(new OsuModHidden());
}
}
}

View File

@ -3,15 +3,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
@ -21,46 +22,67 @@ public class TestCaseSpinner : OsuTestCase
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(Spinner),
typeof(OsuModHidden),
typeof(DrawableSpinner)
typeof(SpinnerDisc),
typeof(DrawableSpinner),
typeof(DrawableOsuHitObject)
};
private readonly Container content;
protected override Container<Drawable> Content => content;
private bool hidden;
private int depthIndex;
private int circleSize;
private float circleScale = 1;
protected readonly List<Mod> Mods = new List<Mod>();
public TestCaseSpinner()
{
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
AddStep("Single", testSingle);
AddToggleStep("Hidden", v => hidden = v);
AddSliderStep("CircleSize", 0, 10, 0, s => circleSize = s);
AddSliderStep("CircleScale", 0.5f, 2, 1, s => circleScale = s);
AddStep("Miss Big", () => testSingle(2));
AddStep("Miss Medium", () => testSingle(5));
AddStep("Miss Small", () => testSingle(7));
AddStep("Hit Big", () => testSingle(2, true));
AddStep("Hit Medium", () => testSingle(5, true));
AddStep("Hit Small", () => testSingle(7, true));
}
private void testSingle()
private void testSingle(float circleSize, bool auto = false)
{
var spinner = new Spinner { StartTime = Time.Current + 1000, EndTime = Time.Current + 4000 };
spinner.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = circleSize });
var drawable = new DrawableSpinner(spinner)
var drawable = new TestDrawableSpinner(spinner, auto)
{
Anchor = Anchor.Centre,
Scale = new Vector2(circleScale),
Depth = depthIndex++
};
if (hidden)
new OsuModHidden().ApplyToDrawableHitObjects(new [] { drawable });
foreach (var mod in Mods.OfType<IApplicableToDrawableHitObjects>())
mod.ApplyToDrawableHitObjects(new[] { drawable });
Add(drawable);
}
private class TestDrawableSpinner : DrawableSpinner
{
private bool auto;
public TestDrawableSpinner(Spinner s, bool auto) : base(s)
{
this.auto = auto;
}
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
{
if (auto && !userTriggered && Time.Current > Spinner.StartTime + Spinner.Duration / 2 && Progress < 1)
{
// force completion only once to not break human interaction
Disc.RotationAbsolute = Spinner.SpinsRequired * 360;
auto = false;
}
base.CheckForJudgements(userTriggered, timeOffset);
}
}
}
}

View File

@ -0,0 +1,22 @@
// Copyright (c) 2007-2017 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 System.Linq;
using NUnit.Framework;
using osu.Game.Rulesets.Osu.Mods;
namespace osu.Game.Rulesets.Osu.Tests
{
[Ignore("getting CI working")]
public class TestCaseSpinnerHidden : TestCaseSpinner
{
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
public TestCaseSpinnerHidden()
{
Mods.Add(new OsuModHidden());
}
}
}

View File

@ -88,9 +88,12 @@
<Compile Include="OsuInputManager.cs" />
<Compile Include="Replays\OsuReplayInputHandler.cs" />
<Compile Include="Tests\TestCaseHitCircle.cs" />
<Compile Include="Tests\TestCaseHitCircleHidden.cs" />
<Compile Include="Tests\TestCasePerformancePoints.cs" />
<Compile Include="Tests\TestCaseSlider.cs" />
<Compile Include="Tests\TestCaseSliderHidden.cs" />
<Compile Include="Tests\TestCaseSpinner.cs" />
<Compile Include="Tests\TestCaseSpinnerHidden.cs" />
<Compile Include="UI\Cursor\CursorTrail.cs" />
<Compile Include="UI\Cursor\GameplayCursor.cs" />
<Compile Include="UI\OsuSettings.cs" />

View File

@ -15,6 +15,15 @@ public class TestCaseResults : OsuTestCase
{
private BeatmapManager beatmaps;
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(Score),
typeof(Results),
typeof(ResultsPage),
typeof(ResultsPageScore),
typeof(ResultsPageRanking)
};
[BackgroundDependencyLoader]
private void load(BeatmapManager beatmaps)
{

View File

@ -5,6 +5,8 @@
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using OpenTK;
namespace osu.Game.Graphics.Containers
{
@ -22,6 +24,48 @@ private void load(AudioManager audio)
StateChanged += onStateChanged;
}
/// <summary>
/// Whether mouse input should be blocked screen-wide while this overlay is visible.
/// Performing mouse actions outside of the valid extents will hide the overlay but pass the events through.
/// </summary>
public virtual bool BlockScreenWideMouse => BlockPassThroughMouse;
// receive input outside our bounds so we can trigger a close event on ourselves.
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => BlockScreenWideMouse || base.ReceiveMouseInputAt(screenSpacePos);
protected override bool OnWheel(InputState state)
{
// always allow wheel to pass through to stuff outside our DrawRectangle.
if (!base.ReceiveMouseInputAt(state.Mouse.NativeState.Position))
return false;
return BlockPassThroughMouse;
}
protected override bool OnClick(InputState state)
{
if (!base.ReceiveMouseInputAt(state.Mouse.NativeState.Position))
{
State = Visibility.Hidden;
return true;
}
return base.OnClick(state);
}
protected override bool OnDragStart(InputState state)
{
if (!base.ReceiveMouseInputAt(state.Mouse.NativeState.Position))
{
State = Visibility.Hidden;
return true;
}
return base.OnDragStart(state);
}
protected override bool OnDrag(InputState state) => State == Visibility.Hidden;
private void onStateChanged(Visibility visibility)
{
switch (visibility)

View File

@ -27,6 +27,7 @@
using osu.Game.Rulesets;
using osu.Game.Screens.Play;
using osu.Game.Input.Bindings;
using OpenTK.Graphics;
namespace osu.Game
{
@ -284,10 +285,10 @@ void updateScreenOffset()
notifications.Enabled.BindTo(ShowOverlays);
ShowOverlays.ValueChanged += visible =>
ShowOverlays.ValueChanged += show =>
{
//central game screen change logic.
if (!visible)
if (!show)
{
hideAllOverlays();
musicController.State = Visibility.Hidden;
@ -331,10 +332,21 @@ private void forwardLoggedErrorsToNotifications()
}
private Task asyncLoadStream;
private int visibleOverlayCount;
private void loadComponentSingleFile<T>(T d, Action<T> add)
where T : Drawable
{
var focused = d as FocusedOverlayContainer;
if (focused != null)
{
focused.StateChanged += s =>
{
visibleOverlayCount += s == Visibility.Visible ? 1 : -1;
screenStack.FadeColour(visibleOverlayCount > 0 ? OsuColour.Gray(0.5f) : Color4.White, 500, Easing.OutQuint);
};
}
// schedule is here to ensure that all component loads are done after LoadComplete is run (and thus all dependencies are cached).
// with some better organisation of LoadComplete to do construction and dependency caching in one step, followed by calls to loadComponentSingleFile,
// we could avoid the need for scheduling altogether.

View File

@ -240,8 +240,6 @@ public void APIStateChanged(APIAccess api, APIState state)
public override bool AcceptsFocus => true;
protected override bool OnClick(InputState state) => true;
protected override void OnFocus(InputState state)
{
//this is necessary as textbox is masked away and therefore can't get focus :(

View File

@ -65,10 +65,10 @@ public MusicController()
AlwaysPresent = true;
}
protected override bool OnDragStart(InputState state) => true;
protected override bool OnDrag(InputState state)
{
if (base.OnDrag(state)) return true;
Trace.Assert(state.Mouse.PositionMouseDown != null, "state.Mouse.PositionMouseDown != null");
Vector2 change = state.Mouse.Position - state.Mouse.PositionMouseDown.Value;
@ -77,7 +77,7 @@ protected override bool OnDrag(InputState state)
change *= change.Length <= 0 ? 0 : (float)Math.Pow(change.Length, 0.7f) / change.Length;
dragContainer.MoveTo(change);
return base.OnDrag(state);
return true;
}
protected override bool OnDragEnd(InputState state)

View File

@ -177,8 +177,6 @@ protected override void PopOut()
public override bool AcceptsFocus => true;
protected override bool OnClick(InputState state) => true;
protected override void OnFocus(InputState state)
{
GetContainingInputManager().ChangeFocus(searchTextBox);

View File

@ -62,10 +62,10 @@ public Toolbar()
new ToolbarChatButton(),
new ToolbarSocialButton(),
new ToolbarMusicButton(),
new ToolbarButton
{
Icon = FontAwesome.fa_search
},
//new ToolbarButton
//{
// Icon = FontAwesome.fa_search
//},
userArea = new ToolbarUserArea(),
new ToolbarNotificationButton(),
}

View File

@ -10,7 +10,6 @@
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
@ -34,15 +33,6 @@ public class UserProfileOverlay : WaveOverlayContainer
public const float CONTENT_X_MARGIN = 50;
// receive input outside our bounds so we can trigger a close event on ourselves.
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => true;
protected override bool OnClick(InputState state)
{
State = Visibility.Hidden;
return true;
}
public UserProfileOverlay()
{
FirstWaveColour = OsuColour.Gray(0.4f);

View File

@ -29,5 +29,6 @@ public class ModAutoplay : Mod
public override string Description => "Watch a perfect automated play through the song";
public override double ScoreMultiplier => 0;
public override Type[] IncompatibleMods => new[] { typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail) };
public override bool AllowFail => false;
}
}

View File

@ -251,16 +251,16 @@ private void load(OsuColour colours)
{
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
Text = datetime.ToString("HH:mm"),
Padding = new MarginPadding { Left = 10, Right = 10, Top = 5, Bottom = 5 },
Text = datetime.ToShortDateString(),
Padding = new MarginPadding { Horizontal = 10, Vertical = 5 },
Colour = Color4.White,
},
new OsuSpriteText
{
Origin = Anchor.CentreRight,
Anchor = Anchor.CentreRight,
Text = datetime.ToString("yyyy/MM/dd"),
Padding = new MarginPadding { Left = 10, Right = 10, Top = 5, Bottom = 5 },
Text = datetime.ToShortTimeString(),
Padding = new MarginPadding { Horizontal = 10, Vertical = 5 },
Colour = Color4.White,
}
};

View File

@ -109,6 +109,13 @@ protected PlaceholderState PlaceholderState
{
if (value == placeholderState) return;
if (value != PlaceholderState.Successful)
{
getScoresRequest?.Cancel();
getScoresRequest = null;
Scores = null;
}
switch (placeholderState = value)
{
case PlaceholderState.NetworkFailure:
@ -211,10 +218,6 @@ private void handleApiStateChange(APIState oldState, APIState newState)
private void updateScores()
{
getScoresRequest?.Cancel();
getScoresRequest = null;
Scores = null;
if (Scope == LeaderboardScope.Local)
{
// TODO: get local scores from wherever here.
@ -234,16 +237,15 @@ private void updateScores()
return;
}
PlaceholderState = PlaceholderState.Retrieving;
loading.Show();
if (Scope != LeaderboardScope.Global && !api.LocalUser.Value.IsSupporter)
{
loading.Hide();
PlaceholderState = PlaceholderState.NotSupporter;
return;
}
PlaceholderState = PlaceholderState.Retrieving;
loading.Show();
getScoresRequest = new GetScoresRequest(Beatmap, osuGame?.Ruleset.Value ?? Beatmap.Ruleset, Scope);
getScoresRequest.Success += r =>
{

View File

@ -25,6 +25,8 @@ public class BeatmapOptionsOverlay : OsuFocusedOverlayContainer
private readonly Box holder;
private readonly FillFlowContainer<BeatmapOptionsButton> buttonsContainer;
public override bool BlockScreenWideMouse => false;
protected override void PopIn()
{
base.PopIn();