diff --git a/.vscode/launch.json b/.vscode/launch.json
index b981556649..c836ff97bc 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -11,7 +11,7 @@
"preLaunchTask": "build",
"runtimeExecutable": null,
"env": {},
- "externalConsole": false
+ "console": "internalConsole"
},
{
"name": "Launch Desktop",
@@ -23,7 +23,7 @@
"preLaunchTask": "build",
"runtimeExecutable": null,
"env": {},
- "externalConsole": false
+ "console": "internalConsole"
},
{
"name": "Attach",
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 0c0e79f7fb..03f5bc4c6c 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -2,25 +2,23 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
- "windows": {
- "command": "msbuild"
- },
- "linux": {
- "command": "xbuild"
- },
- "args": [
- // Ask msbuild to generate full paths for file names.
- "/property:GenerateFullPaths=true"
- ],
"taskSelector": "/t:",
- "showOutput": "silent",
"tasks": [
{
"taskName": "build",
- // Show the output window only if unrecognized errors occur.
+ "isShellCommand": true,
"showOutput": "silent",
+ "command": "xbuild",
+ "windows": {
+ "command": "msbuild"
+ },
+ "args": [
+ // Ask msbuild to generate full paths for file names.
+ "/property:GenerateFullPaths=true"
+ ],
// Use the standard MS compiler pattern to detect errors, warnings and infos
- "problemMatcher": "$msCompile"
+ "problemMatcher": "$msCompile",
+ "isBuildCommand": true
}
]
}
\ No newline at end of file
diff --git a/osu-framework b/osu-framework
index a7c99e06ff..2234013e59 160000
--- a/osu-framework
+++ b/osu-framework
@@ -1 +1 @@
-Subproject commit a7c99e06ff4c3f56fad24bec170eb93f42b1e149
+Subproject commit 2234013e59a99116ee9f9e56a95ff8a6667db2a7
diff --git a/osu.Desktop.Deploy/App.config b/osu.Desktop.Deploy/App.config
index d1da144f50..45685a74a8 100644
--- a/osu.Desktop.Deploy/App.config
+++ b/osu.Desktop.Deploy/App.config
@@ -21,4 +21,16 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj
index 7a3719a25b..901117b026 100644
--- a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj
+++ b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj
@@ -68,9 +68,8 @@
$(SolutionDir)\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Rocks.dll
True
-
- $(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
- True
+
+ $(SolutionDir)\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll
$(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\NuGet.Squirrel.dll
@@ -120,7 +119,7 @@
-
-
-
+
+
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseBeatmapDetails.cs b/osu.Desktop.VisualTests/Tests/TestCaseBeatmapDetails.cs
new file mode 100644
index 0000000000..4a59ad9534
--- /dev/null
+++ b/osu.Desktop.VisualTests/Tests/TestCaseBeatmapDetails.cs
@@ -0,0 +1,65 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Primitives;
+using osu.Framework.Testing;
+using osu.Game.Database;
+using osu.Game.Screens.Select;
+using System.Linq;
+
+namespace osu.Desktop.VisualTests.Tests
+{
+ internal class TestCaseBeatmapDetails : TestCase
+ {
+ public override string Description => "BeatmapDetails tab of BeatmapDetailArea";
+
+ private BeatmapDetails details;
+
+ public override void Reset()
+ {
+ base.Reset();
+
+ Add(details = new BeatmapDetails
+ {
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding(150),
+ Beatmap = new BeatmapInfo
+ {
+ Version = "VisualTest",
+ Metadata = new BeatmapMetadata
+ {
+ Source = "Some guy",
+ Tags = "beatmap metadata example with a very very long list of tags and not much creativity",
+ },
+ Difficulty = new BeatmapDifficulty
+ {
+ CircleSize = 7,
+ ApproachRate = 3.5f,
+ OverallDifficulty = 5.7f,
+ DrainRate = 1,
+ },
+ StarDifficulty = 5.3f,
+ Metrics = new BeatmapMetrics
+ {
+ Ratings = Enumerable.Range(0,10),
+ Fails = Enumerable.Range(lastRange, 100).Select(i => i % 12 - 6),
+ Retries = Enumerable.Range(lastRange - 3, 100).Select(i => i % 12 - 6),
+ },
+ },
+ });
+
+ AddRepeatStep("fail values", newRetryAndFailValues, 10);
+ }
+
+ private int lastRange = 1;
+
+ private void newRetryAndFailValues()
+ {
+ details.Beatmap.Metrics.Fails = Enumerable.Range(lastRange, 100).Select(i => i % 12 - 6);
+ details.Beatmap.Metrics.Retries = Enumerable.Range(lastRange - 3, 100).Select(i => i % 12 - 6);
+ details.Beatmap = details.Beatmap;
+ lastRange += 100;
+ }
+ }
+}
\ No newline at end of file
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseGraph.cs b/osu.Desktop.VisualTests/Tests/TestCaseGraph.cs
new file mode 100644
index 0000000000..7ac795f6f9
--- /dev/null
+++ b/osu.Desktop.VisualTests/Tests/TestCaseGraph.cs
@@ -0,0 +1,42 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using OpenTK;
+using osu.Framework.Graphics;
+using osu.Framework.Testing;
+using osu.Game.Graphics.UserInterface;
+using System.Linq;
+
+namespace osu.Desktop.VisualTests.Tests
+{
+ internal class TestCaseGraph : TestCase
+ {
+ public override string Description => "graph";
+
+ private BarGraph graph;
+
+ public override void Reset()
+ {
+ base.Reset();
+
+ Children = new[]
+ {
+ graph = new BarGraph
+ {
+ RelativeSizeAxes = Axes.Both,
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Size = new Vector2(0.5f),
+ },
+ };
+
+ AddStep("values from 1-10", () => graph.Values = Enumerable.Range(1,10).Select(i => (float)i));
+ AddStep("values from 1-100", () => graph.Values = Enumerable.Range(1, 100).Select(i => (float)i));
+ AddStep("reversed values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Reverse().Select(i => (float)i));
+ AddStep("Bottom to top", () => graph.Direction = BarDirection.BottomToTop);
+ AddStep("Top to bottom", () => graph.Direction = BarDirection.TopToBottom);
+ AddStep("Left to right", () => graph.Direction = BarDirection.LeftToRight);
+ AddStep("Right to left", () => graph.Direction = BarDirection.RightToLeft);
+ }
+ }
+}
\ No newline at end of file
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs
index 99da7d1c73..3d9f3aad79 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs
@@ -99,6 +99,7 @@ namespace osu.Desktop.VisualTests.Tests
AddToggleStep(@"auto", state => { auto = state; load(mode); });
+ BasicSliderBar sliderBar;
Add(new Container
{
Anchor = Anchor.TopRight,
@@ -107,16 +108,17 @@ namespace osu.Desktop.VisualTests.Tests
Children = new Drawable[]
{
new SpriteText { Text = "Playback Speed" },
- new BasicSliderBar
+ sliderBar = new BasicSliderBar
{
Width = 150,
Height = 10,
SelectionColor = Color4.Orange,
- Value = playbackSpeed
}
}
});
+ sliderBar.Current.BindTo(playbackSpeed);
+
framedClock.ProcessFrame();
var clockAdjustContainer = new Container
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs b/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs
index 7e7782662b..b1b9ddbcda 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs
@@ -44,6 +44,8 @@ namespace osu.Desktop.VisualTests.Tests
kc.Add(new KeyCounterKeyboard(key));
});
+ TestSliderBar sliderBar;
+
Add(new Container
{
Anchor = Anchor.TopRight,
@@ -52,16 +54,17 @@ namespace osu.Desktop.VisualTests.Tests
Children = new Drawable[]
{
new SpriteText { Text = "FadeTime" },
- new TestSliderBar
+ sliderBar =new TestSliderBar
{
Width = 150,
Height = 10,
SelectionColor = Color4.Orange,
- Value = bindable
}
}
});
+ sliderBar.Current.BindTo(bindable);
+
Add(kc);
}
private class TestSliderBar : SliderBar where T : struct
diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs
index f36889b02a..624723ed35 100644
--- a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs
@@ -83,10 +83,7 @@ namespace osu.Desktop.VisualTests.Tests
Colour = Color4.Black,
});
- Add(new PlayerLoader(Player = CreatePlayer(beatmap))
- {
- Beatmap = beatmap
- });
+ Add(Player = CreatePlayer(beatmap));
}
protected virtual Player CreatePlayer(WorkingBeatmap beatmap)
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTabControl.cs b/osu.Desktop.VisualTests/Tests/TestCaseTabControl.cs
index 2d3969b822..b72abd1992 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseTabControl.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseTabControl.cs
@@ -36,7 +36,7 @@ namespace osu.Desktop.VisualTests.Tests
filter.PinItem(GroupMode.All);
filter.PinItem(GroupMode.RecentlyPlayed);
- filter.SelectedItem.ValueChanged += newFilter =>
+ filter.Current.ValueChanged += newFilter =>
{
text.Text = "Currently Selected: " + newFilter.ToString();
};
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
index 88a037afee..4e9ff4980e 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
@@ -1,6 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
@@ -11,20 +12,22 @@ using osu.Game.Modes.Taiko.Judgements;
using osu.Game.Modes.Taiko.Objects;
using osu.Game.Modes.Taiko.Objects.Drawables;
using osu.Game.Modes.Taiko.UI;
+using System;
namespace osu.Desktop.VisualTests.Tests
{
internal class TestCaseTaikoPlayfield : TestCase
{
- public override string Description => "Taiko playfield";
+ private const double default_duration = 300;
+ private const float scroll_time = 1000;
- private TaikoPlayfield playfield;
+ public override string Description => "Taiko playfield";
protected override double TimePerAction => default_duration * 2;
- private const double default_duration = 300;
-
- private const float scroll_time = 1000;
+ private readonly Random rng = new Random(1337);
+ private TaikoPlayfield playfield;
+ private Container playfieldContainer;
public override void Reset()
{
@@ -41,15 +44,22 @@ namespace osu.Desktop.VisualTests.Tests
AddStep("Strong Rim", () => addRimHit(true));
AddStep("Add bar line", () => addBarLine(false));
AddStep("Add major bar line", () => addBarLine(true));
-
+ AddStep("Height test 1", () => changePlayfieldSize(1));
+ AddStep("Height test 2", () => changePlayfieldSize(2));
+ AddStep("Height test 3", () => changePlayfieldSize(3));
+ AddStep("Height test 4", () => changePlayfieldSize(4));
+ AddStep("Height test 5", () => changePlayfieldSize(5));
+ AddStep("Reset height", () => changePlayfieldSize(6));
var rateAdjustClock = new StopwatchClock(true) { Rate = 1 };
- Add(new Container
+ Add(playfieldContainer = new Container
{
- Clock = new FramedClock(rateAdjustClock),
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
- Y = 200,
+ Height = TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT,
+ Clock = new FramedClock(rateAdjustClock),
Children = new[]
{
playfield = new TaikoPlayfield()
@@ -57,21 +67,63 @@ namespace osu.Desktop.VisualTests.Tests
});
}
+ private void changePlayfieldSize(int step)
+ {
+ // Add new hits
+ switch (step)
+ {
+ case 1:
+ addCentreHit(false);
+ break;
+ case 2:
+ addCentreHit(true);
+ break;
+ case 3:
+ addDrumRoll(false);
+ break;
+ case 4:
+ addDrumRoll(true);
+ break;
+ case 5:
+ addSwell(1000);
+ playfieldContainer.Delay(scroll_time - 100);
+ break;
+ }
+
+ // Tween playfield height
+ switch (step)
+ {
+ default:
+ playfieldContainer.ResizeTo(new Vector2(1, rng.Next(25, 400)), 500);
+ break;
+ case 6:
+ playfieldContainer.ResizeTo(new Vector2(1, TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT), 500);
+ break;
+ }
+ }
+
private void addHitJudgement()
{
TaikoHitResult hitResult = RNG.Next(2) == 0 ? TaikoHitResult.Good : TaikoHitResult.Great;
- playfield.OnJudgement(new DrawableTestHit(new Hit())
+ var h = new DrawableTestHit(new Hit())
{
X = RNG.NextSingle(hitResult == TaikoHitResult.Good ? -0.1f : -0.05f, hitResult == TaikoHitResult.Good ? 0.1f : 0.05f),
Judgement = new TaikoJudgement
{
Result = HitResult.Hit,
TaikoResult = hitResult,
- TimeOffset = 0,
- SecondHit = RNG.Next(10) == 0
+ TimeOffset = 0
}
- });
+ };
+
+ playfield.OnJudgement(h);
+
+ if (RNG.Next(10) == 0)
+ {
+ h.Judgement.SecondHit = true;
+ playfield.OnJudgement(h);
+ }
}
private void addMissJudgement()
diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
index 99abf3fa41..d75bb94308 100644
--- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
+++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
@@ -83,22 +83,20 @@
-
- $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll
- True
+
+ $(SolutionDir)\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll
-
- ..\packages\SharpCompress.0.15.1\lib\net45\SharpCompress.dll
- True
+
+ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll
+
+
+ $(SolutionDir)\packages\SharpCompress.0.15.2\lib\net45\SharpCompress.dll
False
$(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll
-
- $(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
-
$(SolutionDir)\packages\SQLiteNetExtensions.1.3.0\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\SQLiteNetExtensions.dll
@@ -187,8 +185,10 @@
+
+
diff --git a/osu.Desktop.VisualTests/packages.config b/osu.Desktop.VisualTests/packages.config
index 5a30c50600..cad2ffff0d 100644
--- a/osu.Desktop.VisualTests/packages.config
+++ b/osu.Desktop.VisualTests/packages.config
@@ -4,9 +4,9 @@ Copyright (c) 2007-2017 ppy Pty Ltd .
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
-
-
-
+
+
+
diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs
index 70925f6cf4..9532652bfe 100644
--- a/osu.Desktop/Overlays/VersionManager.cs
+++ b/osu.Desktop/Overlays/VersionManager.cs
@@ -189,19 +189,24 @@ namespace osu.Desktop.Overlays
private class UpdateProgressNotification : ProgressNotification
{
+ private OsuGame game;
+
protected override Notification CreateCompletionNotification() => new ProgressCompletionNotification()
{
Text = @"Update ready to install. Click to restart!",
Activated = () =>
{
- UpdateManager.RestartApp();
+ UpdateManager.RestartAppWhenExited();
+ game.GracefullyExit();
return true;
}
};
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OsuColour colours, OsuGame game)
{
+ this.game = game;
+
IconContent.Add(new Drawable[]
{
new Box
diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj
index fbc342d695..dbd26b4640 100644
--- a/osu.Desktop/osu.Desktop.csproj
+++ b/osu.Desktop/osu.Desktop.csproj
@@ -124,8 +124,7 @@
True
- $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll
- True
+ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll
$(SolutionDir)\packages\Splat.2.0.0\lib\Net45\Splat.dll
diff --git a/osu.Desktop/packages.config b/osu.Desktop/packages.config
index be9b65f0c6..60e8182c82 100644
--- a/osu.Desktop/packages.config
+++ b/osu.Desktop/packages.config
@@ -7,7 +7,7 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
-
+
\ No newline at end of file
diff --git a/osu.Game.Modes.Catch/UI/CatchPlayfield.cs b/osu.Game.Modes.Catch/UI/CatchPlayfield.cs
index cf1a665470..f8792a7fd5 100644
--- a/osu.Game.Modes.Catch/UI/CatchPlayfield.cs
+++ b/osu.Game.Modes.Catch/UI/CatchPlayfield.cs
@@ -14,8 +14,7 @@ namespace osu.Game.Modes.Catch.UI
{
public CatchPlayfield()
{
- RelativeSizeAxes = Axes.Y;
- Size = new Vector2(512, 0.9f);
+ Size = new Vector2(1, 0.9f);
Anchor = Anchor.BottomCentre;
Origin = Anchor.BottomCentre;
diff --git a/osu.Game.Modes.Catch/osu.Game.Modes.Catch.csproj b/osu.Game.Modes.Catch/osu.Game.Modes.Catch.csproj
index 593d8db4f6..50b1a095af 100644
--- a/osu.Game.Modes.Catch/osu.Game.Modes.Catch.csproj
+++ b/osu.Game.Modes.Catch/osu.Game.Modes.Catch.csproj
@@ -33,8 +33,7 @@
- $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll
- True
+ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll
@@ -84,7 +83,7 @@
-
-
+
\ No newline at end of file
diff --git a/osu.Game.Modes.Mania/UI/ManiaPlayfield.cs b/osu.Game.Modes.Mania/UI/ManiaPlayfield.cs
index 670d18f71f..deb4ebac25 100644
--- a/osu.Game.Modes.Mania/UI/ManiaPlayfield.cs
+++ b/osu.Game.Modes.Mania/UI/ManiaPlayfield.cs
@@ -15,8 +15,7 @@ namespace osu.Game.Modes.Mania.UI
{
public ManiaPlayfield(int columns)
{
- RelativeSizeAxes = Axes.Both;
- Size = new Vector2(columns / 20f, 1f);
+ Size = new Vector2(0.8f, 1f);
Anchor = Anchor.BottomCentre;
Origin = Anchor.BottomCentre;
diff --git a/osu.Game.Modes.Mania/osu.Game.Modes.Mania.csproj b/osu.Game.Modes.Mania/osu.Game.Modes.Mania.csproj
index cc925d417a..896e9c68c6 100644
--- a/osu.Game.Modes.Mania/osu.Game.Modes.Mania.csproj
+++ b/osu.Game.Modes.Mania/osu.Game.Modes.Mania.csproj
@@ -33,8 +33,7 @@
- $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll
- True
+ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll
@@ -89,7 +88,7 @@
-
-
+
\ No newline at end of file
diff --git a/osu.Game.Modes.Osu/OsuKeyConversionInputManager.cs b/osu.Game.Modes.Osu/OsuKeyConversionInputManager.cs
index 986240b37f..567c7a35b1 100644
--- a/osu.Game.Modes.Osu/OsuKeyConversionInputManager.cs
+++ b/osu.Game.Modes.Osu/OsuKeyConversionInputManager.cs
@@ -42,14 +42,14 @@ namespace osu.Game.Modes.Osu
{
if (mouseDisabled.Value)
{
- mouse.PressedButtons.Remove(MouseButton.Left);
- mouse.PressedButtons.Remove(MouseButton.Right);
+ mouse.SetPressed(MouseButton.Left, false);
+ mouse.SetPressed(MouseButton.Right, false);
}
if (leftViaKeyboard)
- mouse.PressedButtons.Add(MouseButton.Left);
+ mouse.SetPressed(MouseButton.Left, true);
if (rightViaKeyboard)
- mouse.PressedButtons.Add(MouseButton.Right);
+ mouse.SetPressed(MouseButton.Right, true);
}
}
}
diff --git a/osu.Game.Modes.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Modes.Osu/Scoring/OsuScoreProcessor.cs
index 0bd587e8ea..3b798a2fad 100644
--- a/osu.Game.Modes.Osu/Scoring/OsuScoreProcessor.cs
+++ b/osu.Game.Modes.Osu/Scoring/OsuScoreProcessor.cs
@@ -35,11 +35,9 @@ namespace osu.Game.Modes.Osu.Scoring
switch (judgement.Result)
{
case HitResult.Hit:
- Combo.Value++;
Health.Value += 0.1f;
break;
case HitResult.Miss:
- Combo.Value = 0;
Health.Value -= 0.2f;
break;
}
diff --git a/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs b/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs
index ca9ff6fc61..7e314c5ba1 100644
--- a/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs
+++ b/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs
@@ -1,6 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using OpenTK;
using osu.Game.Beatmaps;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Osu.Beatmaps;
@@ -46,5 +47,7 @@ namespace osu.Game.Modes.Osu.UI
return new DrawableSpinner(spinner);
return null;
}
+
+ protected override Vector2 GetPlayfieldAspectAdjust() => new Vector2(0.75f);
}
}
diff --git a/osu.Game.Modes.Osu/UI/OsuPlayfield.cs b/osu.Game.Modes.Osu/UI/OsuPlayfield.cs
index d89bbfd131..4164607b4d 100644
--- a/osu.Game.Modes.Osu/UI/OsuPlayfield.cs
+++ b/osu.Game.Modes.Osu/UI/OsuPlayfield.cs
@@ -38,8 +38,6 @@ namespace osu.Game.Modes.Osu.UI
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
- RelativeSizeAxes = Axes.Both;
- Size = new Vector2(0.75f);
Add(new Drawable[]
{
diff --git a/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj b/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj
index 55322e855e..21f0f03d8c 100644
--- a/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj
+++ b/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj
@@ -34,8 +34,7 @@
- $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll
- True
+ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll
@@ -104,7 +103,7 @@
-
-
+
\ No newline at end of file
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Modes.Taiko/Objects/Drawables/DrawableHit.cs
index f325026be9..167fbebd7b 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableHit.cs
+++ b/osu.Game.Modes.Taiko/Objects/Drawables/DrawableHit.cs
@@ -6,6 +6,7 @@ using System.Linq;
using osu.Framework.Graphics;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Taiko.Judgements;
+using osu.Game.Modes.Taiko.Objects.Drawables.Pieces;
using OpenTK.Input;
namespace osu.Game.Modes.Taiko.Objects.Drawables
@@ -66,6 +67,10 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables
{
Delay(HitObject.StartTime - Time.Current + Judgement.TimeOffset, true);
+ var circlePiece = MainPiece as CirclePiece;
+
+ circlePiece?.FlashBox.Flush();
+
switch (State)
{
case ArmedState.Idle:
@@ -77,6 +82,16 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables
case ArmedState.Hit:
FadeOut(600);
+ var flash = circlePiece?.FlashBox;
+ if (flash != null)
+ {
+ flash.FadeTo(0.9f);
+ flash.FadeOut(300);
+ }
+
+
+ FadeOut(800);
+
const float gravity_time = 300;
const float gravity_travel_height = 200;
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Modes.Taiko/Objects/Drawables/DrawableSwell.cs
index e1a590a025..1e440df69a 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableSwell.cs
+++ b/osu.Game.Modes.Taiko/Objects/Drawables/DrawableSwell.cs
@@ -65,7 +65,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Alpha = 0,
- Size = new Vector2(TaikoHitObject.CIRCLE_RADIUS * 2),
+ Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER),
BlendingMode = BlendingMode.Additive,
Masking = true,
Children = new []
@@ -82,7 +82,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables
Name = "Target ring (thick border)",
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Size = new Vector2(TaikoHitObject.CIRCLE_RADIUS * 2),
+ Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER),
Masking = true,
BorderThickness = target_ring_thick_border,
BlendingMode = BlendingMode.Additive,
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
index 6ea1494ea7..216e05ebc4 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
+++ b/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
@@ -19,15 +19,10 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
///
public class CirclePiece : TaikoPiece
{
- public const float SYMBOL_SIZE = TaikoHitObject.CIRCLE_RADIUS * 2f * 0.45f;
+ public const float SYMBOL_SIZE = TaikoHitObject.DEFAULT_CIRCLE_DIAMETER * 0.45f;
public const float SYMBOL_BORDER = 8;
public const float SYMBOL_INNER_SIZE = SYMBOL_SIZE - 2 * SYMBOL_BORDER;
- ///
- /// The amount to scale up the base circle to show it as a "strong" piece.
- ///
- private const float strong_scale = 1.5f;
-
///
/// The colour of the inner circle and outer glows.
///
@@ -64,6 +59,8 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
private readonly Container background;
+ public Box FlashBox;
+
public CirclePiece(bool isStrong = false)
{
AddInternal(new Drawable[]
@@ -104,11 +101,13 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
Masking = true,
Children = new[]
{
- new Box
+ FlashBox = new Box
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
+ Colour = Color4.White,
+ BlendingMode = BlendingMode.Additive,
Alpha = 0,
AlwaysPresent = true
}
@@ -125,10 +124,10 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
if (isStrong)
{
- Size *= strong_scale;
+ Size *= TaikoHitObject.STRONG_CIRCLE_DIAMETER_SCALE;
//default for symbols etc.
- Content.Scale *= strong_scale;
+ Content.Scale *= TaikoHitObject.STRONG_CIRCLE_DIAMETER_SCALE;
}
}
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs b/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs
index a0c8865c59..2220438a4a 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs
+++ b/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs
@@ -39,7 +39,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
public TaikoPiece()
{
//just a default
- Size = new Vector2(TaikoHitObject.CIRCLE_RADIUS * 2);
+ Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER);
}
}
}
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/TickPiece.cs b/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/TickPiece.cs
index 697102eb22..53e795e2e2 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/TickPiece.cs
+++ b/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/TickPiece.cs
@@ -15,12 +15,12 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
/// Any tick that is not the first for a drumroll is not filled, but is instead displayed
/// as a hollow circle. This is what controls the border width of that circle.
///
- private const float tick_border_width = TaikoHitObject.CIRCLE_RADIUS / 2 / 4;
+ private const float tick_border_width = TaikoHitObject.DEFAULT_CIRCLE_DIAMETER / 16;
///
/// The size of a tick.
///
- private const float tick_size = TaikoHitObject.CIRCLE_RADIUS / 2;
+ private const float tick_size = TaikoHitObject.DEFAULT_CIRCLE_DIAMETER / 4;
private bool filled;
public bool Filled
diff --git a/osu.Game.Modes.Taiko/Objects/TaikoHitObject.cs b/osu.Game.Modes.Taiko/Objects/TaikoHitObject.cs
index 54ab8c5300..ebc9b19d3a 100644
--- a/osu.Game.Modes.Taiko/Objects/TaikoHitObject.cs
+++ b/osu.Game.Modes.Taiko/Objects/TaikoHitObject.cs
@@ -4,15 +4,31 @@
using osu.Game.Beatmaps.Timing;
using osu.Game.Database;
using osu.Game.Modes.Objects;
+using osu.Game.Modes.Taiko.UI;
namespace osu.Game.Modes.Taiko.Objects
{
public abstract class TaikoHitObject : HitObject
{
///
- /// HitCircle radius.
+ /// Diameter of a circle relative to the size of the .
///
- public const float CIRCLE_RADIUS = 42f;
+ public const float PLAYFIELD_RELATIVE_DIAMETER = 0.5f;
+
+ ///
+ /// Scale multiplier for a strong circle.
+ ///
+ public const float STRONG_CIRCLE_DIAMETER_SCALE = 1.5f;
+
+ ///
+ /// Default circle diameter.
+ ///
+ public const float DEFAULT_CIRCLE_DIAMETER = TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT * PLAYFIELD_RELATIVE_DIAMETER;
+
+ ///
+ /// Default strong circle diameter.
+ ///
+ public const float DEFAULT_STRONG_CIRCLE_DIAMETER = DEFAULT_CIRCLE_DIAMETER * STRONG_CIRCLE_DIAMETER_SCALE;
///
/// The time taken from the initial (off-screen) spawn position to the centre of the hit target for a of 1000ms.
diff --git a/osu.Game.Modes.Taiko/UI/HitExplosion.cs b/osu.Game.Modes.Taiko/UI/HitExplosion.cs
index eb43c1a5d0..e4e329523f 100644
--- a/osu.Game.Modes.Taiko/UI/HitExplosion.cs
+++ b/osu.Game.Modes.Taiko/UI/HitExplosion.cs
@@ -18,11 +18,6 @@ namespace osu.Game.Modes.Taiko.UI
///
internal class HitExplosion : CircularContainer
{
- ///
- /// The size multiplier of a hit explosion if a hit object has been hit with the second key.
- ///
- private const float secondhit_size_multiplier = 1.5f;
-
///
/// The judgement this hit explosion visualises.
///
@@ -34,7 +29,7 @@ namespace osu.Game.Modes.Taiko.UI
{
Judgement = judgement;
- Size = new Vector2(TaikoHitObject.CIRCLE_RADIUS * 2);
+ Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER);
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
@@ -85,7 +80,7 @@ namespace osu.Game.Modes.Taiko.UI
///
public void VisualiseSecondHit()
{
- ResizeTo(Size * secondhit_size_multiplier, 50);
+ ResizeTo(Size * TaikoHitObject.STRONG_CIRCLE_DIAMETER_SCALE, 50);
}
}
}
diff --git a/osu.Game.Modes.Taiko/UI/HitTarget.cs b/osu.Game.Modes.Taiko/UI/HitTarget.cs
index a17480628d..b22dc1d647 100644
--- a/osu.Game.Modes.Taiko/UI/HitTarget.cs
+++ b/osu.Game.Modes.Taiko/UI/HitTarget.cs
@@ -15,16 +15,6 @@ namespace osu.Game.Modes.Taiko.UI
///
internal class HitTarget : Container
{
- ///
- /// Diameter of normal hit object circles.
- ///
- private const float normal_diameter = TaikoHitObject.CIRCLE_RADIUS * 2;
-
- ///
- /// Diameter of strong hit object circles.
- ///
- private const float strong_hit_diameter = normal_diameter * 1.5f;
-
///
/// The 1px inner border of the taiko playfield.
///
@@ -37,7 +27,7 @@ namespace osu.Game.Modes.Taiko.UI
public HitTarget()
{
- RelativeSizeAxes = Axes.Y;
+ Size = new Vector2(TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT);
Children = new Drawable[]
{
@@ -47,7 +37,7 @@ namespace osu.Game.Modes.Taiko.UI
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Y = border_offset,
- Size = new Vector2(border_thickness, (TaikoPlayfield.PLAYFIELD_HEIGHT - strong_hit_diameter) / 2f - border_offset),
+ Size = new Vector2(border_thickness, (TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT - TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER) / 2f - border_offset),
Alpha = 0.1f
},
new CircularContainer
@@ -55,7 +45,7 @@ namespace osu.Game.Modes.Taiko.UI
Name = "Strong Hit Ring",
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Size = new Vector2(strong_hit_diameter),
+ Size = new Vector2(TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER),
Masking = true,
BorderColour = Color4.White,
BorderThickness = border_thickness,
@@ -75,7 +65,7 @@ namespace osu.Game.Modes.Taiko.UI
Name = "Normal Hit Ring",
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Size = new Vector2(normal_diameter),
+ Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER),
Masking = true,
BorderColour = Color4.White,
BorderThickness = border_thickness,
@@ -96,7 +86,7 @@ namespace osu.Game.Modes.Taiko.UI
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
Y = -border_offset,
- Size = new Vector2(border_thickness, (TaikoPlayfield.PLAYFIELD_HEIGHT - strong_hit_diameter) / 2f - border_offset),
+ Size = new Vector2(border_thickness, (TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT - TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER) / 2f - border_offset),
Alpha = 0.1f
},
};
diff --git a/osu.Game.Modes.Taiko/UI/InputDrum.cs b/osu.Game.Modes.Taiko/UI/InputDrum.cs
index 0c1e1105cb..d238c38e74 100644
--- a/osu.Game.Modes.Taiko/UI/InputDrum.cs
+++ b/osu.Game.Modes.Taiko/UI/InputDrum.cs
@@ -21,7 +21,7 @@ namespace osu.Game.Modes.Taiko.UI
{
public InputDrum()
{
- Size = new Vector2(TaikoPlayfield.PLAYFIELD_HEIGHT);
+ Size = new Vector2(TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT);
const float middle_split = 10;
diff --git a/osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs b/osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs
index 29fa693d58..32476dff7f 100644
--- a/osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs
+++ b/osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs
@@ -17,6 +17,7 @@ using osu.Game.Modes.Taiko.Objects.Drawables;
using osu.Game.Modes.Taiko.Scoring;
using osu.Game.Modes.UI;
using osu.Game.Modes.Taiko.Replays;
+using OpenTK;
namespace osu.Game.Modes.Taiko.UI
{
@@ -100,6 +101,17 @@ namespace osu.Game.Modes.Taiko.UI
}
}
+ protected override Vector2 GetPlayfieldAspectAdjust()
+ {
+ const float default_relative_height = TaikoPlayfield.DEFAULT_PLAYFIELD_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);
+ }
+
+
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(this);
protected override IBeatmapConverter CreateBeatmapConverter() => new TaikoBeatmapConverter();
diff --git a/osu.Game.Modes.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Modes.Taiko/UI/TaikoPlayfield.cs
index 9e7eb571a1..db3a1bc84e 100644
--- a/osu.Game.Modes.Taiko/UI/TaikoPlayfield.cs
+++ b/osu.Game.Modes.Taiko/UI/TaikoPlayfield.cs
@@ -16,21 +16,21 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics.Primitives;
using System.Linq;
using osu.Game.Modes.Taiko.Objects.Drawables;
+using System;
namespace osu.Game.Modes.Taiko.UI
{
public class TaikoPlayfield : Playfield
{
///
- /// The play field height. This is relative to the size of hit objects
- /// such that the playfield is just a bit larger than strong hits.
+ /// The default play field height.
///
- public const float PLAYFIELD_HEIGHT = TaikoHitObject.CIRCLE_RADIUS * 2 * 2;
+ public const float DEFAULT_PLAYFIELD_HEIGHT = 168f;
///
/// The offset from which the center of the hit target lies at.
///
- private const float hit_target_offset = TaikoHitObject.CIRCLE_RADIUS * 1.5f + 40;
+ private const float hit_target_offset = TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER / 2f + 40;
///
/// The size of the left area of the playfield. This area contains the input drum.
@@ -52,13 +52,11 @@ namespace osu.Game.Modes.Taiko.UI
public TaikoPlayfield()
{
- RelativeSizeAxes = Axes.X;
- Height = PLAYFIELD_HEIGHT;
-
AddInternal(new Drawable[]
{
rightBackgroundContainer = new Container
{
+ Name = "Transparent playfield background",
RelativeSizeAxes = Axes.Both,
BorderThickness = 2,
Masking = true,
@@ -77,76 +75,88 @@ namespace osu.Game.Modes.Taiko.UI
},
}
},
- new Container
+ new ScaleFixContainer
{
- RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding { Left = left_area_size },
- Children = new Drawable[]
+ RelativeSizeAxes = Axes.X,
+ Height = DEFAULT_PLAYFIELD_HEIGHT,
+ Children = new[]
{
new Container
{
- X = hit_target_offset,
+ Name = "Transparent playfield elements",
RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Left = left_area_size },
Children = new Drawable[]
{
- hitExplosionContainer = new Container
+ new Container
{
- Anchor = Anchor.CentreLeft,
+ Name = "Hit target container",
+ X = hit_target_offset,
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
+ {
+ hitExplosionContainer = new Container
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Y,
+ BlendingMode = BlendingMode.Additive
+ },
+ barLineContainer = new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ new HitTarget
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.Centre,
+ },
+ hitObjectContainer = new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ judgementContainer = new Container
+ {
+ RelativeSizeAxes = Axes.Y,
+ BlendingMode = BlendingMode.Additive
+ },
+ },
+ },
+ }
+ },
+ leftBackgroundContainer = new Container
+ {
+ Name = "Left overlay",
+ Size = new Vector2(left_area_size, DEFAULT_PLAYFIELD_HEIGHT),
+ BorderThickness = 1,
+ Children = new Drawable[]
+ {
+ leftBackground = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ new InputDrum
+ {
+ Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Size = new Vector2(TaikoHitObject.CIRCLE_RADIUS * 2),
- BlendingMode = BlendingMode.Additive
+ RelativePositionAxes = Axes.X,
+ Position = new Vector2(0.10f, 0),
+ Scale = new Vector2(0.9f)
},
- barLineContainer = new Container
+ new Box
{
- RelativeSizeAxes = Axes.Both,
+ Anchor = Anchor.TopRight,
+ RelativeSizeAxes = Axes.Y,
+ Width = 10,
+ ColourInfo = Framework.Graphics.Colour.ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.6f), Color4.Black.Opacity(0)),
},
- new HitTarget
- {
- Anchor = Anchor.CentreLeft,
- Origin = Anchor.Centre,
- },
- hitObjectContainer = new Container
- {
- RelativeSizeAxes = Axes.Both,
- },
- judgementContainer = new Container
- {
- RelativeSizeAxes = Axes.Both,
- BlendingMode = BlendingMode.Additive
- },
- },
- },
- }
- },
- leftBackgroundContainer = new Container
- {
- Size = new Vector2(left_area_size, PLAYFIELD_HEIGHT),
- BorderThickness = 1,
- Children = new Drawable[]
- {
- leftBackground = new Box
- {
- RelativeSizeAxes = Axes.Both,
- },
- new InputDrum
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativePositionAxes = Axes.X,
- Position = new Vector2(0.10f, 0),
- Scale = new Vector2(0.9f)
- },
- new Box
- {
- Anchor = Anchor.TopRight,
- RelativeSizeAxes = Axes.Y,
- Width = 10,
- ColourInfo = Framework.Graphics.Colour.ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.6f), Color4.Black.Opacity(0)),
+ }
},
}
},
topLevelHitContainer = new Container
{
+ Name = "Top level hit objects",
RelativeSizeAxes = Axes.Both,
}
});
@@ -208,5 +218,56 @@ namespace osu.Game.Modes.Taiko.UI
else
hitExplosionContainer.Children.FirstOrDefault(e => e.Judgement == judgedObject.Judgement)?.VisualiseSecondHit();
}
+
+ ///
+ /// This is a very special type of container. It serves a similar purpose to , however unlike ,
+ /// this will only adjust the scale relative to the height of its parent and will maintain the original width relative to its parent.
+ ///
+ ///
+ /// By adjusting the scale relative to the height of its parent, the aspect ratio of this container's children is maintained, however this is undesirable
+ /// in the case where the hit object container should not have its width adjusted by scale. To counteract this, another container is nested inside this
+ /// container which takes care of reversing the width adjustment while appearing transparent to the user.
+ ///
+ ///
+ private class ScaleFixContainer : Container
+ {
+ protected override Container Content => widthAdjustmentContainer;
+ private readonly WidthAdjustmentContainer widthAdjustmentContainer;
+
+ ///
+ /// We only want to apply DrawScale in the Y-axis to preserve aspect ratio and doesn't care about having its width adjusted.
+ ///
+ protected override Vector2 DrawScale => Scale * RelativeToAbsoluteFactor.Y / DrawHeight;
+
+ public ScaleFixContainer()
+ {
+ AddInternal(widthAdjustmentContainer = new WidthAdjustmentContainer { ParentDrawScaleReference = () => DrawScale.X });
+ }
+
+ ///
+ /// The container type that reverses the width adjustment.
+ ///
+ private class WidthAdjustmentContainer : Container
+ {
+ ///
+ /// This container needs to know its parent's so it can reverse the width adjustment caused by .
+ ///
+ public Func ParentDrawScaleReference;
+
+ public WidthAdjustmentContainer()
+ {
+ // This container doesn't care about height, it should always fill its parent
+ RelativeSizeAxes = Axes.Y;
+ }
+
+ protected override void Update()
+ {
+ base.Update();
+
+ // Reverse the DrawScale adjustment
+ Width = Parent.DrawSize.X / ParentDrawScaleReference();
+ }
+ }
+ }
}
}
\ No newline at end of file
diff --git a/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj b/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj
index d0981c2500..19ba5c77e4 100644
--- a/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj
+++ b/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj
@@ -33,8 +33,7 @@
- $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll
- True
+ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll
@@ -112,7 +111,7 @@
-
-
+
\ No newline at end of file
diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj
index d01aa77e02..2844528d0c 100644
--- a/osu.Game.Tests/osu.Game.Tests.csproj
+++ b/osu.Game.Tests/osu.Game.Tests.csproj
@@ -29,13 +29,11 @@
false
-
- $(SolutionDir)\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll
- True
+
+ $(SolutionDir)\packages\NUnit.3.6.1\lib\net45\nunit.framework.dll
- $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll
- True
+ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll
diff --git a/osu.Game.Tests/packages.config b/osu.Game.Tests/packages.config
index ca53ef08b0..9972fb41a1 100644
--- a/osu.Game.Tests/packages.config
+++ b/osu.Game.Tests/packages.config
@@ -1,12 +1,11 @@
-
-
-
+
+
\ No newline at end of file
diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs
index 7d7c61b69a..e2f33479c0 100644
--- a/osu.Game/Configuration/OsuConfigManager.cs
+++ b/osu.Game/Configuration/OsuConfigManager.cs
@@ -46,6 +46,7 @@ namespace osu.Game.Configuration
Set(OsuConfig.AutomaticDownload, true).Disabled = true;
Set(OsuConfig.AutomaticDownloadNoVideo, false).Disabled = true;
Set(OsuConfig.BlockNonFriendPM, false).Disabled = true;
+ Set(OsuConfig.Bloom, false).Disabled = true;
Set(OsuConfig.BloomSoftening, false).Disabled = true;
Set(OsuConfig.BossKeyFirstActivation, true).Disabled = true;
Set(OsuConfig.ChatAudibleHighlight, true).Disabled = true;
diff --git a/osu.Game/Database/BeatmapInfo.cs b/osu.Game/Database/BeatmapInfo.cs
index bc6e077633..3e84825919 100644
--- a/osu.Game/Database/BeatmapInfo.cs
+++ b/osu.Game/Database/BeatmapInfo.cs
@@ -41,8 +41,12 @@ namespace osu.Game.Database
[OneToOne(CascadeOperations = CascadeOperation.All)]
public BeatmapDifficulty Difficulty { get; set; }
+ [Ignore]
+ public BeatmapMetrics Metrics { get; set; }
+
public string Path { get; set; }
+ [JsonProperty("file_md5")]
public string Hash { get; set; }
// General
diff --git a/osu.Game/Database/BeatmapMetrics.cs b/osu.Game/Database/BeatmapMetrics.cs
new file mode 100644
index 0000000000..91320110d0
--- /dev/null
+++ b/osu.Game/Database/BeatmapMetrics.cs
@@ -0,0 +1,28 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using System.Collections.Generic;
+
+namespace osu.Game.Database
+{
+ ///
+ /// Beatmap metrics based on acculumated online data from community plays.
+ ///
+ public class BeatmapMetrics
+ {
+ ///
+ /// Total vote counts of user ratings on a scale of 0..length.
+ ///
+ public IEnumerable Ratings { get; set; }
+
+ ///
+ /// Points of failure on a relative time scale (usually 0..100).
+ ///
+ public IEnumerable Fails { get; set; }
+
+ ///
+ /// Points of retry on a relative time scale (usually 0..100).
+ ///
+ public IEnumerable Retries { get; set; }
+ }
+}
diff --git a/osu.Game/Graphics/Cursor/CursorTrail.cs b/osu.Game/Graphics/Cursor/CursorTrail.cs
index 4b5610e840..09d1b99d13 100644
--- a/osu.Game/Graphics/Cursor/CursorTrail.cs
+++ b/osu.Game/Graphics/Cursor/CursorTrail.cs
@@ -13,6 +13,7 @@ using osu.Framework.Graphics.OpenGL.Buffers;
using OpenTK.Graphics.ES30;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Colour;
+using osu.Framework.Timing;
namespace osu.Game.Graphics.Cursor
{
@@ -58,6 +59,9 @@ namespace osu.Game.Graphics.Cursor
public CursorTrail()
{
+ // as we are currently very dependent on having a running clock, let's make our own clock for the time being.
+ Clock = new FramedClock();
+
AlwaysReceiveInput = true;
RelativeSizeAxes = Axes.Both;
@@ -231,4 +235,4 @@ namespace osu.Game.Graphics.Cursor
}
}
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs
index 0fb7f59212..ceb3296bdf 100644
--- a/osu.Game/Graphics/Cursor/MenuCursor.cs
+++ b/osu.Game/Graphics/Cursor/MenuCursor.cs
@@ -80,14 +80,12 @@ namespace osu.Game.Graphics.Cursor
protected override void PopIn()
{
ActiveCursor.FadeTo(1, 250, EasingTypes.OutQuint);
- ActiveCursor.ScaleTo(1, 1000, EasingTypes.OutElastic);
+ ActiveCursor.ScaleTo(1, 400, EasingTypes.OutQuint);
}
protected override void PopOut()
{
- ActiveCursor.FadeTo(0, 1400, EasingTypes.OutQuint);
- ActiveCursor.ScaleTo(1.1f, 100, EasingTypes.Out);
- ActiveCursor.Delay(100);
+ ActiveCursor.FadeTo(0, 900, EasingTypes.OutQuint);
ActiveCursor.ScaleTo(0, 500, EasingTypes.In);
}
diff --git a/osu.Game/Graphics/IHasAccentColour.cs b/osu.Game/Graphics/IHasAccentColour.cs
index f959bc8760..e4647f22fd 100644
--- a/osu.Game/Graphics/IHasAccentColour.cs
+++ b/osu.Game/Graphics/IHasAccentColour.cs
@@ -28,7 +28,7 @@ namespace osu.Game.Graphics
/// The tween easing.
public static void FadeAccent(this IHasAccentColour accentedDrawable, Color4 newColour, double duration = 0, EasingTypes easing = EasingTypes.None)
{
- accentedDrawable.TransformTo(accentedDrawable.AccentColour, newColour, duration, easing, new TransformAccent());
+ accentedDrawable.TransformTo(() => accentedDrawable.AccentColour, newColour, duration, easing, new TransformAccent());
}
}
}
diff --git a/osu.Game/Graphics/UserInterface/Bar.cs b/osu.Game/Graphics/UserInterface/Bar.cs
new file mode 100644
index 0000000000..76b75f1084
--- /dev/null
+++ b/osu.Game/Graphics/UserInterface/Bar.cs
@@ -0,0 +1,137 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using OpenTK;
+using OpenTK.Graphics;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Sprites;
+using System;
+
+namespace osu.Game.Graphics.UserInterface
+{
+ public class Bar : Container, IHasAccentColour
+ {
+ private readonly Box background;
+ private readonly Box bar;
+
+ private const int resize_duration = 250;
+
+ private const EasingTypes easing = EasingTypes.InOutCubic;
+
+ private float length;
+ ///
+ /// Length of the bar, ranges from 0 to 1
+ ///
+ public float Length
+ {
+ get
+ {
+ return length;
+ }
+ set
+ {
+ length = MathHelper.Clamp(value, 0, 1);
+ updateBarLength();
+ }
+ }
+
+ public Color4 BackgroundColour
+ {
+ get
+ {
+ return background.Colour;
+ }
+ set
+ {
+ background.Colour = value;
+ }
+ }
+
+ public Color4 AccentColour
+ {
+ get
+ {
+ return bar.Colour;
+ }
+ set
+ {
+ bar.Colour = value;
+ }
+ }
+
+ private BarDirection direction = BarDirection.LeftToRight;
+ public BarDirection Direction
+ {
+ get
+ {
+ return direction;
+ }
+ set
+ {
+ direction = value;
+ updateBarLength();
+ }
+ }
+
+ public Bar()
+ {
+ Children = new[]
+ {
+ background = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = new Color4(0,0,0,0)
+ },
+ bar = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Width = 0,
+ },
+ };
+ }
+
+ private void updateBarLength()
+ {
+ switch (direction)
+ {
+ case BarDirection.LeftToRight:
+ case BarDirection.RightToLeft:
+ bar.ResizeTo(new Vector2(length, 1), resize_duration, easing);
+ break;
+
+ case BarDirection.TopToBottom:
+ case BarDirection.BottomToTop:
+ bar.ResizeTo(new Vector2(1, length), resize_duration, easing);
+ break;
+ }
+
+ switch (direction)
+ {
+ case BarDirection.LeftToRight:
+ case BarDirection.TopToBottom:
+ bar.Anchor = Anchor.TopLeft;
+ bar.Origin = Anchor.TopLeft;
+ break;
+
+ case BarDirection.RightToLeft:
+ case BarDirection.BottomToTop:
+ bar.Anchor = Anchor.BottomRight;
+ bar.Origin = Anchor.BottomRight;
+ break;
+ }
+ }
+ }
+
+ [Flags]
+ public enum BarDirection
+ {
+ LeftToRight = 1 << 0,
+ RightToLeft = 1 << 1,
+ TopToBottom = 1 << 2,
+ BottomToTop = 1 << 3,
+
+ Vertical = TopToBottom | BottomToTop,
+ Horizontal = LeftToRight | RightToLeft,
+ }
+}
\ No newline at end of file
diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs
new file mode 100644
index 0000000000..d0965a1861
--- /dev/null
+++ b/osu.Game/Graphics/UserInterface/BarGraph.cs
@@ -0,0 +1,65 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using OpenTK;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace osu.Game.Graphics.UserInterface
+{
+ public class BarGraph : FillFlowContainer
+ {
+ ///
+ /// Manually sets the max value, if null is instead used
+ ///
+ public float? MaxValue { get; set; }
+
+ private BarDirection direction = BarDirection.BottomToTop;
+ public new BarDirection Direction
+ {
+ get
+ {
+ return direction;
+ }
+ set
+ {
+ direction = value;
+ base.Direction = (direction & BarDirection.Horizontal) > 0 ? FillDirection.Vertical : FillDirection.Horizontal;
+ foreach (var bar in Children)
+ {
+ bar.Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, 1.0f / Children.Count()) : new Vector2(1.0f / Children.Count(), 1);
+ bar.Direction = direction;
+ }
+ }
+ }
+
+ ///
+ /// A list of floats that defines the length of each
+ ///
+ public IEnumerable Values
+ {
+ set
+ {
+ List bars = Children.ToList();
+ foreach (var bar in value.Select((length, index) => new { Value = length, Bar = bars.Count > index ? bars[index] : null }))
+ if (bar.Bar != null)
+ {
+ bar.Bar.Length = bar.Value / (MaxValue ?? value.Max());
+ bar.Bar.Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, 1.0f / value.Count()) : new Vector2(1.0f / value.Count(), 1);
+ }
+ else
+ Add(new Bar
+ {
+ RelativeSizeAxes = Axes.Both,
+ Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, 1.0f / value.Count()) : new Vector2(1.0f / value.Count(), 1),
+ Length = bar.Value / (MaxValue ?? value.Max()),
+ Direction = Direction,
+ });
+ //I'm using ToList() here because Where() returns an Enumerable which can change it's elements afterwards
+ Remove(Children.Where((bar, index) => index >= value.Count()).ToList());
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/osu.Game/Graphics/UserInterface/Nub.cs b/osu.Game/Graphics/UserInterface/Nub.cs
index e150c7dc07..82ede8f079 100644
--- a/osu.Game/Graphics/UserInterface/Nub.cs
+++ b/osu.Game/Graphics/UserInterface/Nub.cs
@@ -3,8 +3,8 @@
using OpenTK;
using OpenTK.Graphics;
-using osu.Framework;
using osu.Framework.Allocation;
+using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@@ -12,18 +12,18 @@ using osu.Framework.Graphics.UserInterface;
namespace osu.Game.Graphics.UserInterface
{
- public class Nub : CircularContainer, IStateful
+ public class Nub : CircularContainer, IHasCurrentValue
{
public const float COLLAPSED_SIZE = 20;
public const float EXPANDED_SIZE = 40;
- private readonly Box fill;
-
private const float border_width = 3;
private Color4 glowingColour, idleColour;
public Nub()
{
+ Box fill;
+
Size = new Vector2(COLLAPSED_SIZE, 12);
BorderColour = Color4.White;
@@ -40,6 +40,14 @@ namespace osu.Game.Graphics.UserInterface
AlwaysPresent = true,
},
};
+
+ Current.ValueChanged += newValue =>
+ {
+ if (newValue)
+ fill.FadeIn(200, EasingTypes.OutQuint);
+ else
+ fill.FadeTo(0.01f, 200, EasingTypes.OutQuint); //todo: remove once we figure why containers aren't drawing at all times
+ };
}
[BackgroundDependencyLoader]
@@ -84,28 +92,6 @@ namespace osu.Game.Graphics.UserInterface
}
}
- private CheckboxState state;
-
- public CheckboxState State
- {
- get
- {
- return state;
- }
- set
- {
- state = value;
-
- switch (state)
- {
- case CheckboxState.Checked:
- fill.FadeIn(200, EasingTypes.OutQuint);
- break;
- case CheckboxState.Unchecked:
- fill.FadeTo(0.01f, 200, EasingTypes.OutQuint); //todo: remove once we figure why containers aren't drawing at all times
- break;
- }
- }
- }
+ public Bindable Current { get; } = new Bindable();
}
}
diff --git a/osu.Game/Graphics/UserInterface/OsuCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuCheckbox.cs
index 6a5151b90c..d339388aa5 100644
--- a/osu.Game/Graphics/UserInterface/OsuCheckbox.cs
+++ b/osu.Game/Graphics/UserInterface/OsuCheckbox.cs
@@ -23,18 +23,9 @@ namespace osu.Game.Graphics.UserInterface
{
set
{
- if (bindable != null)
- bindable.ValueChanged -= bindableValueChanged;
bindable = value;
- if (bindable != null)
- {
- bool state = State == CheckboxState.Checked;
- if (state != bindable.Value)
- State = bindable.Value ? CheckboxState.Checked : CheckboxState.Unchecked;
- bindable.ValueChanged += bindableValueChanged;
- }
-
- if (bindable?.Disabled ?? true)
+ Current.BindTo(bindable);
+ if (value?.Disabled ?? true)
Alpha = 0.3f;
}
}
@@ -83,18 +74,16 @@ namespace osu.Game.Graphics.UserInterface
Margin = new MarginPadding { Right = 5 },
}
};
- }
- private void bindableValueChanged(bool isChecked)
- {
- State = isChecked ? CheckboxState.Checked : CheckboxState.Unchecked;
- }
+ nub.Current.BindTo(Current);
- protected override void Dispose(bool isDisposing)
- {
- if (bindable != null)
- bindable.ValueChanged -= bindableValueChanged;
- base.Dispose(isDisposing);
+ Current.ValueChanged += newValue =>
+ {
+ if (newValue)
+ sampleChecked?.Play();
+ else
+ sampleUnchecked?.Play();
+ };
}
protected override bool OnHover(InputState state)
@@ -117,23 +106,5 @@ namespace osu.Game.Graphics.UserInterface
sampleChecked = audio.Sample.Get(@"Checkbox/check-on");
sampleUnchecked = audio.Sample.Get(@"Checkbox/check-off");
}
-
- protected override void OnChecked()
- {
- sampleChecked?.Play();
- nub.State = CheckboxState.Checked;
-
- if (bindable != null)
- bindable.Value = true;
- }
-
- protected override void OnUnchecked()
- {
- sampleUnchecked?.Play();
- nub.State = CheckboxState.Unchecked;
-
- if (bindable != null)
- bindable.Value = false;
- }
}
}
diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs
index 3466fb1a60..9bb0d15545 100644
--- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs
+++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs
@@ -45,7 +45,7 @@ namespace osu.Game.Graphics.UserInterface
private class OsuDropdownMenuItem : DropdownMenuItem
{
- public OsuDropdownMenuItem(string text, T value) : base(text, value)
+ public OsuDropdownMenuItem(string text, T current) : base(text, current)
{
Foreground.Padding = new MarginPadding(2);
diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs
index 078c8564d7..180cb88707 100644
--- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs
+++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
-using OpenTK.Input;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
@@ -50,7 +49,6 @@ namespace osu.Game.Graphics.UserInterface
nub = new Nub
{
Origin = Anchor.TopCentre,
- State = CheckboxState.Unchecked,
Expanded = true,
}
};
@@ -64,15 +62,6 @@ namespace osu.Game.Graphics.UserInterface
rightBox.Colour = colours.Pink;
}
- private void playSample()
- {
- if (Clock == null || Clock.CurrentTime - lastSampleTime <= 50)
- return;
- lastSampleTime = Clock.CurrentTime;
- sample.Frequency.Value = 1 + NormalizedValue * 0.2f;
- sample.Play();
- }
-
protected override bool OnHover(InputState state)
{
nub.Glowing = true;
@@ -85,37 +74,39 @@ namespace osu.Game.Graphics.UserInterface
base.OnHoverLost(state);
}
- protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
+ protected override void OnUserChange()
{
- if (args.Key == Key.Left || args.Key == Key.Right)
- playSample();
- return base.OnKeyDown(state, args);
+ base.OnUserChange();
+ playSample();
+ }
+
+ private void playSample()
+ {
+ if (Clock == null || Clock.CurrentTime - lastSampleTime <= 50)
+ return;
+ lastSampleTime = Clock.CurrentTime;
+ sample.Frequency.Value = 1 + NormalizedValue * 0.2f;
+
+ if (NormalizedValue == 0)
+ sample.Frequency.Value -= 0.4f;
+ else if (NormalizedValue == 1)
+ sample.Frequency.Value += 0.4f;
+
+ sample.Play();
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
{
- nub.State = CheckboxState.Checked;
+ nub.Current.Value = true;
return base.OnMouseDown(state, args);
}
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
{
- nub.State = CheckboxState.Unchecked;
+ nub.Current.Value = false;
return base.OnMouseUp(state, args);
}
- protected override bool OnClick(InputState state)
- {
- playSample();
- return base.OnClick(state);
- }
-
- protected override bool OnDrag(InputState state)
- {
- playSample();
- return base.OnDrag(state);
- }
-
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
diff --git a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs
index 5914d0ba4c..f732916889 100644
--- a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs
+++ b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs
@@ -1,7 +1,6 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using System;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
@@ -24,8 +23,6 @@ namespace osu.Game.Graphics.UserInterface
private readonly SpriteText text;
private readonly TextAwesome icon;
- public event EventHandler Action;
-
private Color4? accentColour;
public Color4 AccentColour
{
@@ -34,7 +31,7 @@ namespace osu.Game.Graphics.UserInterface
{
accentColour = value;
- if (State != CheckboxState.Checked)
+ if (Current)
{
text.Colour = AccentColour;
icon.Colour = AccentColour;
@@ -48,20 +45,6 @@ namespace osu.Game.Graphics.UserInterface
set { text.Text = value; }
}
- protected override void OnChecked()
- {
- fadeIn();
- icon.Icon = FontAwesome.fa_check_circle_o;
- Action?.Invoke(this, State);
- }
-
- protected override void OnUnchecked()
- {
- fadeOut();
- icon.Icon = FontAwesome.fa_circle_o;
- Action?.Invoke(this, State);
- }
-
private const float transition_length = 500;
private void fadeIn()
@@ -84,7 +67,7 @@ namespace osu.Game.Graphics.UserInterface
protected override void OnHoverLost(InputState state)
{
- if (State == CheckboxState.Unchecked)
+ if (!Current)
fadeOut();
base.OnHoverLost(state);
@@ -134,6 +117,20 @@ namespace osu.Game.Graphics.UserInterface
Anchor = Anchor.BottomLeft,
}
};
+
+ Current.ValueChanged += v =>
+ {
+ if (v)
+ {
+ fadeIn();
+ icon.Icon = FontAwesome.fa_check_circle_o;
+ }
+ else
+ {
+ fadeOut();
+ icon.Icon = FontAwesome.fa_circle_o;
+ }
+ };
}
}
}
diff --git a/osu.Game/Graphics/UserInterface/RollingCounter.cs b/osu.Game/Graphics/UserInterface/RollingCounter.cs
index 12eeb771dd..869ee37e11 100644
--- a/osu.Game/Graphics/UserInterface/RollingCounter.cs
+++ b/osu.Game/Graphics/UserInterface/RollingCounter.cs
@@ -108,8 +108,6 @@ namespace osu.Game.Graphics.UserInterface
{
base.LoadComplete();
- Flush(false, TransformType);
-
DisplayedCountSpriteText.Text = FormatCount(Current);
DisplayedCountSpriteText.Anchor = Anchor;
DisplayedCountSpriteText.Origin = Origin;
@@ -205,8 +203,8 @@ namespace osu.Game.Graphics.UserInterface
? GetProportionalDuration(currentValue, newValue)
: RollingDuration;
- transform.StartTime = Time.Current;
- transform.EndTime = Time.Current + rollingTotalDuration;
+ transform.StartTime = TransformStartTime;
+ transform.EndTime = TransformStartTime + rollingTotalDuration;
transform.StartValue = currentValue;
transform.EndValue = newValue;
transform.Easing = RollingEasing;
diff --git a/osu.Game/Modes/Replays/FramedReplayInputHandler.cs b/osu.Game/Modes/Replays/FramedReplayInputHandler.cs
index ae20ece515..0c1e140ce4 100644
--- a/osu.Game/Modes/Replays/FramedReplayInputHandler.cs
+++ b/osu.Game/Modes/Replays/FramedReplayInputHandler.cs
@@ -136,7 +136,7 @@ namespace osu.Game.Modes.Replays
public ReplayMouseState(Vector2 position, IEnumerable list)
{
Position = position;
- list.ForEach(b => PressedButtons.Add(b));
+ list.ForEach(b => SetPressed(b, true));
}
}
@@ -148,4 +148,4 @@ namespace osu.Game.Modes.Replays
}
}
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game/Modes/Scoring/Score.cs b/osu.Game/Modes/Scoring/Score.cs
index c998b11f77..b0c123f438 100644
--- a/osu.Game/Modes/Scoring/Score.cs
+++ b/osu.Game/Modes/Scoring/Score.cs
@@ -27,7 +27,24 @@ namespace osu.Game.Modes.Scoring
public int Combo { get; set; }
public Mod[] Mods { get; set; }
- public User User { get; set; }
+ private User user;
+
+ public User User
+ {
+ get
+ {
+ return user ?? new User
+ {
+ Username = LegacyUsername,
+ Id = LegacyUserID
+ };
+ }
+
+ set
+ {
+ user = value;
+ }
+ }
[JsonProperty(@"replay_data")]
public Replay Replay;
@@ -38,10 +55,10 @@ namespace osu.Game.Modes.Scoring
public long OnlineScoreID;
[JsonProperty(@"username")]
- public string Username;
+ public string LegacyUsername;
[JsonProperty(@"user_id")]
- public long UserID;
+ public long LegacyUserID;
[JsonProperty(@"date")]
public DateTime Date;
diff --git a/osu.Game/Modes/UI/HitRenderer.cs b/osu.Game/Modes/UI/HitRenderer.cs
index a958c61c68..dd5eff5a95 100644
--- a/osu.Game/Modes/UI/HitRenderer.cs
+++ b/osu.Game/Modes/UI/HitRenderer.cs
@@ -16,6 +16,7 @@ using System.Diagnostics;
using System.Linq;
using osu.Game.Modes.Replays;
using osu.Game.Modes.Scoring;
+using OpenTK;
namespace osu.Game.Modes.UI
{
@@ -32,6 +33,11 @@ namespace osu.Game.Modes.UI
///
public event Action OnAllJudged;
+ ///
+ /// Whether to apply adjustments to the child based on our own size.
+ ///
+ public bool AspectAdjust = true;
+
///
/// The input manager for this HitRenderer.
///
@@ -219,6 +225,19 @@ namespace osu.Game.Modes.UI
Playfield.PostProcess();
}
+ protected override void Update()
+ {
+ base.Update();
+
+ Playfield.Size = AspectAdjust ? GetPlayfieldAspectAdjust() : Vector2.One;
+ }
+
+ ///
+ /// In some cases we want to apply changes to the relative size of our contained based on custom conditions.
+ ///
+ ///
+ protected virtual Vector2 GetPlayfieldAspectAdjust() => new Vector2(0.75f); //a sane default
+
///
/// Triggered when an object's Judgement is updated.
///
diff --git a/osu.Game/Modes/UI/Playfield.cs b/osu.Game/Modes/UI/Playfield.cs
index f31ee0f189..1e7cf6579c 100644
--- a/osu.Game/Modes/UI/Playfield.cs
+++ b/osu.Game/Modes/UI/Playfield.cs
@@ -1,6 +1,7 @@
// Copyright (c) 2007-2017 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 osu.Game.Modes.Objects;
@@ -38,6 +39,9 @@ namespace osu.Game.Modes.UI
{
AlwaysReceiveInput = true;
+ // Default height since we force relative size axes
+ Size = Vector2.One;
+
AddInternal(ScaledContent = new ScaledContainer
{
CustomWidth = customWidth,
@@ -63,6 +67,12 @@ namespace osu.Game.Modes.UI
Add(HitObjects);
}
+ public override Axes RelativeSizeAxes
+ {
+ get { return Axes.Both; }
+ set { throw new InvalidOperationException($@"{nameof(Playfield)}'s {nameof(RelativeSizeAxes)} should never be changed from {Axes.Both}"); }
+ }
+
///
/// Performs post-processing tasks (if any) after all DrawableHitObjects are loaded into this Playfield.
///
diff --git a/osu.Game/Modes/UI/StandardHudOverlay.cs b/osu.Game/Modes/UI/StandardHudOverlay.cs
index d51ffab06b..e2eda4a168 100644
--- a/osu.Game/Modes/UI/StandardHudOverlay.cs
+++ b/osu.Game/Modes/UI/StandardHudOverlay.cs
@@ -40,6 +40,7 @@ namespace osu.Game.Modes.UI
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Margin = new MarginPadding(10),
+ Y = - TwoLayerButton.SIZE_RETRACTED.Y,
};
protected override ScoreCounter CreateScoreCounter() => new ScoreCounter(6)
diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs
index 7172aba3be..ccea6ef458 100644
--- a/osu.Game/OsuGame.cs
+++ b/osu.Game/OsuGame.cs
@@ -307,6 +307,18 @@ namespace osu.Game
return base.OnExiting();
}
+ ///
+ /// Use to programatically exit the game as if the user was triggering via alt-f4.
+ /// Will keep persisting until an exit occurs (exit may be blocked multiple times).
+ ///
+ public void GracefullyExit()
+ {
+ if (!OnExiting())
+ Exit();
+ else
+ Scheduler.AddDelayed(GracefullyExit, 2000);
+ }
+
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs
index 0bb3d3dc71..fc12789b05 100644
--- a/osu.Game/Overlays/ChatOverlay.cs
+++ b/osu.Game/Overlays/ChatOverlay.cs
@@ -93,7 +93,7 @@ namespace osu.Game.Overlays
{
var postText = sender.Text;
- if (!string.IsNullOrEmpty(postText))
+ if (!string.IsNullOrEmpty(postText) && api.LocalUser.Value != null)
{
//todo: actually send to server
careChannels.FirstOrDefault()?.AddNewMessages(new[]
diff --git a/osu.Game/Overlays/DragBar.cs b/osu.Game/Overlays/DragBar.cs
index 123cd404c7..8690388127 100644
--- a/osu.Game/Overlays/DragBar.cs
+++ b/osu.Game/Overlays/DragBar.cs
@@ -72,7 +72,7 @@ namespace osu.Game.Overlays
private void updatePosition(float position)
{
position = MathHelper.Clamp(position, 0, 1);
- FillContainer.TransformTo(FillContainer.Width, position, 200, EasingTypes.OutQuint, new TransformSeek());
+ FillContainer.TransformTo(() => FillContainer.Width, position, 200, EasingTypes.OutQuint, new TransformSeek());
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs
index 73b7695dab..9d21a0341c 100644
--- a/osu.Game/Overlays/MusicController.cs
+++ b/osu.Game/Overlays/MusicController.cs
@@ -48,7 +48,7 @@ namespace osu.Game.Overlays
private const float progress_height = 10;
- private const float bottom_black_area_height = 50;
+ private const float bottom_black_area_height = 55;
public MusicController()
{
@@ -119,7 +119,8 @@ namespace osu.Game.Overlays
Text = @"Nothing to play",
Font = @"Exo2.0-BoldItalic"
},
- new Container {
+ new Container
+ {
Padding = new MarginPadding { Bottom = progress_height },
Height = bottom_black_area_height,
RelativeSizeAxes = Axes.X,
@@ -143,7 +144,8 @@ namespace osu.Game.Overlays
},
playButton = new Button
{
- //Scale = new Vector2(1.3f),
+ Scale = new Vector2(1.4f),
+ IconScale = new Vector2(1.4f),
Action = () =>
{
if (current?.Track == null) return;
@@ -421,6 +423,13 @@ namespace osu.Game.Overlays
}
private const float button_size = 30;
+ private Color4 flashColour;
+
+ public Vector2 IconScale
+ {
+ get { return icon.Scale; }
+ set { icon.Scale = value; }
+ }
public Button()
{
@@ -467,6 +476,7 @@ namespace osu.Game.Overlays
private void load(OsuColour colours)
{
hover.Colour = colours.Yellow.Opacity(0.6f);
+ flashColour = colours.Yellow;
}
protected override bool OnHover(InputState state)
@@ -481,9 +491,15 @@ namespace osu.Game.Overlays
base.OnHoverLost(state);
}
+ protected override bool OnClick(InputState state)
+ {
+ hover.FlashColour(flashColour, 800, EasingTypes.OutQuint);
+ return base.OnClick(state);
+ }
+
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
{
- content.ScaleTo(1, 2000, EasingTypes.OutQuint);
+ content.ScaleTo(0.75f, 2000, EasingTypes.OutQuint);
return base.OnMouseDown(state, args);
}
diff --git a/osu.Game/Overlays/Options/OptionDropdown.cs b/osu.Game/Overlays/Options/OptionDropdown.cs
index 9ae02a17d3..ee12ba9b05 100644
--- a/osu.Game/Overlays/Options/OptionDropdown.cs
+++ b/osu.Game/Overlays/Options/OptionDropdown.cs
@@ -33,8 +33,8 @@ namespace osu.Game.Overlays.Options
set
{
bindable = value;
- dropdown.SelectedValue.BindTo(bindable);
- if (bindable.Disabled)
+ dropdown.Current.BindTo(bindable);
+ if (value?.Disabled ?? true)
Alpha = 0.3f;
}
}
diff --git a/osu.Game/Overlays/Options/OptionSlider.cs b/osu.Game/Overlays/Options/OptionSlider.cs
index 8fa9bf063d..1c4b54a080 100644
--- a/osu.Game/Overlays/Options/OptionSlider.cs
+++ b/osu.Game/Overlays/Options/OptionSlider.cs
@@ -27,12 +27,14 @@ namespace osu.Game.Overlays.Options
}
}
- public BindableNumber Bindable
+ private Bindable bindable;
+
+ public Bindable Bindable
{
- get { return slider.Value; }
set
{
- slider.Value = value;
+ bindable = value;
+ slider.Current.BindTo(bindable);
if (value?.Disabled ?? true)
Alpha = 0.3f;
}
diff --git a/osu.Game/Overlays/Options/OptionTextBox.cs b/osu.Game/Overlays/Options/OptionTextBox.cs
index 722f24d50d..b5ef39c8b2 100644
--- a/osu.Game/Overlays/Options/OptionTextBox.cs
+++ b/osu.Game/Overlays/Options/OptionTextBox.cs
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Configuration;
-using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Overlays.Options
@@ -15,38 +14,11 @@ namespace osu.Game.Overlays.Options
{
set
{
- if (bindable != null)
- bindable.ValueChanged -= bindableValueChanged;
bindable = value;
- if (bindable != null)
- {
- Text = bindable.Value;
- bindable.ValueChanged += bindableValueChanged;
- }
-
- if (bindable?.Disabled ?? true)
+ Current.BindTo(bindable);
+ if (value?.Disabled ?? true)
Alpha = 0.3f;
}
}
-
- public OptionTextBox()
- {
- OnChange += onChange;
- }
-
- private void onChange(TextBox sender, bool newText)
- {
- if (bindable != null)
- bindable.Value = Text;
- }
-
- private void bindableValueChanged(string newValue) => Text = newValue;
-
- protected override void Dispose(bool isDisposing)
- {
- if (bindable != null)
- bindable.ValueChanged -= bindableValueChanged;
- base.Dispose(isDisposing);
- }
}
}
\ No newline at end of file
diff --git a/osu.Game/Overlays/Options/Sections/Audio/AudioDevicesOptions.cs b/osu.Game/Overlays/Options/Sections/Audio/AudioDevicesOptions.cs
index 2818f5fbd7..e3033b876d 100644
--- a/osu.Game/Overlays/Options/Sections/Audio/AudioDevicesOptions.cs
+++ b/osu.Game/Overlays/Options/Sections/Audio/AudioDevicesOptions.cs
@@ -39,7 +39,13 @@ namespace osu.Game.Overlays.Options.Sections.Audio
if (deviceItems.All(kv => kv.Value != preferredDeviceName))
deviceItems.Add(new KeyValuePair(preferredDeviceName, preferredDeviceName));
- dropdown.Items = deviceItems;
+ // The option dropdown for audio device selection lists all audio
+ // device names. Dropdowns, however, may not have multiple identical
+ // keys. Thus, we remove duplicate audio device names from
+ // the dropdown. BASS does not give us a simple mechanism to select
+ // specific audio devices in such a case anyways. Such
+ // functionality would require involved OS-specific code.
+ dropdown.Items = deviceItems.Distinct().ToList();
}
private void onDeviceChanged(string name) => updateItems();
diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs
index e5fb1db38e..29f6cb2967 100644
--- a/osu.Game/Screens/Menu/OsuLogo.cs
+++ b/osu.Game/Screens/Menu/OsuLogo.cs
@@ -194,8 +194,6 @@ namespace osu.Game.Screens.Menu
return true;
}
- protected override bool OnDragStart(InputState state) => true;
-
protected override bool OnClick(InputState state)
{
if (!Interactive) return false;
diff --git a/osu.Game/Screens/Play/FailOverlay.cs b/osu.Game/Screens/Play/FailOverlay.cs
index 7a32e19338..faff687ddb 100644
--- a/osu.Game/Screens/Play/FailOverlay.cs
+++ b/osu.Game/Screens/Play/FailOverlay.cs
@@ -1,31 +1,19 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using OpenTK.Input;
using osu.Game.Graphics;
using OpenTK.Graphics;
using osu.Framework.Allocation;
+using System.Linq;
namespace osu.Game.Screens.Play
{
public class FailOverlay : MenuOverlay
{
-
public override string Header => "failed";
public override string Description => "you're dead, try again?";
- protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
- {
- if (args.Key == Key.Escape)
- {
- if (State == Visibility.Hidden) return false;
- OnQuit();
- return true;
- }
-
- return base.OnKeyDown(state, args);
- }
[BackgroundDependencyLoader]
private void load(OsuColour colours)
@@ -33,5 +21,16 @@ namespace osu.Game.Screens.Play
AddButton("Retry", colours.YellowDark, OnRetry);
AddButton("Quit", new Color4(170, 27, 39, 255), OnQuit);
}
+
+ protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
+ {
+ if (!args.Repeat && args.Key == Key.Escape)
+ {
+ Buttons.Children.Last().TriggerClick();
+ return true;
+ }
+
+ return base.OnKeyDown(state, args);
+ }
}
}
diff --git a/osu.Game/Screens/Play/HotkeyRetryOverlay.cs b/osu.Game/Screens/Play/HotkeyRetryOverlay.cs
new file mode 100644
index 0000000000..16062bebe5
--- /dev/null
+++ b/osu.Game/Screens/Play/HotkeyRetryOverlay.cs
@@ -0,0 +1,82 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Input;
+using OpenTK.Input;
+using osu.Framework.Allocation;
+using osu.Framework.Audio.Sample;
+using osu.Framework.Audio;
+using System;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Sprites;
+using OpenTK.Graphics;
+
+namespace osu.Game.Screens.Play
+{
+ public class HotkeyRetryOverlay : Container
+ {
+ public Action Action;
+
+ private SampleChannel retrySample;
+ private Box overlay;
+
+ private const int activate_delay = 400;
+ private const int fadeout_delay = 200;
+
+ private bool fired;
+
+ [BackgroundDependencyLoader]
+ private void load(AudioManager audio)
+ {
+ retrySample = audio.Sample.Get(@"Menu/menuback");
+ RelativeSizeAxes = Axes.Both;
+ AlwaysPresent = true;
+
+ Children = new Drawable[]
+ {
+ overlay = new Box
+ {
+ Alpha = 0,
+ Colour = Color4.Black,
+ RelativeSizeAxes = Axes.Both,
+ }
+ };
+ }
+
+ protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
+ {
+ if (args.Repeat) return false;
+
+ if (args.Key == Key.Tilde)
+ {
+ overlay.FadeIn(activate_delay, EasingTypes.Out);
+ return true;
+ }
+
+ return base.OnKeyDown(state, args);
+ }
+
+ protected override bool OnKeyUp(InputState state, KeyUpEventArgs args)
+ {
+ if (args.Key == Key.Tilde && !fired)
+ {
+ overlay.FadeOut(fadeout_delay, EasingTypes.Out);
+ return true;
+ }
+
+ return base.OnKeyUp(state, args);
+ }
+
+ protected override void Update()
+ {
+ base.Update();
+ if (!fired && overlay.Alpha == 1)
+ {
+ fired = true;
+ retrySample.Play();
+ Action?.Invoke();
+ }
+ }
+ }
+}
diff --git a/osu.Game/Screens/Play/MenuOverlay.cs b/osu.Game/Screens/Play/MenuOverlay.cs
index ede49065a7..738e5cc35d 100644
--- a/osu.Game/Screens/Play/MenuOverlay.cs
+++ b/osu.Game/Screens/Play/MenuOverlay.cs
@@ -13,10 +13,11 @@ using OpenTK;
using OpenTK.Graphics;
using osu.Game.Graphics;
using osu.Framework.Allocation;
+using osu.Game.Graphics.UserInterface;
namespace osu.Game.Screens.Play
{
- public abstract class MenuOverlay : OverlayContainer
+ public abstract class MenuOverlay : OverlayContainer, IRequireHighFrequencyMousePosition
{
private const int transition_duration = 200;
private const int button_height = 70;
@@ -30,7 +31,7 @@ namespace osu.Game.Screens.Play
public abstract string Header { get; }
public abstract string Description { get; }
- private FillFlowContainer buttons;
+ protected FillFlowContainer Buttons;
public int Retries
{
@@ -80,11 +81,13 @@ namespace osu.Game.Screens.Play
// Don't let mouse down events through the overlay or people can click circles while paused.
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => true;
+ protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) => true;
+
protected override bool OnMouseMove(InputState state) => true;
protected void AddButton(string text, Color4 colour, Action action)
{
- buttons.Add(new PauseButton
+ Buttons.Add(new PauseButton
{
Text = text,
ButtonColour = colour,
@@ -151,7 +154,7 @@ namespace osu.Game.Screens.Play
}
}
},
- buttons = new FillFlowContainer
+ Buttons = new FillFlowContainer
{
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
diff --git a/osu.Game/Screens/Play/PauseOverlay.cs b/osu.Game/Screens/Play/PauseOverlay.cs
index f9706d263e..9561979751 100644
--- a/osu.Game/Screens/Play/PauseOverlay.cs
+++ b/osu.Game/Screens/Play/PauseOverlay.cs
@@ -2,10 +2,10 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
+using System.Linq;
using osu.Framework.Input;
using osu.Game.Graphics;
using OpenTK.Input;
-using osu.Framework.Graphics.Containers;
using OpenTK.Graphics;
using osu.Framework.Allocation;
@@ -20,10 +20,9 @@ namespace osu.Game.Screens.Play
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{
- if (args.Key == Key.Escape)
+ if (!args.Repeat && args.Key == Key.Escape)
{
- if (State == Visibility.Hidden) return false;
- OnResume();
+ Buttons.Children.First().TriggerClick();
return true;
}
@@ -39,4 +38,3 @@ namespace osu.Game.Screens.Play
}
}
}
-
\ No newline at end of file
diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs
index 9b3ca0df26..570c1831c0 100644
--- a/osu.Game/Screens/Play/Player.cs
+++ b/osu.Game/Screens/Play/Player.cs
@@ -20,6 +20,7 @@ using osu.Game.Screens.Backgrounds;
using osu.Game.Screens.Ranking;
using System;
using System.Linq;
+using osu.Framework.Threading;
using osu.Game.Modes.Scoring;
namespace osu.Game.Screens.Play
@@ -115,7 +116,12 @@ namespace osu.Game.Screens.Play
scoreProcessor = HitRenderer.CreateScoreProcessor();
- hudOverlay = new StandardHudOverlay();
+ hudOverlay = new StandardHudOverlay()
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre
+ };
+
hudOverlay.KeyCounter.Add(ruleset.CreateGameplayKeys());
hudOverlay.BindProcessor(scoreProcessor);
hudOverlay.BindHitRenderer(HitRenderer);
@@ -157,6 +163,15 @@ namespace osu.Game.Screens.Play
{
OnRetry = Restart,
OnQuit = Exit,
+ },
+ new HotkeyRetryOverlay
+ {
+ Action = () => {
+ //we want to hide the hitrenderer immediately (looks better).
+ //we may be able to remove this once the mouse cursor trail is improved.
+ HitRenderer?.Hide();
+ Restart();
+ },
}
};
}
@@ -247,14 +262,16 @@ namespace osu.Game.Screens.Play
});
}
+ private ScheduledDelegate onCompletionEvent;
+
private void onCompletion()
{
// Only show the completion screen if the player hasn't failed
- if (scoreProcessor.HasFailed)
+ if (scoreProcessor.HasFailed || onCompletionEvent != null)
return;
Delay(1000);
- Schedule(delegate
+ onCompletionEvent = Schedule(delegate
{
ValidForResume = false;
Push(new Results
@@ -299,41 +316,51 @@ namespace osu.Game.Screens.Play
sourceClock.Start();
initializeSkipButton();
});
+
+ //keep in mind this is using the interpolatedSourceClock so won't be run as early as we may expect.
+ HitRenderer.Alpha = 0;
+ HitRenderer.FadeIn(750, EasingTypes.OutQuint);
}
protected override void OnSuspending(Screen next)
{
- Content.FadeOut(350);
- Content.ScaleTo(0.7f, 750, EasingTypes.InQuint);
+ fadeOut();
base.OnSuspending(next);
}
protected override bool OnExiting(Screen next)
{
- if (pauseOverlay == null) return false;
-
- if (HitRenderer.HasReplayLoaded)
- return false;
-
- if (pauseOverlay.State != Visibility.Visible && !canPause) return true;
-
- if (!IsPaused && sourceClock.IsRunning) // For if the user presses escape quickly when entering the map
+ if (pauseOverlay != null && !HitRenderer.HasReplayLoaded)
{
- Pause();
- return true;
- }
- else
- {
- FadeOut(250);
- Content.ScaleTo(0.7f, 750, EasingTypes.InQuint);
- Background?.FadeTo(1f, 200);
- return base.OnExiting(next);
+ //pause screen override logic.
+ if (pauseOverlay?.State == Visibility.Hidden && !canPause) return true;
+
+ if (!IsPaused && sourceClock.IsRunning) // For if the user presses escape quickly when entering the map
+ {
+ Pause();
+ return true;
+ }
}
+
+ fadeOut();
+ return base.OnExiting(next);
+ }
+
+ private void fadeOut()
+ {
+ const float fade_out_duration = 250;
+
+ HitRenderer?.FadeOut(fade_out_duration);
+ Content.FadeOut(fade_out_duration);
+
+ hudOverlay.ScaleTo(0.7f, fade_out_duration * 3, EasingTypes.In);
+
+ Background?.FadeTo(1f, fade_out_duration);
}
private Bindable mouseWheelDisabled;
protected override bool OnWheel(InputState state) => mouseWheelDisabled.Value && !IsPaused;
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs
index dae909f2b7..ae117254fa 100644
--- a/osu.Game/Screens/Select/BeatmapDetailArea.cs
+++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs
@@ -1,13 +1,10 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Game.Beatmaps;
-using osu.Game.Online.API;
-using osu.Game.Online.API.Requests;
using osu.Game.Screens.Select.Leaderboards;
namespace osu.Game.Screens.Select
@@ -17,11 +14,9 @@ namespace osu.Game.Screens.Select
private readonly Container content;
protected override Container Content => content;
- public readonly Container Details; //todo: replace with a real details view when added
+ public readonly BeatmapDetails Details;
public readonly Leaderboard Leaderboard;
- private APIAccess api;
-
private WorkingBeatmap beatmap;
public WorkingBeatmap Beatmap
{
@@ -32,7 +27,8 @@ namespace osu.Game.Screens.Select
set
{
beatmap = value;
- if (IsLoaded) Schedule(updateScores);
+ Leaderboard.Beatmap = beatmap?.BeatmapInfo;
+ Details.Beatmap = beatmap?.Beatmap.BeatmapInfo;
}
}
@@ -51,14 +47,12 @@ namespace osu.Game.Screens.Select
Details.Show();
Leaderboard.Hide();
break;
+
default:
Details.Hide();
Leaderboard.Show();
break;
}
-
- //for now let's always update scores.
- updateScores();
},
},
content = new Container
@@ -70,42 +64,18 @@ namespace osu.Game.Screens.Select
Add(new Drawable[]
{
- Details = new Container
+ Details = new BeatmapDetails
{
RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding(5),
+ Alpha = 0,
},
Leaderboard = new Leaderboard
{
RelativeSizeAxes = Axes.Both,
+
}
});
}
-
- protected override void LoadComplete()
- {
- base.LoadComplete();
- updateScores();
- }
-
- [BackgroundDependencyLoader(permitNulls: true)]
- private void load(APIAccess api)
- {
- this.api = api;
- }
-
- private GetScoresRequest getScoresRequest;
- private void updateScores()
- {
- if (!IsLoaded) return;
-
- Leaderboard.Scores = null;
- getScoresRequest?.Cancel();
-
- if (api == null || beatmap?.BeatmapInfo == null || !Leaderboard.IsPresent) return;
-
- getScoresRequest = new GetScoresRequest(beatmap.BeatmapInfo);
- getScoresRequest.Success += r => Leaderboard.Scores = r.Scores;
- api.Queue(getScoresRequest);
- }
}
-}
+}
\ No newline at end of file
diff --git a/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs b/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs
index c52d0397ed..48a46f0b90 100644
--- a/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs
+++ b/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs
@@ -8,7 +8,6 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
-using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
@@ -24,7 +23,7 @@ namespace osu.Game.Screens.Select
private void invokeOnFilter()
{
- OnFilter?.Invoke(tabs.SelectedItem, modsCheckbox.State == CheckboxState.Checked);
+ OnFilter?.Invoke(tabs.Current, modsCheckbox.Current);
}
[BackgroundDependencyLoader]
@@ -61,10 +60,10 @@ namespace osu.Game.Screens.Select
},
};
- tabs.SelectedItem.ValueChanged += item => invokeOnFilter();
- modsCheckbox.Action += (sender, e) => invokeOnFilter();
+ tabs.Current.ValueChanged += item => invokeOnFilter();
+ modsCheckbox.Current.ValueChanged += item => invokeOnFilter();
- tabs.SelectedItem.Value = BeatmapDetailTab.Global;
+ tabs.Current.Value = BeatmapDetailTab.Global;
}
}
diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs
new file mode 100644
index 0000000000..a0d15101e0
--- /dev/null
+++ b/osu.Game/Screens/Select/BeatmapDetails.cs
@@ -0,0 +1,434 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using OpenTK;
+using OpenTK.Graphics;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Primitives;
+using osu.Framework.Graphics.Sprites;
+using osu.Game.Database;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Sprites;
+using osu.Game.Graphics.UserInterface;
+using System.Globalization;
+using System.Linq;
+
+namespace osu.Game.Screens.Select
+{
+ public class BeatmapDetails : Container
+ {
+ private readonly MetadataSegment description;
+ private readonly MetadataSegment source;
+ private readonly MetadataSegment tags;
+
+ private readonly DifficultyRow circleSize;
+ private readonly DifficultyRow drainRate;
+ private readonly DifficultyRow overallDifficulty;
+ private readonly DifficultyRow approachRate;
+ private readonly DifficultyRow stars;
+
+ private readonly Container ratingsContainer;
+ private readonly Bar ratingsBar;
+ private readonly OsuSpriteText negativeRatings;
+ private readonly OsuSpriteText positiveRatings;
+ private readonly BarGraph ratingsGraph;
+
+ private readonly FillFlowContainer retryFailContainer;
+ private readonly BarGraph retryGraph;
+ private readonly BarGraph failGraph;
+
+ private BeatmapInfo beatmap;
+ public BeatmapInfo Beatmap
+ {
+ get
+ {
+ return beatmap;
+ }
+ set
+ {
+ beatmap = value;
+ if (beatmap == null) return;
+
+ description.Text = beatmap.Version;
+ source.Text = beatmap.Metadata.Source;
+ tags.Text = beatmap.Metadata.Tags;
+
+ circleSize.Value = beatmap.Difficulty.CircleSize;
+ drainRate.Value = beatmap.Difficulty.DrainRate;
+ overallDifficulty.Value = beatmap.Difficulty.OverallDifficulty;
+ approachRate.Value = beatmap.Difficulty.ApproachRate;
+ stars.Value = (float)beatmap.StarDifficulty;
+
+ if (beatmap.Metrics?.Ratings.Any() ?? false)
+ {
+ var ratings = beatmap.Metrics.Ratings.ToList();
+ ratingsContainer.Show();
+
+ negativeRatings.Text = ratings.GetRange(0, ratings.Count / 2).Sum().ToString();
+ positiveRatings.Text = ratings.GetRange(ratings.Count / 2, ratings.Count / 2).Sum().ToString();
+ ratingsBar.Length = (float)ratings.GetRange(0, ratings.Count / 2).Sum() / ratings.Sum();
+
+ ratingsGraph.Values = ratings.Select(rating => (float)rating);
+ }
+ else
+ ratingsContainer.Hide();
+
+ if ((beatmap.Metrics?.Retries.Any() ?? false) && beatmap.Metrics.Fails.Any())
+ {
+ var retries = beatmap.Metrics.Retries;
+ var fails = beatmap.Metrics.Fails;
+ retryFailContainer.Show();
+
+ float maxValue = fails.Zip(retries, (fail, retry) => fail + retry).Max();
+ failGraph.MaxValue = maxValue;
+ retryGraph.MaxValue = maxValue;
+
+ failGraph.Values = fails.Select(fail => (float)fail);
+ retryGraph.Values = retries.Zip(fails, (retry, fail) => retry + MathHelper.Clamp(fail, 0, maxValue));
+ }
+ else
+ retryFailContainer.Hide();
+ }
+ }
+
+ public BeatmapDetails()
+ {
+ Children = new Drawable[]
+ {
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = Color4.Black,
+ Alpha = 0.5f,
+ },
+ new FillFlowContainer()
+ {
+ Anchor = Anchor.TopRight,
+ Origin = Anchor.TopRight,
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Width = 0.4f,
+ Direction = FillDirection.Vertical,
+ LayoutDuration = 200,
+ LayoutEasing = EasingTypes.OutQuint,
+ Padding = new MarginPadding(10) { Top = 25 },
+ Children = new []
+ {
+ description = new MetadataSegment("Description"),
+ source = new MetadataSegment("Source"),
+ tags = new MetadataSegment("Tags")
+ },
+ },
+ new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Width = 0.6f,
+ Direction = FillDirection.Vertical,
+ Spacing = new Vector2(0, 15),
+ Padding = new MarginPadding(10) { Top = 0 },
+ Children = new Drawable[]
+ {
+ new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Children = new Drawable[]
+ {
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = Color4.Black,
+ Alpha = 0.5f,
+ },
+ new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Vertical,
+ Spacing = new Vector2(0,10),
+ Padding = new MarginPadding(15) { Top = 25 },
+ Children = new []
+ {
+ circleSize = new DifficultyRow("Circle Size", 7),
+ drainRate = new DifficultyRow("HP Drain"),
+ overallDifficulty = new DifficultyRow("Accuracy"),
+ approachRate = new DifficultyRow("Approach Rate"),
+ stars = new DifficultyRow("Star Diffculty"),
+ },
+ },
+ },
+ },
+ ratingsContainer = new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Alpha = 0,
+ AlwaysPresent = true,
+ Children = new Drawable[]
+ {
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = Color4.Black,
+ Alpha = 0.5f,
+ },
+ new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Vertical,
+ Padding = new MarginPadding
+ {
+ Top = 25,
+ Left = 15,
+ Right = 15,
+ },
+ Children = new Drawable[]
+ {
+ new OsuSpriteText
+ {
+ Text = "User Rating",
+ Font = @"Exo2.0-Medium",
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ },
+ ratingsBar = new Bar
+ {
+ RelativeSizeAxes = Axes.X,
+ Height = 5,
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Children = new[]
+ {
+ negativeRatings = new OsuSpriteText
+ {
+ Font = @"Exo2.0-Regular",
+ Text = "0",
+ },
+ positiveRatings = new OsuSpriteText
+ {
+ Font = @"Exo2.0-Regular",
+ Text = "0",
+ Anchor = Anchor.TopRight,
+ Origin = Anchor.TopRight,
+ },
+ },
+ },
+ new OsuSpriteText
+ {
+ Text = "Rating Spread",
+ TextSize = 14,
+ Font = @"Exo2.0-Regular",
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ },
+ ratingsGraph = new BarGraph
+ {
+ RelativeSizeAxes = Axes.X,
+ Height = 50,
+ },
+ },
+ },
+ },
+ },
+ retryFailContainer = new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Alpha = 0,
+ Children = new Drawable[]
+ {
+ new OsuSpriteText
+ {
+ Text = "Points of Failure",
+ Font = @"Exo2.0-Regular",
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ Size = new Vector2(1/0.6f, 50),
+ Children = new[]
+ {
+ retryGraph = new BarGraph
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ failGraph = new BarGraph
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ },
+ },
+ }
+ },
+ },
+ }
+ };
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colour)
+ {
+ description.AccentColour = colour.GrayB;
+ source.AccentColour = colour.GrayB;
+ tags.AccentColour = colour.YellowLight;
+
+ stars.AccentColour = colour.Yellow;
+
+ ratingsBar.BackgroundColour = colour.Green;
+ ratingsBar.AccentColour = colour.YellowDark;
+ ratingsGraph.Colour = colour.BlueDark;
+
+ failGraph.Colour = colour.YellowDarker;
+ retryGraph.Colour = colour.Yellow;
+ }
+
+ private class DifficultyRow : Container, IHasAccentColour
+ {
+ private readonly OsuSpriteText name;
+ private readonly Bar bar;
+ private readonly OsuSpriteText valueText;
+
+ private readonly float maxValue;
+
+ private float difficultyValue;
+ public float Value
+ {
+ get
+ {
+ return difficultyValue;
+ }
+ set
+ {
+ difficultyValue = value;
+ bar.Length = value / maxValue;
+ valueText.Text = value.ToString(CultureInfo.InvariantCulture);
+ }
+ }
+
+ public Color4 AccentColour
+ {
+ get
+ {
+ return bar.AccentColour;
+ }
+ set
+ {
+ bar.AccentColour = value;
+ }
+ }
+
+ public DifficultyRow(string difficultyName, float maxValue = 10)
+ {
+ this.maxValue = maxValue;
+ RelativeSizeAxes = Axes.X;
+ AutoSizeAxes = Axes.Y;
+ Children = new Drawable[]
+ {
+ name = new OsuSpriteText
+ {
+ Font = @"Exo2.0-Regular",
+ Text = difficultyName,
+ },
+ bar = new Bar
+ {
+ Origin = Anchor.CentreLeft,
+ Anchor = Anchor.CentreLeft,
+ RelativeSizeAxes = Axes.Both,
+ Size = new Vector2(1, 0.35f),
+ Padding = new MarginPadding { Left = 100, Right = 25 },
+ },
+ valueText = new OsuSpriteText
+ {
+ Anchor = Anchor.TopRight,
+ Origin = Anchor.TopRight,
+ Font = @"Exo2.0-Regular",
+ },
+ };
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colour)
+ {
+ name.Colour = colour.GrayB;
+ bar.BackgroundColour = colour.Gray7;
+ valueText.Colour = colour.GrayB;
+ }
+ }
+
+ private class MetadataSegment : Container, IHasAccentColour
+ {
+ private readonly OsuSpriteText header;
+ private readonly FillFlowContainer content;
+
+ public string Text
+ {
+ set
+ {
+ if (string.IsNullOrEmpty(value))
+ Hide();
+ else
+ {
+ Show();
+ if (header.Text == "Tags")
+ content.Children = value.Split(' ').Select(text => new OsuSpriteText
+ {
+ Text = text,
+ Font = "Exo2.0-Regular",
+ });
+ else
+ content.Children = new[]
+ {
+ new OsuSpriteText
+ {
+ Text = value,
+ Font = "Exo2.0-Regular",
+ }
+ };
+ }
+ }
+ }
+
+ public Color4 AccentColour
+ {
+ get
+ {
+ return content.Colour;
+ }
+ set
+ {
+ content.Colour = value;
+ }
+ }
+
+ public MetadataSegment(string headerText)
+ {
+ RelativeSizeAxes = Axes.X;
+ AutoSizeAxes = Axes.Y;
+ Margin = new MarginPadding { Top = 10 };
+ Children = new Drawable[]
+ {
+ header = new OsuSpriteText
+ {
+ Font = @"Exo2.0-Bold",
+ Text = headerText,
+ },
+ content = new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Full,
+ Spacing = new Vector2(5,0),
+ Margin = new MarginPadding { Top = header.TextSize }
+ }
+ };
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs
index 6d92b35993..7596af1484 100644
--- a/osu.Game/Screens/Select/FilterControl.cs
+++ b/osu.Game/Screens/Select/FilterControl.cs
@@ -93,11 +93,6 @@ namespace osu.Game.Screens.Select
searchTextBox = new SearchTextBox
{
RelativeSizeAxes = Axes.X,
- OnChange = (sender, newText) =>
- {
- if (newText)
- FilterChanged?.Invoke(CreateCriteria());
- },
Exit = () => Exit?.Invoke(),
},
new Box
@@ -149,10 +144,12 @@ namespace osu.Game.Screens.Select
}
};
+ searchTextBox.Current.ValueChanged += t => FilterChanged?.Invoke(CreateCriteria());
+
groupTabs.PinItem(GroupMode.All);
groupTabs.PinItem(GroupMode.RecentlyPlayed);
- groupTabs.SelectedItem.ValueChanged += val => Group = val;
- sortTabs.SelectedItem.ValueChanged += val => Sort = val;
+ groupTabs.Current.ValueChanged += val => Group = val;
+ sortTabs.Current.ValueChanged += val => Sort = val;
}
public void Deactivate()
diff --git a/osu.Game/Screens/Select/FilterCriteria.cs b/osu.Game/Screens/Select/FilterCriteria.cs
index acf0954418..2654129a44 100644
--- a/osu.Game/Screens/Select/FilterCriteria.cs
+++ b/osu.Game/Screens/Select/FilterCriteria.cs
@@ -31,7 +31,9 @@ namespace osu.Game.Screens.Select
|| (set.Metadata.Artist ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1
|| (set.Metadata.ArtistUnicode ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1
|| (set.Metadata.Title ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1
- || (set.Metadata.TitleUnicode ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1;
+ || (set.Metadata.TitleUnicode ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1
+ || (set.Metadata.Tags ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1
+ || (set.Metadata.Source ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1;
switch (g.State)
{
diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs
index 12ff096d16..315611a60c 100644
--- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs
+++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs
@@ -10,7 +10,11 @@ using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using System;
+using osu.Framework.Allocation;
+using osu.Game.Database;
using osu.Game.Modes.Scoring;
+using osu.Game.Online.API;
+using osu.Game.Online.API.Requests;
namespace osu.Game.Screens.Select.Leaderboards
{
@@ -26,6 +30,7 @@ namespace osu.Game.Screens.Select.Leaderboards
set
{
scores = value;
+ getScoresRequest?.Cancel();
int i = 150;
if (scores == null)
@@ -81,6 +86,41 @@ namespace osu.Game.Screens.Select.Leaderboards
};
}
+ private APIAccess api;
+
+ private BeatmapInfo beatmap;
+
+ public BeatmapInfo Beatmap
+ {
+ get { return beatmap; }
+ set
+ {
+ beatmap = value;
+ Schedule(updateScores);
+ }
+ }
+
+ [BackgroundDependencyLoader(permitNulls: true)]
+ private void load(APIAccess api)
+ {
+ this.api = api;
+ }
+
+ private GetScoresRequest getScoresRequest;
+ private void updateScores()
+ {
+ if (!IsLoaded) return;
+
+ Scores = null;
+ getScoresRequest?.Cancel();
+
+ if (api == null || Beatmap == null) return;
+
+ getScoresRequest = new GetScoresRequest(Beatmap);
+ getScoresRequest.Success += r => Scores = r.Scores;
+ api.Queue(getScoresRequest);
+ }
+
protected override void Update()
{
base.Update();
diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs
index 2bac387c5c..493f351b75 100644
--- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs
+++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs
@@ -142,7 +142,7 @@ namespace osu.Game.Screens.Select.Leaderboards
Children = new Drawable[]
{
avatar = new DelayedLoadWrapper(
- new Avatar(Score.User ?? new User { Id = Score.UserID })
+ new Avatar(Score.User)
{
RelativeSizeAxes = Axes.Both,
CornerRadius = corner_radius,
@@ -169,7 +169,7 @@ namespace osu.Game.Screens.Select.Leaderboards
{
nameLabel = new OsuSpriteText
{
- Text = Score.User?.Username ?? Score.Username,
+ Text = Score.User.Username,
Font = @"Exo2.0-BoldItalic",
TextSize = 23,
},
diff --git a/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs b/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs
index b80f76d281..08f270741c 100644
--- a/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs
+++ b/osu.Game/Screens/Tournament/ScrollingTeamContainer.cs
@@ -298,7 +298,7 @@ namespace osu.Game.Screens.Tournament
private void speedTo(float value, double duration = 0, EasingTypes easing = EasingTypes.None)
{
DelayReset();
- TransformTo(speed, value, duration, easing, new TransformScrollSpeed());
+ TransformTo(() => speed, value, duration, easing, new TransformScrollSpeed());
}
private enum ScrollState
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 35c3575071..aa2926b4e5 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -35,17 +35,14 @@
false
-
- $(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
- True
+
+ $(SolutionDir)\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll
- $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll
- True
+ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll
-
- ..\packages\SharpCompress.0.15.1\lib\net45\SharpCompress.dll
- True
+
+ $(SolutionDir)\packages\SharpCompress.0.15.2\lib\net45\SharpCompress.dll
$(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll
@@ -79,6 +76,7 @@
+
@@ -87,6 +85,7 @@
+
@@ -180,6 +179,7 @@
+
@@ -204,6 +204,8 @@
+
+
@@ -391,7 +393,7 @@
-
-
-
-
+
+
+