mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 14:25:05 +08:00
Merge branch 'master' into improve-text-search
This commit is contained in:
commit
e6c197e9aa
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="RulesetTests (catch)" type="DotNetProject" factoryName=".NET Project">
|
<configuration default="false" name="RulesetTests (catch)" type="DotNetProject" factoryName=".NET Project">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Catch.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="RulesetTests (mania)" type="DotNetProject" factoryName=".NET Project">
|
<configuration default="false" name="RulesetTests (mania)" type="DotNetProject" factoryName=".NET Project">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Mania.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="RulesetTests (osu!)" type="DotNetProject" factoryName=".NET Project">
|
<configuration default="false" name="RulesetTests (osu!)" type="DotNetProject" factoryName=".NET Project">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Osu.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="RulesetTests (taiko)" type="DotNetProject" factoryName=".NET Project">
|
<configuration default="false" name="RulesetTests (taiko)" type="DotNetProject" factoryName=".NET Project">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Taiko.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="VisualTests" type="DotNetProject" factoryName=".NET Project">
|
<configuration default="false" name="VisualTests" type="DotNetProject" factoryName=".NET Project">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp2.1/osu.Game.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
|
16
.vscode/launch.json
vendored
16
.vscode/launch.json
vendored
@ -7,13 +7,13 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.1/osu.Game.Tests.dll"
|
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build tests (Debug)",
|
"preLaunchTask": "Build tests (Debug)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
@ -24,13 +24,13 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.1/osu.Game.Tests.dll"
|
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.2/osu.Game.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build tests (Release)",
|
"preLaunchTask": "Build tests (Release)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
@ -41,13 +41,13 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/osu!.dll"
|
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.2/osu!.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build osu! (Debug)",
|
"preLaunchTask": "Build osu! (Debug)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
@ -58,13 +58,13 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1/osu!.dll"
|
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.2/osu!.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build osu! (Release)",
|
"preLaunchTask": "Build osu! (Release)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
|
6
.vscode/tasks.json
vendored
6
.vscode/tasks.json
vendored
@ -11,7 +11,6 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Desktop",
|
"osu.Desktop",
|
||||||
"/p:TargetFramework=netcoreapp2.1",
|
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
"/verbosity:m"
|
"/verbosity:m"
|
||||||
@ -27,7 +26,6 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Desktop",
|
"osu.Desktop",
|
||||||
"/p:TargetFramework=netcoreapp2.1",
|
|
||||||
"/p:Configuration=Release",
|
"/p:Configuration=Release",
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
@ -44,7 +42,6 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Game.Tests",
|
"osu.Game.Tests",
|
||||||
"/p:TargetFramework=netcoreapp2.1",
|
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
"/verbosity:m"
|
"/verbosity:m"
|
||||||
@ -60,7 +57,6 @@
|
|||||||
"build",
|
"build",
|
||||||
"--no-restore",
|
"--no-restore",
|
||||||
"osu.Game.Tests",
|
"osu.Game.Tests",
|
||||||
"/p:TargetFramework=netcoreapp2.1",
|
|
||||||
"/p:Configuration=Release",
|
"/p:Configuration=Release",
|
||||||
"/p:GenerateFullPaths=true",
|
"/p:GenerateFullPaths=true",
|
||||||
"/m",
|
"/m",
|
||||||
@ -70,7 +66,7 @@
|
|||||||
"problemMatcher": "$msCompile"
|
"problemMatcher": "$msCompile"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Restore (netcoreapp2.1)",
|
"label": "Restore (netcoreapp2.2)",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
|
@ -10,7 +10,7 @@ We are accepting bug reports (please report with as much detail as possible). Fe
|
|||||||
|
|
||||||
# Requirements
|
# Requirements
|
||||||
|
|
||||||
- A desktop platform with the [.NET Core SDK 2.1](https://www.microsoft.com/net/learn/get-started) or higher installed.
|
- A desktop platform with the [.NET Core SDK 2.2](https://www.microsoft.com/net/learn/get-started) or higher installed.
|
||||||
- When working with the codebase, we recommend using an IDE with intellisense and syntax highlighting, such as [Visual Studio Community Edition](https://www.visualstudio.com/) (Windows), [Visual Studio Code](https://code.visualstudio.com/) (with the C# plugin installed) or [Jetbrains Rider](https://www.jetbrains.com/rider/) (commercial).
|
- When working with the codebase, we recommend using an IDE with intellisense and syntax highlighting, such as [Visual Studio Community Edition](https://www.visualstudio.com/) (Windows), [Visual Studio Code](https://code.visualstudio.com/) (with the C# plugin installed) or [Jetbrains Rider](https://www.jetbrains.com/rider/) (commercial).
|
||||||
|
|
||||||
# Building and running
|
# Building and running
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 694cb03f19c93106ed0f2593f3e506e835fb652a
|
Subproject commit 9880089b4e8fcd78d68f30c8a40d43bf8dccca86
|
@ -7,7 +7,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll"
|
"${workspaceRoot}/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Catch.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug)",
|
"preLaunchTask": "Build (Debug)",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll"
|
"${workspaceRoot}/bin/Release/netcoreapp2.2/osu.Game.Rulesets.Catch.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release)",
|
"preLaunchTask": "Build (Release)",
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll"
|
"${workspaceRoot}/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Mania.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug)",
|
"preLaunchTask": "Build (Debug)",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll"
|
"${workspaceRoot}/bin/Release/netcoreapp2.2/osu.Game.Rulesets.Mania.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release)",
|
"preLaunchTask": "Build (Release)",
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll"
|
"${workspaceRoot}/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Osu.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug)",
|
"preLaunchTask": "Build (Debug)",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll"
|
"${workspaceRoot}/bin/Release/netcoreapp2.2/osu.Game.Rulesets.Osu.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release)",
|
"preLaunchTask": "Build (Release)",
|
||||||
|
194
osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs
Normal file
194
osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
|
{
|
||||||
|
public class OsuModBlinds : Mod, IApplicableToRulesetContainer<OsuHitObject>, IApplicableToScoreProcessor
|
||||||
|
{
|
||||||
|
public override string Name => "Blinds";
|
||||||
|
public override string Description => "Play with blinds on your screen.";
|
||||||
|
public override string Acronym => "BL";
|
||||||
|
|
||||||
|
public override FontAwesome Icon => FontAwesome.fa_adjust;
|
||||||
|
public override ModType Type => ModType.DifficultyIncrease;
|
||||||
|
|
||||||
|
public override bool Ranked => false;
|
||||||
|
|
||||||
|
public override double ScoreMultiplier => 1.12;
|
||||||
|
private DrawableOsuBlinds blinds;
|
||||||
|
|
||||||
|
public void ApplyToRulesetContainer(RulesetContainer<OsuHitObject> rulesetContainer)
|
||||||
|
{
|
||||||
|
rulesetContainer.Overlays.Add(blinds = new DrawableOsuBlinds(rulesetContainer.Playfield.HitObjectContainer, rulesetContainer.Beatmap));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor)
|
||||||
|
{
|
||||||
|
scoreProcessor.Health.ValueChanged += val => { blinds.AnimateClosedness((float)val); };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Element for the Blinds mod drawing 2 black boxes covering the whole screen which resize inside a restricted area with some leniency.
|
||||||
|
/// </summary>
|
||||||
|
public class DrawableOsuBlinds : Container
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Black background boxes behind blind panel textures.
|
||||||
|
/// </summary>
|
||||||
|
private Box blackBoxLeft, blackBoxRight;
|
||||||
|
|
||||||
|
private Drawable panelLeft, panelRight, bgPanelLeft, bgPanelRight;
|
||||||
|
|
||||||
|
private readonly Beatmap<OsuHitObject> beatmap;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Value between 0 and 1 setting a maximum "closedness" for the blinds.
|
||||||
|
/// Useful for animating how far the blinds can be opened while keeping them at the original position if they are wider open than this.
|
||||||
|
/// </summary>
|
||||||
|
private const float target_clamp = 1;
|
||||||
|
|
||||||
|
private readonly float targetBreakMultiplier = 0;
|
||||||
|
private readonly float easing = 1;
|
||||||
|
|
||||||
|
private readonly CompositeDrawable restrictTo;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>
|
||||||
|
/// Percentage of playfield to extend blinds over. Basically moves the origin points where the blinds start.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// -1 would mean the blinds always cover the whole screen no matter health.
|
||||||
|
/// 0 would mean the blinds will only ever be on the edge of the playfield on 0% health.
|
||||||
|
/// 1 would mean the blinds are fully outside the playfield on 50% health.
|
||||||
|
/// Infinity would mean the blinds are always outside the playfield except on 100% health.
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
private const float leniency = 0.1f;
|
||||||
|
|
||||||
|
public DrawableOsuBlinds(CompositeDrawable restrictTo, Beatmap<OsuHitObject> beatmap)
|
||||||
|
{
|
||||||
|
this.restrictTo = restrictTo;
|
||||||
|
this.beatmap = beatmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
blackBoxLeft = new Box
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopLeft,
|
||||||
|
Origin = Anchor.TopLeft,
|
||||||
|
Colour = Color4.Black,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
},
|
||||||
|
blackBoxRight = new Box
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
Colour = Color4.Black,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
},
|
||||||
|
bgPanelLeft = new ModBlindsPanel
|
||||||
|
{
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
Colour = Color4.Gray,
|
||||||
|
},
|
||||||
|
panelLeft = new ModBlindsPanel { Origin = Anchor.TopRight, },
|
||||||
|
bgPanelRight = new ModBlindsPanel { Colour = Color4.Gray },
|
||||||
|
panelRight = new ModBlindsPanel()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private float calculateGap(float value) => MathHelper.Clamp(value, 0, target_clamp) * targetBreakMultiplier;
|
||||||
|
|
||||||
|
// lagrange polinominal for (0,0) (0.6,0.4) (1,1) should make a good curve
|
||||||
|
private static float applyAdjustmentCurve(float value) => 0.6f * value * value + 0.4f * value;
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
float start = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopLeft).X;
|
||||||
|
float end = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopRight).X;
|
||||||
|
|
||||||
|
float rawWidth = end - start;
|
||||||
|
|
||||||
|
start -= rawWidth * leniency * 0.5f;
|
||||||
|
end += rawWidth * leniency * 0.5f;
|
||||||
|
|
||||||
|
float width = (end - start) * 0.5f * applyAdjustmentCurve(calculateGap(easing));
|
||||||
|
|
||||||
|
// different values in case the playfield ever moves from center to somewhere else.
|
||||||
|
blackBoxLeft.Width = start + width;
|
||||||
|
blackBoxRight.Width = DrawWidth - end + width;
|
||||||
|
|
||||||
|
panelLeft.X = start + width;
|
||||||
|
panelRight.X = end - width;
|
||||||
|
bgPanelLeft.X = start;
|
||||||
|
bgPanelRight.X = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
const float break_open_early = 500;
|
||||||
|
const float break_close_late = 250;
|
||||||
|
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
var firstObj = beatmap.HitObjects[0];
|
||||||
|
var startDelay = firstObj.StartTime - firstObj.TimePreempt;
|
||||||
|
|
||||||
|
using (BeginAbsoluteSequence(startDelay + break_close_late, true))
|
||||||
|
leaveBreak();
|
||||||
|
|
||||||
|
foreach (var breakInfo in beatmap.Breaks)
|
||||||
|
{
|
||||||
|
if (breakInfo.HasEffect)
|
||||||
|
{
|
||||||
|
using (BeginAbsoluteSequence(breakInfo.StartTime - break_open_early, true))
|
||||||
|
{
|
||||||
|
enterBreak();
|
||||||
|
using (BeginDelayedSequence(breakInfo.Duration + break_open_early + break_close_late, true))
|
||||||
|
leaveBreak();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enterBreak() => this.TransformTo(nameof(targetBreakMultiplier), 0f, 1000, Easing.OutSine);
|
||||||
|
|
||||||
|
private void leaveBreak() => this.TransformTo(nameof(targetBreakMultiplier), 1f, 2500, Easing.OutBounce);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 0 is open, 1 is closed.
|
||||||
|
/// </summary>
|
||||||
|
public void AnimateClosedness(float value) => this.TransformTo(nameof(easing), value, 200, Easing.OutQuint);
|
||||||
|
|
||||||
|
public class ModBlindsPanel : Sprite
|
||||||
|
{
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(TextureStore textures)
|
||||||
|
{
|
||||||
|
Texture = textures.Get("Play/osu/blinds-panel");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -26,9 +26,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
if (slider == null)
|
if (slider == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
slider.HeadCircle.Position = new Vector2(slider.HeadCircle.Position.X, OsuPlayfield.BASE_SIZE.Y - slider.HeadCircle.Position.Y);
|
|
||||||
slider.TailCircle.Position = new Vector2(slider.TailCircle.Position.X, OsuPlayfield.BASE_SIZE.Y - slider.TailCircle.Position.Y);
|
|
||||||
|
|
||||||
slider.NestedHitObjects.OfType<SliderTick>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
slider.NestedHitObjects.OfType<SliderTick>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
||||||
slider.NestedHitObjects.OfType<RepeatPoint>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
slider.NestedHitObjects.OfType<RepeatPoint>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
|
|
||||||
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
|
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
|
||||||
{
|
{
|
||||||
new KeyBinding(InputKey.A, OsuAction.LeftButton),
|
new KeyBinding(InputKey.Z, OsuAction.LeftButton),
|
||||||
new KeyBinding(InputKey.S, OsuAction.RightButton),
|
new KeyBinding(InputKey.X, OsuAction.RightButton),
|
||||||
new KeyBinding(InputKey.MouseLeft, OsuAction.LeftButton),
|
new KeyBinding(InputKey.MouseLeft, OsuAction.LeftButton),
|
||||||
new KeyBinding(InputKey.MouseRight, OsuAction.RightButton),
|
new KeyBinding(InputKey.MouseRight, OsuAction.RightButton),
|
||||||
};
|
};
|
||||||
@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
new MultiMod(new OsuModSuddenDeath(), new OsuModPerfect()),
|
new MultiMod(new OsuModSuddenDeath(), new OsuModPerfect()),
|
||||||
new MultiMod(new OsuModDoubleTime(), new OsuModNightcore()),
|
new MultiMod(new OsuModDoubleTime(), new OsuModNightcore()),
|
||||||
new OsuModHidden(),
|
new OsuModHidden(),
|
||||||
new OsuModFlashlight(),
|
new MultiMod(new OsuModFlashlight(), new OsuModBlinds()),
|
||||||
};
|
};
|
||||||
case ModType.Conversion:
|
case ModType.Conversion:
|
||||||
return new Mod[]
|
return new Mod[]
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll"
|
"${workspaceRoot}/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Taiko.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug)",
|
"preLaunchTask": "Build (Debug)",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll"
|
"${workspaceRoot}/bin/Release/netcoreapp2.2/osu.Game.Rulesets.Taiko.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release)",
|
"preLaunchTask": "Build (Release)",
|
||||||
|
67
osu.Game.Tests/Visual/TestCaseDrawableDate.cs
Normal file
67
osu.Game.Tests/Visual/TestCaseDrawableDate.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseDrawableDate : OsuTestCase
|
||||||
|
{
|
||||||
|
public TestCaseDrawableDate()
|
||||||
|
{
|
||||||
|
Child = new FillFlowContainer
|
||||||
|
{
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new PokeyDrawableDate(DateTimeOffset.Now.Subtract(TimeSpan.FromSeconds(60))),
|
||||||
|
new PokeyDrawableDate(DateTimeOffset.Now.Subtract(TimeSpan.FromSeconds(55))),
|
||||||
|
new PokeyDrawableDate(DateTimeOffset.Now.Subtract(TimeSpan.FromSeconds(50))),
|
||||||
|
new PokeyDrawableDate(DateTimeOffset.Now),
|
||||||
|
new PokeyDrawableDate(DateTimeOffset.Now.Add(TimeSpan.FromSeconds(60))),
|
||||||
|
new PokeyDrawableDate(DateTimeOffset.Now.Add(TimeSpan.FromSeconds(65))),
|
||||||
|
new PokeyDrawableDate(DateTimeOffset.Now.Add(TimeSpan.FromSeconds(70))),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PokeyDrawableDate : CompositeDrawable
|
||||||
|
{
|
||||||
|
public PokeyDrawableDate(DateTimeOffset date)
|
||||||
|
{
|
||||||
|
const float box_size = 10;
|
||||||
|
|
||||||
|
DrawableDate drawableDate;
|
||||||
|
Box flash;
|
||||||
|
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
flash = new Box
|
||||||
|
{
|
||||||
|
Colour = Color4.Yellow,
|
||||||
|
Size = new Vector2(box_size),
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
Alpha = 0
|
||||||
|
},
|
||||||
|
drawableDate = new DrawableDate(date)
|
||||||
|
{
|
||||||
|
X = box_size + 2,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
drawableDate.Current.ValueChanged += v => flash.FadeOutFromOne(500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ using osu.Framework.Allocation;
|
|||||||
using osuTK;
|
using osuTK;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Online.Leaderboards;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Size = new Vector2(550f, 450f),
|
Size = new Vector2(550f, 450f),
|
||||||
Scope = LeaderboardScope.Global,
|
Scope = BeatmapLeaderboardScope.Global,
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep(@"New Scores", newScores);
|
AddStep(@"New Scores", newScores);
|
||||||
@ -275,7 +276,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FailableLeaderboard : Leaderboard
|
private class FailableLeaderboard : BeatmapLeaderboard
|
||||||
{
|
{
|
||||||
public void SetRetrievalState(PlaceholderState state)
|
public void SetRetrievalState(PlaceholderState state)
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,9 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
|
using osu.Game.Screens.Ranking.Pages;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
@ -23,8 +25,8 @@ namespace osu.Game.Tests.Visual
|
|||||||
typeof(ScoreInfo),
|
typeof(ScoreInfo),
|
||||||
typeof(Results),
|
typeof(Results),
|
||||||
typeof(ResultsPage),
|
typeof(ResultsPage),
|
||||||
typeof(ResultsPageScore),
|
typeof(ScoreResultsPage),
|
||||||
typeof(ResultsPageRanking)
|
typeof(RankingResultsPage)
|
||||||
};
|
};
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -41,7 +43,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
if (beatmapInfo != null)
|
if (beatmapInfo != null)
|
||||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo);
|
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo);
|
||||||
|
|
||||||
Add(new Results(new ScoreInfo
|
Add(new SoloResults(new ScoreInfo
|
||||||
{
|
{
|
||||||
TotalScore = 2845370,
|
TotalScore = 2845370,
|
||||||
Accuracy = 0.98,
|
Accuracy = 0.98,
|
||||||
|
104
osu.Game.Tests/Visual/TestCaseStandAloneChatDisplay.cs
Normal file
104
osu.Game.Tests/Visual/TestCaseStandAloneChatDisplay.cs
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Online.Chat;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseStandAloneChatDisplay : OsuTestCase
|
||||||
|
{
|
||||||
|
private readonly Channel testChannel = new Channel();
|
||||||
|
|
||||||
|
private readonly User admin = new User
|
||||||
|
{
|
||||||
|
Username = "HappyStick",
|
||||||
|
Id = 2,
|
||||||
|
Colour = "f2ca34"
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly User redUser = new User
|
||||||
|
{
|
||||||
|
Username = "BanchoBot",
|
||||||
|
Id = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly User blueUser = new User
|
||||||
|
{
|
||||||
|
Username = "Zallius",
|
||||||
|
Id = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
[Cached]
|
||||||
|
private ChannelManager channelManager = new ChannelManager();
|
||||||
|
|
||||||
|
private readonly StandAloneChatDisplay chatDisplay;
|
||||||
|
private readonly StandAloneChatDisplay chatDisplay2;
|
||||||
|
|
||||||
|
public TestCaseStandAloneChatDisplay()
|
||||||
|
{
|
||||||
|
Add(channelManager);
|
||||||
|
|
||||||
|
Add(chatDisplay = new StandAloneChatDisplay
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
Margin = new MarginPadding(20),
|
||||||
|
Size = new Vector2(400, 80)
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(chatDisplay2 = new StandAloneChatDisplay(true)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreRight,
|
||||||
|
Origin = Anchor.CentreRight,
|
||||||
|
Margin = new MarginPadding(20),
|
||||||
|
Size = new Vector2(400, 150)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
channelManager.CurrentChannel.Value = testChannel;
|
||||||
|
|
||||||
|
chatDisplay.Channel.Value = testChannel;
|
||||||
|
chatDisplay2.Channel.Value = testChannel;
|
||||||
|
|
||||||
|
int sequence = 0;
|
||||||
|
|
||||||
|
AddStep("message from admin", () => testChannel.AddNewMessages(new Message(sequence++)
|
||||||
|
{
|
||||||
|
Sender = admin,
|
||||||
|
Content = "I am a wang!"
|
||||||
|
}));
|
||||||
|
|
||||||
|
AddStep("message from team red", () => testChannel.AddNewMessages(new Message(sequence++)
|
||||||
|
{
|
||||||
|
Sender = redUser,
|
||||||
|
Content = "I am team red."
|
||||||
|
}));
|
||||||
|
|
||||||
|
AddStep("message from team red", () => testChannel.AddNewMessages(new Message(sequence++)
|
||||||
|
{
|
||||||
|
Sender = redUser,
|
||||||
|
Content = "I plan to win!"
|
||||||
|
}));
|
||||||
|
|
||||||
|
AddStep("message from team blue", () => testChannel.AddNewMessages(new Message(sequence++)
|
||||||
|
{
|
||||||
|
Sender = blueUser,
|
||||||
|
Content = "Not on my watch. Prepare to eat saaaaaaaaaand. Lots and lots of saaaaaaand."
|
||||||
|
}));
|
||||||
|
|
||||||
|
AddStep("message from admin", () => testChannel.AddNewMessages(new Message(sequence++)
|
||||||
|
{
|
||||||
|
Sender = admin,
|
||||||
|
Content = "Okay okay, calm down guys. Let's do this!"
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
@ -11,13 +12,27 @@ namespace osu.Game.Graphics
|
|||||||
{
|
{
|
||||||
public class DrawableDate : OsuSpriteText, IHasTooltip
|
public class DrawableDate : OsuSpriteText, IHasTooltip
|
||||||
{
|
{
|
||||||
protected readonly DateTimeOffset Date;
|
private DateTimeOffset date;
|
||||||
|
|
||||||
|
public DateTimeOffset Date
|
||||||
|
{
|
||||||
|
get => date;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (date == value)
|
||||||
|
return;
|
||||||
|
date = value.ToLocalTime();
|
||||||
|
|
||||||
|
if (LoadState >= LoadState.Ready)
|
||||||
|
updateTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public DrawableDate(DateTimeOffset date)
|
public DrawableDate(DateTimeOffset date)
|
||||||
{
|
{
|
||||||
Font = "Exo2.0-RegularItalic";
|
Font = "Exo2.0-RegularItalic";
|
||||||
|
|
||||||
Date = date.ToLocalTime();
|
Date = date;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -39,14 +54,14 @@ namespace osu.Game.Graphics
|
|||||||
var diffToNow = DateTimeOffset.Now.Subtract(Date);
|
var diffToNow = DateTimeOffset.Now.Subtract(Date);
|
||||||
|
|
||||||
double timeUntilNextUpdate = 1000;
|
double timeUntilNextUpdate = 1000;
|
||||||
if (diffToNow.TotalSeconds > 60)
|
if (Math.Abs(diffToNow.TotalSeconds) > 120)
|
||||||
{
|
{
|
||||||
timeUntilNextUpdate *= 60;
|
timeUntilNextUpdate *= 60;
|
||||||
if (diffToNow.TotalMinutes > 60)
|
if (Math.Abs(diffToNow.TotalMinutes) > 120)
|
||||||
{
|
{
|
||||||
timeUntilNextUpdate *= 60;
|
timeUntilNextUpdate *= 60;
|
||||||
|
|
||||||
if (diffToNow.TotalHours > 24)
|
if (Math.Abs(diffToNow.TotalHours) > 48)
|
||||||
timeUntilNextUpdate *= 24;
|
timeUntilNextUpdate *= 24;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
@ -99,7 +100,20 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bindable<bool> Current { get; } = new Bindable<bool>();
|
private readonly Bindable<bool> current = new Bindable<bool>();
|
||||||
|
|
||||||
|
public Bindable<bool> Current
|
||||||
|
{
|
||||||
|
get => current;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
|
||||||
|
current.UnbindBindings();
|
||||||
|
current.BindTo(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Color4 accentColour;
|
private Color4 accentColour;
|
||||||
public Color4 AccentColour
|
public Color4 AccentColour
|
||||||
|
@ -13,15 +13,15 @@ namespace osu.Game.Online.API.Requests
|
|||||||
public class GetScoresRequest : APIRequest<APIScores>
|
public class GetScoresRequest : APIRequest<APIScores>
|
||||||
{
|
{
|
||||||
private readonly BeatmapInfo beatmap;
|
private readonly BeatmapInfo beatmap;
|
||||||
private readonly LeaderboardScope scope;
|
private readonly BeatmapLeaderboardScope scope;
|
||||||
private readonly RulesetInfo ruleset;
|
private readonly RulesetInfo ruleset;
|
||||||
|
|
||||||
public GetScoresRequest(BeatmapInfo beatmap, RulesetInfo ruleset, LeaderboardScope scope = LeaderboardScope.Global)
|
public GetScoresRequest(BeatmapInfo beatmap, RulesetInfo ruleset, BeatmapLeaderboardScope scope = BeatmapLeaderboardScope.Global)
|
||||||
{
|
{
|
||||||
if (!beatmap.OnlineBeatmapID.HasValue)
|
if (!beatmap.OnlineBeatmapID.HasValue)
|
||||||
throw new InvalidOperationException($"Cannot lookup a beatmap's scores without having a populated {nameof(BeatmapInfo.OnlineBeatmapID)}.");
|
throw new InvalidOperationException($"Cannot lookup a beatmap's scores without having a populated {nameof(BeatmapInfo.OnlineBeatmapID)}.");
|
||||||
|
|
||||||
if (scope == LeaderboardScope.Local)
|
if (scope == BeatmapLeaderboardScope.Local)
|
||||||
throw new InvalidOperationException("Should not attempt to request online scores for a local scoped leaderboard");
|
throw new InvalidOperationException("Should not attempt to request online scores for a local scoped leaderboard");
|
||||||
|
|
||||||
this.beatmap = beatmap;
|
this.beatmap = beatmap;
|
||||||
|
@ -96,12 +96,14 @@ namespace osu.Game.Online.Chat
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text">The message text that is going to be posted</param>
|
/// <param name="text">The message text that is going to be posted</param>
|
||||||
/// <param name="isAction">Is true if the message is an action, e.g.: user is currently eating </param>
|
/// <param name="isAction">Is true if the message is an action, e.g.: user is currently eating </param>
|
||||||
public void PostMessage(string text, bool isAction = false)
|
/// <param name="target">An optional target channel. If null, <see cref="CurrentChannel"/> will be used.</param>
|
||||||
|
public void PostMessage(string text, bool isAction = false, Channel target = null)
|
||||||
{
|
{
|
||||||
if (CurrentChannel.Value == null)
|
if (target == null)
|
||||||
return;
|
target = CurrentChannel.Value;
|
||||||
|
|
||||||
var currentChannel = CurrentChannel.Value;
|
if (target == null)
|
||||||
|
return;
|
||||||
|
|
||||||
void dequeueAndRun()
|
void dequeueAndRun()
|
||||||
{
|
{
|
||||||
@ -113,7 +115,7 @@ namespace osu.Game.Online.Chat
|
|||||||
{
|
{
|
||||||
if (!api.IsLoggedIn)
|
if (!api.IsLoggedIn)
|
||||||
{
|
{
|
||||||
currentChannel.AddNewMessages(new ErrorMessage("Please sign in to participate in chat!"));
|
target.AddNewMessages(new ErrorMessage("Please sign in to participate in chat!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,29 +123,29 @@ namespace osu.Game.Online.Chat
|
|||||||
{
|
{
|
||||||
Sender = api.LocalUser.Value,
|
Sender = api.LocalUser.Value,
|
||||||
Timestamp = DateTimeOffset.Now,
|
Timestamp = DateTimeOffset.Now,
|
||||||
ChannelId = CurrentChannel.Value.Id,
|
ChannelId = target.Id,
|
||||||
IsAction = isAction,
|
IsAction = isAction,
|
||||||
Content = text
|
Content = text
|
||||||
};
|
};
|
||||||
|
|
||||||
currentChannel.AddLocalEcho(message);
|
target.AddLocalEcho(message);
|
||||||
|
|
||||||
// if this is a PM and the first message, we need to do a special request to create the PM channel
|
// if this is a PM and the first message, we need to do a special request to create the PM channel
|
||||||
if (currentChannel.Type == ChannelType.PM && !currentChannel.Joined)
|
if (target.Type == ChannelType.PM && !target.Joined)
|
||||||
{
|
{
|
||||||
var createNewPrivateMessageRequest = new CreateNewPrivateMessageRequest(currentChannel.Users.First(), message);
|
var createNewPrivateMessageRequest = new CreateNewPrivateMessageRequest(target.Users.First(), message);
|
||||||
|
|
||||||
createNewPrivateMessageRequest.Success += createRes =>
|
createNewPrivateMessageRequest.Success += createRes =>
|
||||||
{
|
{
|
||||||
currentChannel.Id = createRes.ChannelID;
|
target.Id = createRes.ChannelID;
|
||||||
currentChannel.ReplaceMessage(message, createRes.Message);
|
target.ReplaceMessage(message, createRes.Message);
|
||||||
dequeueAndRun();
|
dequeueAndRun();
|
||||||
};
|
};
|
||||||
|
|
||||||
createNewPrivateMessageRequest.Failure += exception =>
|
createNewPrivateMessageRequest.Failure += exception =>
|
||||||
{
|
{
|
||||||
Logger.Error(exception, "Posting message failed.");
|
Logger.Error(exception, "Posting message failed.");
|
||||||
currentChannel.ReplaceMessage(message, null);
|
target.ReplaceMessage(message, null);
|
||||||
dequeueAndRun();
|
dequeueAndRun();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -155,14 +157,14 @@ namespace osu.Game.Online.Chat
|
|||||||
|
|
||||||
req.Success += m =>
|
req.Success += m =>
|
||||||
{
|
{
|
||||||
currentChannel.ReplaceMessage(message, m);
|
target.ReplaceMessage(message, m);
|
||||||
dequeueAndRun();
|
dequeueAndRun();
|
||||||
};
|
};
|
||||||
|
|
||||||
req.Failure += exception =>
|
req.Failure += exception =>
|
||||||
{
|
{
|
||||||
Logger.Error(exception, "Posting message failed.");
|
Logger.Error(exception, "Posting message failed.");
|
||||||
currentChannel.ReplaceMessage(message, null);
|
target.ReplaceMessage(message, null);
|
||||||
dequeueAndRun();
|
dequeueAndRun();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -178,9 +180,13 @@ namespace osu.Game.Online.Chat
|
|||||||
/// Posts a command locally. Commands like /help will result in a help message written in the current channel.
|
/// Posts a command locally. Commands like /help will result in a help message written in the current channel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text">the text containing the command identifier and command parameters.</param>
|
/// <param name="text">the text containing the command identifier and command parameters.</param>
|
||||||
public void PostCommand(string text)
|
/// <param name="target">An optional target channel. If null, <see cref="CurrentChannel"/> will be used.</param>
|
||||||
|
public void PostCommand(string text, Channel target = null)
|
||||||
{
|
{
|
||||||
if (CurrentChannel.Value == null)
|
if (target == null)
|
||||||
|
target = CurrentChannel.Value;
|
||||||
|
|
||||||
|
if (target == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var parameters = text.Split(new[] { ' ' }, 2);
|
var parameters = text.Split(new[] { ' ' }, 2);
|
||||||
@ -192,7 +198,7 @@ namespace osu.Game.Online.Chat
|
|||||||
case "me":
|
case "me":
|
||||||
if (string.IsNullOrWhiteSpace(content))
|
if (string.IsNullOrWhiteSpace(content))
|
||||||
{
|
{
|
||||||
CurrentChannel.Value.AddNewMessages(new ErrorMessage("Usage: /me [action]"));
|
target.AddNewMessages(new ErrorMessage("Usage: /me [action]"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,11 +206,11 @@ namespace osu.Game.Online.Chat
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "help":
|
case "help":
|
||||||
CurrentChannel.Value.AddNewMessages(new InfoMessage("Supported commands: /help, /me [action]"));
|
target.AddNewMessages(new InfoMessage("Supported commands: /help, /me [action]"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
CurrentChannel.Value.AddNewMessages(new ErrorMessage($@"""/{command}"" is not supported! For a list of supported commands see /help"));
|
target.AddNewMessages(new ErrorMessage($@"""/{command}"" is not supported! For a list of supported commands see /help"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
148
osu.Game/Online/Chat/StandAloneChatDisplay.cs
Normal file
148
osu.Game/Online/Chat/StandAloneChatDisplay.cs
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Overlays.Chat;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.Chat
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Display a chat channel in an insolated region.
|
||||||
|
/// </summary>
|
||||||
|
public class StandAloneChatDisplay : CompositeDrawable
|
||||||
|
{
|
||||||
|
private readonly bool postingTextbox;
|
||||||
|
|
||||||
|
public readonly Bindable<Channel> Channel = new Bindable<Channel>();
|
||||||
|
|
||||||
|
private readonly FocusedTextBox textbox;
|
||||||
|
|
||||||
|
protected ChannelManager ChannelManager;
|
||||||
|
|
||||||
|
private ScrollContainer scroll;
|
||||||
|
|
||||||
|
private DrawableChannel drawableChannel;
|
||||||
|
|
||||||
|
private const float textbox_height = 30;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Construct a new instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="postingTextbox">Whether a textbox for posting new messages should be displayed.</param>
|
||||||
|
public StandAloneChatDisplay(bool postingTextbox = false)
|
||||||
|
{
|
||||||
|
this.postingTextbox = postingTextbox;
|
||||||
|
CornerRadius = 10;
|
||||||
|
Masking = true;
|
||||||
|
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Colour = Color4.Black,
|
||||||
|
Alpha = 0.8f,
|
||||||
|
RelativeSizeAxes = Axes.Both
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (postingTextbox)
|
||||||
|
{
|
||||||
|
AddInternal(textbox = new FocusedTextBox
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = textbox_height,
|
||||||
|
PlaceholderText = "type your message",
|
||||||
|
OnCommit = postMessage,
|
||||||
|
ReleaseFocusOnCommit = false,
|
||||||
|
HoldFocus = true,
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Channel.BindValueChanged(channelChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader(true)]
|
||||||
|
private void load(ChannelManager manager)
|
||||||
|
{
|
||||||
|
if (ChannelManager == null)
|
||||||
|
ChannelManager = manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postMessage(TextBox sender, bool newtext)
|
||||||
|
{
|
||||||
|
var text = textbox.Text.Trim();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (text[0] == '/')
|
||||||
|
ChannelManager?.PostCommand(text.Substring(1), Channel);
|
||||||
|
else
|
||||||
|
ChannelManager?.PostMessage(text, target: Channel);
|
||||||
|
|
||||||
|
textbox.Text = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Contract()
|
||||||
|
{
|
||||||
|
this.FadeIn(300);
|
||||||
|
this.MoveToY(0, 500, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Expand()
|
||||||
|
{
|
||||||
|
this.FadeOut(200);
|
||||||
|
this.MoveToY(100, 500, Easing.In);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual ChatLine CreateMessage(Message message) => new StandAloneMessage(message);
|
||||||
|
|
||||||
|
private void channelChanged(Channel channel)
|
||||||
|
{
|
||||||
|
drawableChannel?.Expire();
|
||||||
|
|
||||||
|
if (channel == null) return;
|
||||||
|
|
||||||
|
AddInternal(drawableChannel = new StandAloneDrawableChannel(channel)
|
||||||
|
{
|
||||||
|
CreateChatLineAction = CreateMessage,
|
||||||
|
Padding = new MarginPadding { Bottom = postingTextbox ? textbox_height : 0 }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class StandAloneDrawableChannel : DrawableChannel
|
||||||
|
{
|
||||||
|
public Func<Message,ChatLine> CreateChatLineAction;
|
||||||
|
|
||||||
|
protected override ChatLine CreateChatLine(Message m) => CreateChatLineAction(m);
|
||||||
|
|
||||||
|
public StandAloneDrawableChannel(Channel channel)
|
||||||
|
: base(channel)
|
||||||
|
{
|
||||||
|
ChatLineFlow.Padding = new MarginPadding { Horizontal = 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class StandAloneMessage : ChatLine
|
||||||
|
{
|
||||||
|
protected override float TextSize => 15;
|
||||||
|
|
||||||
|
protected override float HorizontalPadding => 10;
|
||||||
|
protected override float MessagePadding => 120;
|
||||||
|
|
||||||
|
public StandAloneMessage(Message message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,14 +2,14 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Extensions;
|
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Online.Leaderboards
|
||||||
{
|
{
|
||||||
public class DrawableRank : Container
|
public class DrawableRank : Container
|
||||||
{
|
{
|
@ -3,27 +3,22 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osuTK;
|
using System.Linq;
|
||||||
using osuTK.Graphics;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Colour;
|
using osu.Framework.Graphics.Colour;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests;
|
using osuTK;
|
||||||
using System.Linq;
|
using osuTK.Graphics;
|
||||||
using osu.Framework.Configuration;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Scoring;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Online.Leaderboards
|
||||||
{
|
{
|
||||||
public class Leaderboard : Container
|
public abstract class Leaderboard<TScope, ScoreInfo> : Container
|
||||||
{
|
{
|
||||||
private const double fade_duration = 300;
|
private const double fade_duration = 300;
|
||||||
|
|
||||||
@ -32,10 +27,6 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
private FillFlowContainer<LeaderboardScore> scrollFlow;
|
private FillFlowContainer<LeaderboardScore> scrollFlow;
|
||||||
|
|
||||||
private readonly IBindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
|
||||||
|
|
||||||
public Action<ScoreInfo> ScoreSelected;
|
|
||||||
|
|
||||||
private readonly LoadingAnimation loading;
|
private readonly LoadingAnimation loading;
|
||||||
|
|
||||||
private ScheduledDelegate showScoresDelegate;
|
private ScheduledDelegate showScoresDelegate;
|
||||||
@ -70,7 +61,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Spacing = new Vector2(0f, 5f),
|
Spacing = new Vector2(0f, 5f),
|
||||||
Padding = new MarginPadding { Top = 10, Bottom = 5 },
|
Padding = new MarginPadding { Top = 10, Bottom = 5 },
|
||||||
ChildrenEnumerable = scores.Select((s, index) => new LeaderboardScore(s, index + 1) { Action = () => ScoreSelected?.Invoke(s) })
|
ChildrenEnumerable = scores.Select((s, index) => CreateDrawableScore(s, index + 1))
|
||||||
};
|
};
|
||||||
|
|
||||||
// schedule because we may not be loaded yet (LoadComponentAsync complains).
|
// schedule because we may not be loaded yet (LoadComponentAsync complains).
|
||||||
@ -96,18 +87,18 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private LeaderboardScope scope;
|
private TScope scope;
|
||||||
|
|
||||||
public LeaderboardScope Scope
|
public TScope Scope
|
||||||
{
|
{
|
||||||
get { return scope; }
|
get { return scope; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == scope)
|
if (value.Equals(scope))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scope = value;
|
scope = value;
|
||||||
updateScores();
|
UpdateScores();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +128,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
case PlaceholderState.NetworkFailure:
|
case PlaceholderState.NetworkFailure:
|
||||||
replacePlaceholder(new RetrievalFailurePlaceholder
|
replacePlaceholder(new RetrievalFailurePlaceholder
|
||||||
{
|
{
|
||||||
OnRetry = updateScores,
|
OnRetry = UpdateScores,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case PlaceholderState.Unavailable:
|
case PlaceholderState.Unavailable:
|
||||||
@ -159,7 +150,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Leaderboard()
|
protected Leaderboard()
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
@ -177,36 +168,14 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
}
|
}
|
||||||
|
|
||||||
private APIAccess api;
|
private APIAccess api;
|
||||||
private BeatmapInfo beatmap;
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private ScoreManager scoreManager { get; set; }
|
|
||||||
|
|
||||||
private ScheduledDelegate pendingUpdateScores;
|
private ScheduledDelegate pendingUpdateScores;
|
||||||
|
|
||||||
public BeatmapInfo Beatmap
|
[BackgroundDependencyLoader(true)]
|
||||||
{
|
private void load(APIAccess api)
|
||||||
get { return beatmap; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (beatmap == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
beatmap = value;
|
|
||||||
Scores = null;
|
|
||||||
|
|
||||||
updateScores();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader(permitNulls: true)]
|
|
||||||
private void load(APIAccess api, IBindable<RulesetInfo> parentRuleset)
|
|
||||||
{
|
{
|
||||||
this.api = api;
|
this.api = api;
|
||||||
|
|
||||||
ruleset.BindTo(parentRuleset);
|
|
||||||
ruleset.ValueChanged += _ => updateScores();
|
|
||||||
|
|
||||||
if (api != null)
|
if (api != null)
|
||||||
api.OnStateChange += handleApiStateChange;
|
api.OnStateChange += handleApiStateChange;
|
||||||
}
|
}
|
||||||
@ -219,21 +188,17 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
api.OnStateChange -= handleApiStateChange;
|
api.OnStateChange -= handleApiStateChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RefreshScores() => updateScores();
|
public void RefreshScores() => UpdateScores();
|
||||||
|
|
||||||
private GetScoresRequest getScoresRequest;
|
private APIRequest getScoresRequest;
|
||||||
|
|
||||||
private void handleApiStateChange(APIState oldState, APIState newState)
|
private void handleApiStateChange(APIState oldState, APIState newState)
|
||||||
{
|
{
|
||||||
if (Scope == LeaderboardScope.Local)
|
|
||||||
// No need to respond to API state change while current scope is local
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (newState == APIState.Online)
|
if (newState == APIState.Online)
|
||||||
updateScores();
|
UpdateScores();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateScores()
|
protected void UpdateScores()
|
||||||
{
|
{
|
||||||
// don't display any scores or placeholder until the first Scores_Set has been called.
|
// don't display any scores or placeholder until the first Scores_Set has been called.
|
||||||
// this avoids scope changes flickering a "no scores" placeholder before initialisation of song select is finished.
|
// this avoids scope changes flickering a "no scores" placeholder before initialisation of song select is finished.
|
||||||
@ -245,40 +210,23 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
pendingUpdateScores?.Cancel();
|
pendingUpdateScores?.Cancel();
|
||||||
pendingUpdateScores = Schedule(() =>
|
pendingUpdateScores = Schedule(() =>
|
||||||
{
|
{
|
||||||
if (Scope == LeaderboardScope.Local)
|
|
||||||
{
|
|
||||||
Scores = scoreManager.QueryScores(s => s.Beatmap.ID == Beatmap.ID).ToArray();
|
|
||||||
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Beatmap?.OnlineBeatmapID == null)
|
|
||||||
{
|
|
||||||
PlaceholderState = PlaceholderState.Unavailable;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (api?.IsLoggedIn != true)
|
if (api?.IsLoggedIn != true)
|
||||||
{
|
{
|
||||||
PlaceholderState = PlaceholderState.NotLoggedIn;
|
PlaceholderState = PlaceholderState.NotLoggedIn;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Scope != LeaderboardScope.Global && !api.LocalUser.Value.IsSupporter)
|
|
||||||
{
|
|
||||||
PlaceholderState = PlaceholderState.NotSupporter;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlaceholderState = PlaceholderState.Retrieving;
|
PlaceholderState = PlaceholderState.Retrieving;
|
||||||
loading.Show();
|
loading.Show();
|
||||||
|
|
||||||
getScoresRequest = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope);
|
getScoresRequest = FetchScores(scores => Schedule(() =>
|
||||||
getScoresRequest.Success += r => Schedule(() =>
|
|
||||||
{
|
{
|
||||||
Scores = r.Scores;
|
Scores = scores;
|
||||||
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
||||||
});
|
}));
|
||||||
|
|
||||||
|
if (getScoresRequest == null)
|
||||||
|
return;
|
||||||
|
|
||||||
getScoresRequest.Failure += e => Schedule(() =>
|
getScoresRequest.Failure += e => Schedule(() =>
|
||||||
{
|
{
|
||||||
@ -292,6 +240,8 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract APIRequest FetchScores(Action<IEnumerable<ScoreInfo>> scoresCallback);
|
||||||
|
|
||||||
private Placeholder currentPlaceholder;
|
private Placeholder currentPlaceholder;
|
||||||
|
|
||||||
private void replacePlaceholder(Placeholder placeholder)
|
private void replacePlaceholder(Placeholder placeholder)
|
||||||
@ -344,5 +294,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract LeaderboardScore CreateDrawableScore(ScoreInfo model, int index);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,9 +1,8 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osuTK;
|
|
||||||
using osuTK.Graphics;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -17,35 +16,40 @@ using osu.Game.Graphics.Sprites;
|
|||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Online.Leaderboards
|
||||||
{
|
{
|
||||||
public class LeaderboardScore : OsuClickableContainer
|
public class LeaderboardScore : OsuClickableContainer
|
||||||
{
|
{
|
||||||
public static readonly float HEIGHT = 60;
|
|
||||||
|
|
||||||
public readonly int RankPosition;
|
public readonly int RankPosition;
|
||||||
public readonly ScoreInfo Score;
|
|
||||||
|
public const float HEIGHT = 60;
|
||||||
|
|
||||||
private const float corner_radius = 5;
|
private const float corner_radius = 5;
|
||||||
private const float edge_margin = 5;
|
private const float edge_margin = 5;
|
||||||
private const float background_alpha = 0.25f;
|
private const float background_alpha = 0.25f;
|
||||||
private const float rank_width = 30;
|
private const float rank_width = 30;
|
||||||
|
|
||||||
|
protected Container RankContainer { get; private set; }
|
||||||
|
|
||||||
|
private readonly ScoreInfo score;
|
||||||
|
|
||||||
private Box background;
|
private Box background;
|
||||||
private Container content;
|
private Container content;
|
||||||
private Drawable avatar;
|
private Drawable avatar;
|
||||||
private DrawableRank scoreRank;
|
private Drawable scoreRank;
|
||||||
private OsuSpriteText nameLabel;
|
private OsuSpriteText nameLabel;
|
||||||
private GlowingSpriteText scoreLabel;
|
private GlowingSpriteText scoreLabel;
|
||||||
private ScoreComponentLabel maxCombo;
|
|
||||||
private ScoreComponentLabel accuracy;
|
|
||||||
private Container flagBadgeContainer;
|
private Container flagBadgeContainer;
|
||||||
private FillFlowContainer<ModIcon> modsContainer;
|
private FillFlowContainer<ModIcon> modsContainer;
|
||||||
|
|
||||||
|
private List<ScoreComponentLabel> statisticsLabels;
|
||||||
|
|
||||||
public LeaderboardScore(ScoreInfo score, int rank)
|
public LeaderboardScore(ScoreInfo score, int rank)
|
||||||
{
|
{
|
||||||
Score = score;
|
this.score = score;
|
||||||
RankPosition = rank;
|
RankPosition = rank;
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
@ -55,6 +59,10 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
var user = score.User;
|
||||||
|
|
||||||
|
statisticsLabels = GetStatistics(score).Select(s => new ScoreComponentLabel(s)).ToList();
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new Container
|
new Container
|
||||||
@ -102,7 +110,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
avatar = new DelayedLoadWrapper(
|
avatar = new DelayedLoadWrapper(
|
||||||
new Avatar(Score.User)
|
new Avatar(user)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
CornerRadius = corner_radius,
|
CornerRadius = corner_radius,
|
||||||
@ -128,7 +136,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
{
|
{
|
||||||
nameLabel = new OsuSpriteText
|
nameLabel = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = Score.User.Username,
|
Text = user.Username,
|
||||||
Font = @"Exo2.0-BoldItalic",
|
Font = @"Exo2.0-BoldItalic",
|
||||||
TextSize = 23,
|
TextSize = 23,
|
||||||
},
|
},
|
||||||
@ -149,7 +157,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
Masking = true,
|
Masking = true,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new DrawableFlag(Score.User?.Country)
|
new DrawableFlag(user.Country)
|
||||||
{
|
{
|
||||||
Width = 30,
|
Width = 30,
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
@ -164,11 +172,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
Direction = FillDirection.Horizontal,
|
Direction = FillDirection.Horizontal,
|
||||||
Spacing = new Vector2(10f, 0f),
|
Spacing = new Vector2(10f, 0f),
|
||||||
Margin = new MarginPadding { Left = edge_margin },
|
Margin = new MarginPadding { Left = edge_margin },
|
||||||
Children = new Drawable[]
|
Children = statisticsLabels
|
||||||
{
|
|
||||||
maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString(), "Max Combo"),
|
|
||||||
accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", Score.Accuracy), "Accuracy"),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -183,17 +187,17 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
Spacing = new Vector2(5f, 0f),
|
Spacing = new Vector2(5f, 0f),
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
scoreLabel = new GlowingSpriteText(Score.TotalScore.ToString(@"N0"), @"Venera", 23, Color4.White, OsuColour.FromHex(@"83ccfa")),
|
scoreLabel = new GlowingSpriteText(score.TotalScore.ToString(@"N0"), @"Venera", 23, Color4.White, OsuColour.FromHex(@"83ccfa")),
|
||||||
new Container
|
RankContainer = new Container
|
||||||
{
|
{
|
||||||
Size = new Vector2(40f, 20f),
|
Size = new Vector2(40f, 20f),
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
scoreRank = new DrawableRank(Score.Rank)
|
scoreRank = new DrawableRank(score.Rank)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Size = new Vector2(40f),
|
Size = new Vector2(40f)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -205,7 +209,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
Origin = Anchor.BottomRight,
|
Origin = Anchor.BottomRight,
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Direction = FillDirection.Horizontal,
|
Direction = FillDirection.Horizontal,
|
||||||
ChildrenEnumerable = Score.Mods.Select(mod => new ModIcon(mod) { Scale = new Vector2(0.375f) })
|
ChildrenEnumerable = score.Mods.Select(mod => new ModIcon(mod) { Scale = new Vector2(0.375f) })
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -216,7 +220,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
public override void Show()
|
public override void Show()
|
||||||
{
|
{
|
||||||
foreach (var d in new[] { avatar, nameLabel, scoreLabel, scoreRank, flagBadgeContainer, maxCombo, accuracy, modsContainer })
|
foreach (var d in new[] { avatar, nameLabel, scoreLabel, scoreRank, flagBadgeContainer, modsContainer }.Concat(statisticsLabels))
|
||||||
d.FadeOut();
|
d.FadeOut();
|
||||||
|
|
||||||
Alpha = 0;
|
Alpha = 0;
|
||||||
@ -243,7 +247,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
using (BeginDelayedSequence(50, true))
|
using (BeginDelayedSequence(50, true))
|
||||||
{
|
{
|
||||||
var drawables = new Drawable[] { flagBadgeContainer, maxCombo, accuracy, modsContainer, };
|
var drawables = new Drawable[] { flagBadgeContainer, modsContainer }.Concat(statisticsLabels).ToArray();
|
||||||
for (int i = 0; i < drawables.Length; i++)
|
for (int i = 0; i < drawables.Length; i++)
|
||||||
drawables[i].FadeIn(100 + i * 50);
|
drawables[i].FadeIn(100 + i * 50);
|
||||||
}
|
}
|
||||||
@ -251,6 +255,12 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual IEnumerable<LeaderboardScoreStatistic> GetStatistics(ScoreInfo model) => new[]
|
||||||
|
{
|
||||||
|
new LeaderboardScoreStatistic(FontAwesome.fa_link, "Max Combo", model.MaxCombo.ToString()),
|
||||||
|
new LeaderboardScoreStatistic(FontAwesome.fa_crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy))
|
||||||
|
};
|
||||||
|
|
||||||
protected override bool OnHover(HoverEvent e)
|
protected override bool OnHover(HoverEvent e)
|
||||||
{
|
{
|
||||||
background.FadeTo(0.5f, 300, Easing.OutQuint);
|
background.FadeTo(0.5f, 300, Easing.OutQuint);
|
||||||
@ -321,11 +331,10 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
public string TooltipText => name;
|
public string TooltipText => name;
|
||||||
|
|
||||||
public ScoreComponentLabel(FontAwesome icon, string value, string name)
|
public ScoreComponentLabel(LeaderboardScoreStatistic statistic)
|
||||||
{
|
{
|
||||||
this.name = name;
|
name = statistic.Name;
|
||||||
AutoSizeAxes = Axes.Y;
|
AutoSizeAxes = Axes.Both;
|
||||||
Width = 60;
|
|
||||||
|
|
||||||
Child = content = new FillFlowContainer
|
Child = content = new FillFlowContainer
|
||||||
{
|
{
|
||||||
@ -356,11 +365,11 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Size = new Vector2(icon_size - 6),
|
Size = new Vector2(icon_size - 6),
|
||||||
Colour = OsuColour.FromHex(@"a4edff"),
|
Colour = OsuColour.FromHex(@"a4edff"),
|
||||||
Icon = icon,
|
Icon = statistic.Icon,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa"))
|
new GlowingSpriteText(statistic.Value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa"))
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
@ -369,5 +378,19 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class LeaderboardScoreStatistic
|
||||||
|
{
|
||||||
|
public FontAwesome Icon;
|
||||||
|
public string Value;
|
||||||
|
public string Name;
|
||||||
|
|
||||||
|
public LeaderboardScoreStatistic(FontAwesome icon, string name, string value)
|
||||||
|
{
|
||||||
|
Icon = icon;
|
||||||
|
Name = name;
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,7 +4,7 @@
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Online.Leaderboards
|
||||||
{
|
{
|
||||||
public class MessagePlaceholder : Placeholder
|
public class MessagePlaceholder : Placeholder
|
||||||
{
|
{
|
@ -5,7 +5,7 @@ using System;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Online.Leaderboards
|
||||||
{
|
{
|
||||||
public abstract class Placeholder : OsuTextFlowContainer, IEquatable<Placeholder>
|
public abstract class Placeholder : OsuTextFlowContainer, IEquatable<Placeholder>
|
||||||
{
|
{
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Online.Leaderboards
|
||||||
{
|
{
|
||||||
public enum PlaceholderState
|
public enum PlaceholderState
|
||||||
{
|
{
|
@ -8,7 +8,7 @@ using osu.Game.Graphics;
|
|||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Online.Leaderboards
|
||||||
{
|
{
|
||||||
public class RetrievalFailurePlaceholder : Placeholder
|
public class RetrievalFailurePlaceholder : Placeholder
|
||||||
{
|
{
|
@ -9,7 +9,6 @@ using osu.Game.Graphics.Sprites;
|
|||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
|
|
||||||
@ -20,7 +19,6 @@ namespace osu.Game.Overlays.BeatmapSet
|
|||||||
private const float height = 50;
|
private const float height = 50;
|
||||||
|
|
||||||
private readonly UpdateableAvatar avatar;
|
private readonly UpdateableAvatar avatar;
|
||||||
private readonly ClickableArea clickableArea;
|
|
||||||
private readonly FillFlowContainer fields;
|
private readonly FillFlowContainer fields;
|
||||||
|
|
||||||
private BeatmapSetInfo beatmapSet;
|
private BeatmapSetInfo beatmapSet;
|
||||||
@ -73,7 +71,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
|||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
clickableArea = new ClickableArea
|
new Container
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
CornerRadius = 3,
|
CornerRadius = 3,
|
||||||
@ -100,14 +98,8 @@ namespace osu.Game.Overlays.BeatmapSet
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
private void load()
|
||||||
private void load(UserProfileOverlay profile)
|
|
||||||
{
|
{
|
||||||
clickableArea.Action = () =>
|
|
||||||
{
|
|
||||||
if (avatar.User != null) profile?.ShowUser(avatar.User);
|
|
||||||
};
|
|
||||||
|
|
||||||
updateDisplay();
|
updateDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,11 +10,11 @@ using osu.Framework.Input.Events;
|
|||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Online.Leaderboards;
|
||||||
using osu.Game.Overlays.Profile.Sections.Ranks;
|
using osu.Game.Overlays.Profile.Sections.Ranks;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Screens.Select.Leaderboards;
|
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapSet.Scores
|
namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||||
|
@ -12,12 +12,12 @@ using osu.Framework.Input.Events;
|
|||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Online.Leaderboards;
|
||||||
using osu.Game.Overlays.Profile.Sections.Ranks;
|
using osu.Game.Overlays.Profile.Sections.Ranks;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Select.Leaderboards;
|
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapSet.Scores
|
namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||||
|
@ -1,72 +1,38 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osuTK;
|
|
||||||
using osuTK.Graphics;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Cursor;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Online.Chat;
|
using osu.Game.Online.Chat;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osuTK;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osuTK.Graphics;
|
||||||
using osu.Game.Graphics.UserInterface;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Chat
|
namespace osu.Game.Overlays.Chat
|
||||||
{
|
{
|
||||||
public class ChatLine : Container
|
public class ChatLine : CompositeDrawable
|
||||||
{
|
{
|
||||||
private static readonly Color4[] username_colours =
|
public const float LEFT_PADDING = default_message_padding + default_horizontal_padding * 2;
|
||||||
{
|
|
||||||
OsuColour.FromHex("588c7e"),
|
|
||||||
OsuColour.FromHex("b2a367"),
|
|
||||||
OsuColour.FromHex("c98f65"),
|
|
||||||
OsuColour.FromHex("bc5151"),
|
|
||||||
OsuColour.FromHex("5c8bd6"),
|
|
||||||
OsuColour.FromHex("7f6ab7"),
|
|
||||||
OsuColour.FromHex("a368ad"),
|
|
||||||
OsuColour.FromHex("aa6880"),
|
|
||||||
|
|
||||||
OsuColour.FromHex("6fad9b"),
|
private const float default_message_padding = 200;
|
||||||
OsuColour.FromHex("f2e394"),
|
|
||||||
OsuColour.FromHex("f2ae72"),
|
|
||||||
OsuColour.FromHex("f98f8a"),
|
|
||||||
OsuColour.FromHex("7daef4"),
|
|
||||||
OsuColour.FromHex("a691f2"),
|
|
||||||
OsuColour.FromHex("c894d3"),
|
|
||||||
OsuColour.FromHex("d895b0"),
|
|
||||||
|
|
||||||
OsuColour.FromHex("53c4a1"),
|
protected virtual float MessagePadding => default_message_padding;
|
||||||
OsuColour.FromHex("eace5c"),
|
|
||||||
OsuColour.FromHex("ea8c47"),
|
|
||||||
OsuColour.FromHex("fc4f4f"),
|
|
||||||
OsuColour.FromHex("3d94ea"),
|
|
||||||
OsuColour.FromHex("7760ea"),
|
|
||||||
OsuColour.FromHex("af52c6"),
|
|
||||||
OsuColour.FromHex("e25696"),
|
|
||||||
|
|
||||||
OsuColour.FromHex("677c66"),
|
private const float default_horizontal_padding = 15;
|
||||||
OsuColour.FromHex("9b8732"),
|
|
||||||
OsuColour.FromHex("8c5129"),
|
|
||||||
OsuColour.FromHex("8c3030"),
|
|
||||||
OsuColour.FromHex("1f5d91"),
|
|
||||||
OsuColour.FromHex("4335a5"),
|
|
||||||
OsuColour.FromHex("812a96"),
|
|
||||||
OsuColour.FromHex("992861"),
|
|
||||||
};
|
|
||||||
|
|
||||||
public const float LEFT_PADDING = message_padding + padding * 2;
|
protected virtual float HorizontalPadding => default_horizontal_padding;
|
||||||
|
|
||||||
private const float padding = 15;
|
protected virtual float TextSize => 20;
|
||||||
private const float message_padding = 200;
|
|
||||||
private const float action_padding = 3;
|
|
||||||
private const float text_size = 20;
|
|
||||||
|
|
||||||
private Color4 customUsernameColour;
|
private Color4 customUsernameColour;
|
||||||
|
|
||||||
@ -75,14 +41,13 @@ namespace osu.Game.Overlays.Chat
|
|||||||
public ChatLine(Message message)
|
public ChatLine(Message message)
|
||||||
{
|
{
|
||||||
Message = message;
|
Message = message;
|
||||||
|
Padding = new MarginPadding { Left = HorizontalPadding, Right = HorizontalPadding };
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
AutoSizeAxes = Axes.Y;
|
AutoSizeAxes = Axes.Y;
|
||||||
|
|
||||||
Padding = new MarginPadding { Left = padding, Right = padding };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ChannelManager chatManager;
|
[Resolved(CanBeNull = true)]
|
||||||
|
private ChannelManager chatManager { get; set; }
|
||||||
|
|
||||||
private Message message;
|
private Message message;
|
||||||
private OsuSpriteText username;
|
private OsuSpriteText username;
|
||||||
@ -106,10 +71,9 @@ namespace osu.Game.Overlays.Chat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours, ChannelManager chatManager)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
this.chatManager = chatManager;
|
|
||||||
customUsernameColour = colours.ChatBlue;
|
customUsernameColour = colours.ChatBlue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +89,7 @@ namespace osu.Game.Overlays.Chat
|
|||||||
{
|
{
|
||||||
Font = @"Exo2.0-BoldItalic",
|
Font = @"Exo2.0-BoldItalic",
|
||||||
Colour = hasBackground ? customUsernameColour : username_colours[message.Sender.Id % username_colours.Length],
|
Colour = hasBackground ? customUsernameColour : username_colours[message.Sender.Id % username_colours.Length],
|
||||||
TextSize = text_size,
|
TextSize = TextSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (hasBackground)
|
if (hasBackground)
|
||||||
@ -163,11 +127,11 @@ namespace osu.Game.Overlays.Chat
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Children = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
Size = new Vector2(message_padding, text_size),
|
Size = new Vector2(MessagePadding, TextSize),
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
timestamp = new OsuSpriteText
|
timestamp = new OsuSpriteText
|
||||||
@ -176,7 +140,7 @@ namespace osu.Game.Overlays.Chat
|
|||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
Font = @"Exo2.0-SemiBold",
|
Font = @"Exo2.0-SemiBold",
|
||||||
FixedWidth = true,
|
FixedWidth = true,
|
||||||
TextSize = text_size * 0.75f,
|
TextSize = TextSize * 0.75f,
|
||||||
},
|
},
|
||||||
new MessageSender(message.Sender)
|
new MessageSender(message.Sender)
|
||||||
{
|
{
|
||||||
@ -191,7 +155,7 @@ namespace osu.Game.Overlays.Chat
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Padding = new MarginPadding { Left = message_padding + padding },
|
Padding = new MarginPadding { Left = MessagePadding + HorizontalPadding },
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
contentFlow = new LinkFlowContainer(t =>
|
contentFlow = new LinkFlowContainer(t =>
|
||||||
@ -204,7 +168,7 @@ namespace osu.Game.Overlays.Chat
|
|||||||
t.Colour = OsuColour.FromHex(message.Sender.Colour);
|
t.Colour = OsuColour.FromHex(message.Sender.Colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
t.TextSize = text_size;
|
t.TextSize = TextSize;
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
@ -257,5 +221,44 @@ namespace osu.Game.Overlays.Chat
|
|||||||
new OsuMenuItem("Start Chat", MenuItemType.Standard, startChatAction),
|
new OsuMenuItem("Start Chat", MenuItemType.Standard, startChatAction),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly Color4[] username_colours =
|
||||||
|
{
|
||||||
|
OsuColour.FromHex("588c7e"),
|
||||||
|
OsuColour.FromHex("b2a367"),
|
||||||
|
OsuColour.FromHex("c98f65"),
|
||||||
|
OsuColour.FromHex("bc5151"),
|
||||||
|
OsuColour.FromHex("5c8bd6"),
|
||||||
|
OsuColour.FromHex("7f6ab7"),
|
||||||
|
OsuColour.FromHex("a368ad"),
|
||||||
|
OsuColour.FromHex("aa6880"),
|
||||||
|
|
||||||
|
OsuColour.FromHex("6fad9b"),
|
||||||
|
OsuColour.FromHex("f2e394"),
|
||||||
|
OsuColour.FromHex("f2ae72"),
|
||||||
|
OsuColour.FromHex("f98f8a"),
|
||||||
|
OsuColour.FromHex("7daef4"),
|
||||||
|
OsuColour.FromHex("a691f2"),
|
||||||
|
OsuColour.FromHex("c894d3"),
|
||||||
|
OsuColour.FromHex("d895b0"),
|
||||||
|
|
||||||
|
OsuColour.FromHex("53c4a1"),
|
||||||
|
OsuColour.FromHex("eace5c"),
|
||||||
|
OsuColour.FromHex("ea8c47"),
|
||||||
|
OsuColour.FromHex("fc4f4f"),
|
||||||
|
OsuColour.FromHex("3d94ea"),
|
||||||
|
OsuColour.FromHex("7760ea"),
|
||||||
|
OsuColour.FromHex("af52c6"),
|
||||||
|
OsuColour.FromHex("e25696"),
|
||||||
|
|
||||||
|
OsuColour.FromHex("677c66"),
|
||||||
|
OsuColour.FromHex("9b8732"),
|
||||||
|
OsuColour.FromHex("8c5129"),
|
||||||
|
OsuColour.FromHex("8c3030"),
|
||||||
|
OsuColour.FromHex("1f5d91"),
|
||||||
|
OsuColour.FromHex("4335a5"),
|
||||||
|
OsuColour.FromHex("812a96"),
|
||||||
|
OsuColour.FromHex("992861"),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Chat
|
|||||||
public class DrawableChannel : Container
|
public class DrawableChannel : Container
|
||||||
{
|
{
|
||||||
public readonly Channel Channel;
|
public readonly Channel Channel;
|
||||||
private readonly ChatLineContainer flow;
|
protected readonly ChatLineContainer ChatLineFlow;
|
||||||
private readonly ScrollContainer scroll;
|
private readonly ScrollContainer scroll;
|
||||||
|
|
||||||
public DrawableChannel(Channel channel)
|
public DrawableChannel(Channel channel)
|
||||||
@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Chat
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Child = flow = new ChatLineContainer
|
Child = ChatLineFlow = new ChatLineContainer
|
||||||
{
|
{
|
||||||
Padding = new MarginPadding { Left = 20, Right = 20 },
|
Padding = new MarginPadding { Left = 20, Right = 20 },
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
@ -72,17 +72,19 @@ namespace osu.Game.Overlays.Chat
|
|||||||
Channel.PendingMessageResolved -= pendingMessageResolved;
|
Channel.PendingMessageResolved -= pendingMessageResolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual ChatLine CreateChatLine(Message m) => new ChatLine(m);
|
||||||
|
|
||||||
private void newMessagesArrived(IEnumerable<Message> newMessages)
|
private void newMessagesArrived(IEnumerable<Message> newMessages)
|
||||||
{
|
{
|
||||||
// Add up to last Channel.MAX_HISTORY messages
|
// Add up to last Channel.MAX_HISTORY messages
|
||||||
var displayMessages = newMessages.Skip(Math.Max(0, newMessages.Count() - Channel.MaxHistory));
|
var displayMessages = newMessages.Skip(Math.Max(0, newMessages.Count() - Channel.MaxHistory));
|
||||||
|
|
||||||
flow.AddRange(displayMessages.Select(m => new ChatLine(m)));
|
ChatLineFlow.AddRange(displayMessages.Select(CreateChatLine));
|
||||||
|
|
||||||
if (scroll.IsScrolledToEnd(10) || !flow.Children.Any() || newMessages.Any(m => m is LocalMessage))
|
if (scroll.IsScrolledToEnd(10) || !ChatLineFlow.Children.Any() || newMessages.Any(m => m is LocalMessage))
|
||||||
scrollToEnd();
|
scrollToEnd();
|
||||||
|
|
||||||
var staleMessages = flow.Children.Where(c => c.LifetimeEnd == double.MaxValue).ToArray();
|
var staleMessages = ChatLineFlow.Children.Where(c => c.LifetimeEnd == double.MaxValue).ToArray();
|
||||||
int count = staleMessages.Length - Channel.MaxHistory;
|
int count = staleMessages.Length - Channel.MaxHistory;
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
@ -96,25 +98,25 @@ namespace osu.Game.Overlays.Chat
|
|||||||
|
|
||||||
private void pendingMessageResolved(Message existing, Message updated)
|
private void pendingMessageResolved(Message existing, Message updated)
|
||||||
{
|
{
|
||||||
var found = flow.Children.LastOrDefault(c => c.Message == existing);
|
var found = ChatLineFlow.Children.LastOrDefault(c => c.Message == existing);
|
||||||
if (found != null)
|
if (found != null)
|
||||||
{
|
{
|
||||||
Trace.Assert(updated.Id.HasValue, "An updated message was returned with no ID.");
|
Trace.Assert(updated.Id.HasValue, "An updated message was returned with no ID.");
|
||||||
|
|
||||||
flow.Remove(found);
|
ChatLineFlow.Remove(found);
|
||||||
found.Message = updated;
|
found.Message = updated;
|
||||||
flow.Add(found);
|
ChatLineFlow.Add(found);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void messageRemoved(Message removed)
|
private void messageRemoved(Message removed)
|
||||||
{
|
{
|
||||||
flow.Children.FirstOrDefault(c => c.Message == removed)?.FadeColour(Color4.Red, 400).FadeOut(600).Expire();
|
ChatLineFlow.Children.FirstOrDefault(c => c.Message == removed)?.FadeColour(Color4.Red, 400).FadeOut(600).Expire();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scrollToEnd() => ScheduleAfterChildren(() => scroll.ScrollToEnd());
|
private void scrollToEnd() => ScheduleAfterChildren(() => scroll.ScrollToEnd());
|
||||||
|
|
||||||
private class ChatLineContainer : FillFlowContainer<ChatLine>
|
protected class ChatLineContainer : FillFlowContainer<ChatLine>
|
||||||
{
|
{
|
||||||
protected override int Compare(Drawable x, Drawable y)
|
protected override int Compare(Drawable x, Drawable y)
|
||||||
{
|
{
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
@ -19,6 +20,7 @@ using osu.Game.Online.Chat;
|
|||||||
using osu.Game.Overlays.Chat;
|
using osu.Game.Overlays.Chat;
|
||||||
using osu.Game.Overlays.Chat.Selection;
|
using osu.Game.Overlays.Chat.Selection;
|
||||||
using osu.Game.Overlays.Chat.Tabs;
|
using osu.Game.Overlays.Chat.Tabs;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Overlays
|
namespace osu.Game.Overlays
|
||||||
{
|
{
|
||||||
@ -222,7 +224,7 @@ namespace osu.Game.Overlays
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
currentChannelContainer.Clear(false);
|
currentChannelContainer.Clear(false);
|
||||||
Scheduler.Add(() => currentChannelContainer.Add(loaded));
|
currentChannelContainer.Add(loaded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,6 +264,39 @@ namespace osu.Game.Overlays
|
|||||||
return base.OnDragEnd(e);
|
return base.OnDragEnd(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void selectTab(int index)
|
||||||
|
{
|
||||||
|
var channel = channelTabControl.Items.Skip(index).FirstOrDefault();
|
||||||
|
if (channel != null && channel.Name != "+")
|
||||||
|
channelTabControl.Current.Value = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnKeyDown(KeyDownEvent e)
|
||||||
|
{
|
||||||
|
if (e.AltPressed)
|
||||||
|
{
|
||||||
|
switch (e.Key)
|
||||||
|
{
|
||||||
|
case Key.Number1:
|
||||||
|
case Key.Number2:
|
||||||
|
case Key.Number3:
|
||||||
|
case Key.Number4:
|
||||||
|
case Key.Number5:
|
||||||
|
case Key.Number6:
|
||||||
|
case Key.Number7:
|
||||||
|
case Key.Number8:
|
||||||
|
case Key.Number9:
|
||||||
|
selectTab((int)e.Key - (int)Key.Number1);
|
||||||
|
return true;
|
||||||
|
case Key.Number0:
|
||||||
|
selectTab(9);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.OnKeyDown(e);
|
||||||
|
}
|
||||||
|
|
||||||
public override bool AcceptsFocus => true;
|
public override bool AcceptsFocus => true;
|
||||||
|
|
||||||
protected override void OnFocus(FocusEvent e)
|
protected override void OnFocus(FocusEvent e)
|
||||||
|
@ -82,6 +82,7 @@ namespace osu.Game.Overlays.Profile
|
|||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
Masking = true,
|
Masking = true,
|
||||||
CornerRadius = 5,
|
CornerRadius = 5,
|
||||||
|
OpenOnClick = { Value = false },
|
||||||
EdgeEffect = new EdgeEffectParameters
|
EdgeEffect = new EdgeEffectParameters
|
||||||
{
|
{
|
||||||
Type = EdgeEffectType.Shadow,
|
Type = EdgeEffectType.Shadow,
|
||||||
@ -114,7 +115,7 @@ namespace osu.Game.Overlays.Profile
|
|||||||
Y = -48,
|
Y = -48,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new OsuSpriteText
|
usernameText = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = user.Username,
|
Text = user.Username,
|
||||||
Font = @"Exo2.0-RegularItalic",
|
Font = @"Exo2.0-RegularItalic",
|
||||||
@ -316,6 +317,8 @@ namespace osu.Game.Overlays.Profile
|
|||||||
levelBadge.Texture = textures.Get(@"Profile/levelbadge");
|
levelBadge.Texture = textures.Get(@"Profile/levelbadge");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly OsuSpriteText usernameText;
|
||||||
|
|
||||||
private User user;
|
private User user;
|
||||||
|
|
||||||
public User User
|
public User User
|
||||||
@ -343,6 +346,8 @@ namespace osu.Game.Overlays.Profile
|
|||||||
if (user.IsSupporter)
|
if (user.IsSupporter)
|
||||||
SupporterTag.Show();
|
SupporterTag.Show();
|
||||||
|
|
||||||
|
usernameText.Text = user.Username;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(user.Colour))
|
if (!string.IsNullOrEmpty(user.Colour))
|
||||||
{
|
{
|
||||||
colourBar.Colour = OsuColour.FromHex(user.Colour);
|
colourBar.Colour = OsuColour.FromHex(user.Colour);
|
||||||
|
@ -6,8 +6,8 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Online.Leaderboards;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Screens.Select.Leaderboards;
|
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Online.API;
|
|||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Online.Chat;
|
using osu.Game.Online.Chat;
|
||||||
using osu.Game.Screens.Select.Leaderboards;
|
using osu.Game.Online.Leaderboards;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Profile.Sections.Recent
|
namespace osu.Game.Overlays.Profile.Sections.Recent
|
||||||
{
|
{
|
||||||
|
@ -31,6 +31,7 @@ namespace osu.Game.Overlays.Toolbar
|
|||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
CornerRadius = 4,
|
CornerRadius = 4,
|
||||||
|
OpenOnClick = { Value = false },
|
||||||
EdgeEffect = new EdgeEffectParameters
|
EdgeEffect = new EdgeEffectParameters
|
||||||
{
|
{
|
||||||
Type = EdgeEffectType.Shadow,
|
Type = EdgeEffectType.Shadow,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
@ -18,7 +19,20 @@ namespace osu.Game.Overlays.Volume
|
|||||||
{
|
{
|
||||||
public class MuteButton : Container, IHasCurrentValue<bool>
|
public class MuteButton : Container, IHasCurrentValue<bool>
|
||||||
{
|
{
|
||||||
public Bindable<bool> Current { get; } = new Bindable<bool>();
|
private readonly Bindable<bool> current = new Bindable<bool>();
|
||||||
|
|
||||||
|
public Bindable<bool> Current
|
||||||
|
{
|
||||||
|
get => current;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
|
||||||
|
current.UnbindBindings();
|
||||||
|
current.BindTo(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Color4 hoveredColour, unhoveredColour;
|
private Color4 hoveredColour, unhoveredColour;
|
||||||
private const float width = 100;
|
private const float width = 100;
|
||||||
|
@ -68,6 +68,11 @@ namespace osu.Game.Rulesets.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Playfield Playfield => playfield.Value;
|
public Playfield Playfield => playfield.Value;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Place to put drawables above hit objects but below UI.
|
||||||
|
/// </summary>
|
||||||
|
public Container Overlays { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The cursor provided by this <see cref="RulesetContainer"/>. May be null if no cursor is provided.
|
/// The cursor provided by this <see cref="RulesetContainer"/>. May be null if no cursor is provided.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -215,7 +220,6 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
protected override Container<Drawable> Content => content;
|
protected override Container<Drawable> Content => content;
|
||||||
private Container content;
|
private Container content;
|
||||||
private IEnumerable<Mod> mods;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether to assume the beatmap passed into this <see cref="RulesetContainer{TObject}"/> is for the current ruleset.
|
/// Whether to assume the beatmap passed into this <see cref="RulesetContainer{TObject}"/> is for the current ruleset.
|
||||||
@ -245,17 +249,24 @@ namespace osu.Game.Rulesets.UI
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config)
|
private void load(OsuConfigManager config)
|
||||||
{
|
{
|
||||||
KeyBindingInputManager.Add(content = new Container
|
KeyBindingInputManager.Children = new Drawable[]
|
||||||
|
{
|
||||||
|
content = new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
});
|
},
|
||||||
|
Playfield
|
||||||
AddInternal(KeyBindingInputManager);
|
};
|
||||||
KeyBindingInputManager.Add(Playfield);
|
|
||||||
|
|
||||||
if (Cursor != null)
|
if (Cursor != null)
|
||||||
KeyBindingInputManager.Add(Cursor);
|
KeyBindingInputManager.Add(Cursor);
|
||||||
|
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
KeyBindingInputManager,
|
||||||
|
Overlays = new Container { RelativeSizeAxes = Axes.Both }
|
||||||
|
};
|
||||||
|
|
||||||
// Apply mods
|
// Apply mods
|
||||||
applyRulesetMods(Mods, config);
|
applyRulesetMods(Mods, config);
|
||||||
|
|
||||||
@ -330,7 +341,6 @@ namespace osu.Game.Rulesets.UI
|
|||||||
Playfield.Add(drawableObject);
|
Playfield.Add(drawableObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a DrawableHitObject from a HitObject.
|
/// Creates a DrawableHitObject from a HitObject.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -11,7 +13,6 @@ using osu.Game.Rulesets.Mods;
|
|||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play.HUD
|
namespace osu.Game.Screens.Play.HUD
|
||||||
@ -20,9 +21,20 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
{
|
{
|
||||||
private const int fade_duration = 1000;
|
private const int fade_duration = 1000;
|
||||||
|
|
||||||
private readonly Bindable<IEnumerable<Mod>> mods = new Bindable<IEnumerable<Mod>>();
|
private readonly Bindable<IEnumerable<Mod>> current = new Bindable<IEnumerable<Mod>>();
|
||||||
|
|
||||||
public Bindable<IEnumerable<Mod>> Current => mods;
|
public Bindable<IEnumerable<Mod>> Current
|
||||||
|
{
|
||||||
|
get => current;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
|
||||||
|
current.UnbindBindings();
|
||||||
|
current.BindTo(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private readonly FillFlowContainer<ModIcon> iconsContainer;
|
private readonly FillFlowContainer<ModIcon> iconsContainer;
|
||||||
private readonly OsuSpriteText unrankedText;
|
private readonly OsuSpriteText unrankedText;
|
||||||
@ -50,7 +62,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
mods.ValueChanged += mods =>
|
Current.ValueChanged += mods =>
|
||||||
{
|
{
|
||||||
iconsContainer.Clear();
|
iconsContainer.Clear();
|
||||||
foreach (Mod mod in mods)
|
foreach (Mod mod in mods)
|
||||||
@ -66,7 +78,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
mods.UnbindAll();
|
Current.UnbindAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
@ -77,7 +89,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
|
|
||||||
private void appearTransform()
|
private void appearTransform()
|
||||||
{
|
{
|
||||||
if (mods.Value.Any(m => !m.Ranked))
|
if (Current.Value.Any(m => !m.Ranked))
|
||||||
unrankedText.FadeInFromZero(fade_duration, Easing.OutQuint);
|
unrankedText.FadeInFromZero(fade_duration, Easing.OutQuint);
|
||||||
else
|
else
|
||||||
unrankedText.Hide();
|
unrankedText.Hide();
|
||||||
|
@ -28,7 +28,6 @@ using osu.Game.Rulesets.Mods;
|
|||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Ranking;
|
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osu.Game.Storyboards.Drawables;
|
using osu.Game.Storyboards.Drawables;
|
||||||
|
|
||||||
@ -288,7 +287,7 @@ namespace osu.Game.Screens.Play
|
|||||||
if (RulesetContainer.Replay == null)
|
if (RulesetContainer.Replay == null)
|
||||||
scoreManager.Import(score, true);
|
scoreManager.Import(score, true);
|
||||||
|
|
||||||
Push(new Results(score));
|
Push(new SoloResults(score));
|
||||||
|
|
||||||
onCompletionEvent = null;
|
onCompletionEvent = null;
|
||||||
});
|
});
|
||||||
|
24
osu.Game/Screens/Play/SoloResults.cs
Normal file
24
osu.Game/Screens/Play/SoloResults.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
using osu.Game.Screens.Ranking;
|
||||||
|
using osu.Game.Screens.Ranking.Types;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Play
|
||||||
|
{
|
||||||
|
public class SoloResults : Results
|
||||||
|
{
|
||||||
|
public SoloResults(ScoreInfo score)
|
||||||
|
: base(score)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IEnumerable<IResultPageInfo> CreateResultPages() => new IResultPageInfo[]
|
||||||
|
{
|
||||||
|
new ScoreOverviewPageInfo(Score, Beatmap),
|
||||||
|
new BeatmapLeaderboardPageInfo(Score, Beatmap)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,16 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Ranking
|
namespace osu.Game.Screens.Ranking
|
||||||
{
|
{
|
||||||
public enum ResultMode
|
public interface IResultPageInfo
|
||||||
{
|
{
|
||||||
Summary,
|
FontAwesome Icon { get; }
|
||||||
Ranking,
|
|
||||||
Share
|
string Name { get; }
|
||||||
|
|
||||||
|
ResultsPage CreatePage();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,18 +3,19 @@
|
|||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Select.Leaderboards;
|
using osu.Game.Screens.Select.Leaderboards;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Framework.Graphics.Shapes;
|
|
||||||
using osu.Game.Scoring;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Ranking
|
namespace osu.Game.Screens.Ranking.Pages
|
||||||
{
|
{
|
||||||
public class ResultsPageRanking : ResultsPage
|
public class RankingResultsPage : ResultsPage
|
||||||
{
|
{
|
||||||
public ResultsPageRanking(ScoreInfo score, WorkingBeatmap beatmap = null) : base(score, beatmap)
|
public RankingResultsPage(ScoreInfo score, WorkingBeatmap beatmap = null)
|
||||||
|
: base(score, beatmap)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ namespace osu.Game.Screens.Ranking
|
|||||||
Colour = colours.GrayE,
|
Colour = colours.GrayE,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
new Leaderboard
|
new BeatmapLeaderboard
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
@ -4,36 +4,39 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osuTK;
|
|
||||||
using osuTK.Graphics;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Colour;
|
using osu.Framework.Graphics.Colour;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Online.Leaderboards;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Screens.Play;
|
|
||||||
using osu.Game.Screens.Select.Leaderboards;
|
|
||||||
using osu.Game.Users;
|
|
||||||
using osu.Framework.Graphics.Shapes;
|
|
||||||
using osu.Framework.Extensions;
|
|
||||||
using osu.Framework.Localisation;
|
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Ranking
|
namespace osu.Game.Screens.Ranking.Pages
|
||||||
{
|
{
|
||||||
public class ResultsPageScore : ResultsPage
|
public class ScoreResultsPage : ResultsPage
|
||||||
{
|
{
|
||||||
private Container scoreContainer;
|
private Container scoreContainer;
|
||||||
private ScoreCounter scoreCounter;
|
private ScoreCounter scoreCounter;
|
||||||
|
|
||||||
public ResultsPageScore(ScoreInfo score, WorkingBeatmap beatmap) : base(score, beatmap) { }
|
public ScoreResultsPage(ScoreInfo score, WorkingBeatmap beatmap)
|
||||||
|
: base(score, beatmap)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
private FillFlowContainer<DrawableScoreStatistic> statisticsContainer;
|
private FillFlowContainer<DrawableScoreStatistic> statisticsContainer;
|
||||||
|
|
@ -5,6 +5,7 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Cursor;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -13,27 +14,18 @@ using osu.Framework.Graphics.Shapes;
|
|||||||
|
|
||||||
namespace osu.Game.Screens.Ranking
|
namespace osu.Game.Screens.Ranking
|
||||||
{
|
{
|
||||||
public class ResultModeButton : TabItem<ResultMode>
|
public class ResultModeButton : TabItem<IResultPageInfo>, IHasTooltip
|
||||||
{
|
{
|
||||||
private readonly FontAwesome icon;
|
private readonly FontAwesome icon;
|
||||||
private Color4 activeColour;
|
private Color4 activeColour;
|
||||||
private Color4 inactiveColour;
|
private Color4 inactiveColour;
|
||||||
private CircularContainer colouredPart;
|
private CircularContainer colouredPart;
|
||||||
|
|
||||||
public ResultModeButton(ResultMode mode) : base(mode)
|
public ResultModeButton(IResultPageInfo mode)
|
||||||
|
: base(mode)
|
||||||
{
|
{
|
||||||
switch (mode)
|
icon = mode.Icon;
|
||||||
{
|
TooltipText = mode.Name;
|
||||||
case ResultMode.Summary:
|
|
||||||
icon = FontAwesome.fa_asterisk;
|
|
||||||
break;
|
|
||||||
case ResultMode.Ranking:
|
|
||||||
icon = FontAwesome.fa_list;
|
|
||||||
break;
|
|
||||||
case ResultMode.Share:
|
|
||||||
icon = FontAwesome.fa_camera;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -95,5 +87,7 @@ namespace osu.Game.Screens.Ranking
|
|||||||
protected override void OnActivated() => colouredPart.FadeColour(activeColour, 200, Easing.OutQuint);
|
protected override void OnActivated() => colouredPart.FadeColour(activeColour, 200, Easing.OutQuint);
|
||||||
|
|
||||||
protected override void OnDeactivated() => colouredPart.FadeColour(inactiveColour, 200, Easing.OutQuint);
|
protected override void OnDeactivated() => colouredPart.FadeColour(inactiveColour, 200, Easing.OutQuint);
|
||||||
|
|
||||||
|
public string TooltipText { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ using osuTK;
|
|||||||
|
|
||||||
namespace osu.Game.Screens.Ranking
|
namespace osu.Game.Screens.Ranking
|
||||||
{
|
{
|
||||||
public class ResultModeTabControl : TabControl<ResultMode>
|
public class ResultModeTabControl : TabControl<IResultPageInfo>
|
||||||
{
|
{
|
||||||
public ResultModeTabControl()
|
public ResultModeTabControl()
|
||||||
{
|
{
|
||||||
@ -19,9 +19,9 @@ namespace osu.Game.Screens.Ranking
|
|||||||
TabContainer.Padding = new MarginPadding(5);
|
TabContainer.Padding = new MarginPadding(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Dropdown<ResultMode> CreateDropdown() => null;
|
protected override Dropdown<IResultPageInfo> CreateDropdown() => null;
|
||||||
|
|
||||||
protected override TabItem<ResultMode> CreateTabItem(ResultMode value) => new ResultModeButton(value)
|
protected override TabItem<IResultPageInfo> CreateTabItem(IResultPageInfo value) => new ResultModeButton(value)
|
||||||
{
|
{
|
||||||
Anchor = TabContainer.Anchor,
|
Anchor = TabContainer.Anchor,
|
||||||
Origin = TabContainer.Origin
|
Origin = TabContainer.Origin
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
@ -21,9 +22,8 @@ using osu.Game.Scoring;
|
|||||||
|
|
||||||
namespace osu.Game.Screens.Ranking
|
namespace osu.Game.Screens.Ranking
|
||||||
{
|
{
|
||||||
public class Results : OsuScreen
|
public abstract class Results : OsuScreen
|
||||||
{
|
{
|
||||||
private readonly ScoreInfo score;
|
|
||||||
private Container circleOuterBackground;
|
private Container circleOuterBackground;
|
||||||
private Container circleOuter;
|
private Container circleOuter;
|
||||||
private Container circleInner;
|
private Container circleInner;
|
||||||
@ -34,6 +34,8 @@ namespace osu.Game.Screens.Ranking
|
|||||||
|
|
||||||
public override bool AllowBeatmapRulesetChange => false;
|
public override bool AllowBeatmapRulesetChange => false;
|
||||||
|
|
||||||
|
protected readonly ScoreInfo Score;
|
||||||
|
|
||||||
private Container currentPage;
|
private Container currentPage;
|
||||||
|
|
||||||
private static readonly Vector2 background_blur = new Vector2(20);
|
private static readonly Vector2 background_blur = new Vector2(20);
|
||||||
@ -44,9 +46,9 @@ namespace osu.Game.Screens.Ranking
|
|||||||
|
|
||||||
private const float circle_outer_scale = 0.96f;
|
private const float circle_outer_scale = 0.96f;
|
||||||
|
|
||||||
public Results(ScoreInfo score)
|
protected Results(ScoreInfo score)
|
||||||
{
|
{
|
||||||
this.score = score;
|
Score = score;
|
||||||
}
|
}
|
||||||
|
|
||||||
private const float transition_time = 800;
|
private const float transition_time = 800;
|
||||||
@ -67,7 +69,7 @@ namespace osu.Game.Screens.Ranking
|
|||||||
|
|
||||||
backgroundParallax.FadeOut();
|
backgroundParallax.FadeOut();
|
||||||
modeChangeButtons.FadeOut();
|
modeChangeButtons.FadeOut();
|
||||||
currentPage.FadeOut();
|
currentPage?.FadeOut();
|
||||||
|
|
||||||
circleOuterBackground
|
circleOuterBackground
|
||||||
.FadeIn(transition_time, Easing.OutQuint)
|
.FadeIn(transition_time, Easing.OutQuint)
|
||||||
@ -90,7 +92,7 @@ namespace osu.Game.Screens.Ranking
|
|||||||
using (BeginDelayedSequence(transition_time * 0.4f, true))
|
using (BeginDelayedSequence(transition_time * 0.4f, true))
|
||||||
{
|
{
|
||||||
modeChangeButtons.FadeIn(transition_time, Easing.OutQuint);
|
modeChangeButtons.FadeIn(transition_time, Easing.OutQuint);
|
||||||
currentPage.FadeIn(transition_time, Easing.OutQuint);
|
currentPage?.FadeIn(transition_time, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -188,7 +190,7 @@ namespace osu.Game.Screens.Ranking
|
|||||||
},
|
},
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = $"{score.MaxCombo}x",
|
Text = $"{Score.MaxCombo}x",
|
||||||
TextSize = 40,
|
TextSize = 40,
|
||||||
RelativePositionAxes = Axes.X,
|
RelativePositionAxes = Axes.X,
|
||||||
Font = @"Exo2.0-Bold",
|
Font = @"Exo2.0-Bold",
|
||||||
@ -209,7 +211,7 @@ namespace osu.Game.Screens.Ranking
|
|||||||
},
|
},
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = $"{score.Accuracy:P2}",
|
Text = $"{Score.Accuracy:P2}",
|
||||||
TextSize = 40,
|
TextSize = 40,
|
||||||
RelativePositionAxes = Axes.X,
|
RelativePositionAxes = Axes.X,
|
||||||
Font = @"Exo2.0-Bold",
|
Font = @"Exo2.0-Bold",
|
||||||
@ -262,30 +264,22 @@ namespace osu.Game.Screens.Ranking
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
modeChangeButtons.AddItem(ResultMode.Summary);
|
foreach (var t in CreateResultPages())
|
||||||
modeChangeButtons.AddItem(ResultMode.Ranking);
|
modeChangeButtons.AddItem(t);
|
||||||
//modeChangeButtons.AddItem(ResultMode.Share);
|
modeChangeButtons.Current.Value = modeChangeButtons.Items.FirstOrDefault();
|
||||||
|
|
||||||
modeChangeButtons.Current.ValueChanged += mode =>
|
modeChangeButtons.Current.BindValueChanged(m =>
|
||||||
{
|
{
|
||||||
currentPage?.FadeOut();
|
currentPage?.FadeOut();
|
||||||
currentPage?.Expire();
|
currentPage?.Expire();
|
||||||
|
|
||||||
switch (mode)
|
currentPage = m?.CreatePage();
|
||||||
{
|
|
||||||
case ResultMode.Summary:
|
|
||||||
currentPage = new ResultsPageScore(score, Beatmap.Value);
|
|
||||||
break;
|
|
||||||
case ResultMode.Ranking:
|
|
||||||
currentPage = new ResultsPageRanking(score, Beatmap.Value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentPage != null)
|
if (currentPage != null)
|
||||||
circleInner.Add(currentPage);
|
circleInner.Add(currentPage);
|
||||||
};
|
}, true);
|
||||||
|
|
||||||
modeChangeButtons.Current.TriggerChange();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract IEnumerable<IResultPageInfo> CreateResultPages();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ using osuTK.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Screens.Ranking
|
namespace osu.Game.Screens.Ranking
|
||||||
{
|
{
|
||||||
public class ResultsPage : Container
|
public abstract class ResultsPage : Container
|
||||||
{
|
{
|
||||||
protected readonly ScoreInfo Score;
|
protected readonly ScoreInfo Score;
|
||||||
protected readonly WorkingBeatmap Beatmap;
|
protected readonly WorkingBeatmap Beatmap;
|
||||||
@ -23,7 +23,7 @@ namespace osu.Game.Screens.Ranking
|
|||||||
|
|
||||||
protected override Container<Drawable> Content => content;
|
protected override Container<Drawable> Content => content;
|
||||||
|
|
||||||
public ResultsPage(ScoreInfo score, WorkingBeatmap beatmap)
|
protected ResultsPage(ScoreInfo score, WorkingBeatmap beatmap)
|
||||||
{
|
{
|
||||||
Score = score;
|
Score = score;
|
||||||
Beatmap = beatmap;
|
Beatmap = beatmap;
|
||||||
|
28
osu.Game/Screens/Ranking/Types/BeatmapLeaderboardPageInfo.cs
Normal file
28
osu.Game/Screens/Ranking/Types/BeatmapLeaderboardPageInfo.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
using osu.Game.Screens.Ranking.Pages;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Ranking.Types
|
||||||
|
{
|
||||||
|
public class BeatmapLeaderboardPageInfo : IResultPageInfo
|
||||||
|
{
|
||||||
|
private readonly ScoreInfo score;
|
||||||
|
private readonly WorkingBeatmap beatmap;
|
||||||
|
|
||||||
|
public BeatmapLeaderboardPageInfo(ScoreInfo score, WorkingBeatmap beatmap)
|
||||||
|
{
|
||||||
|
this.score = score;
|
||||||
|
this.beatmap = beatmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FontAwesome Icon => FontAwesome.fa_list;
|
||||||
|
|
||||||
|
public string Name => @"Beatmap Leaderboard";
|
||||||
|
|
||||||
|
public ResultsPage CreatePage() => new RankingResultsPage(score, beatmap);
|
||||||
|
}
|
||||||
|
}
|
30
osu.Game/Screens/Ranking/Types/ScoreOverviewPageInfo.cs
Normal file
30
osu.Game/Screens/Ranking/Types/ScoreOverviewPageInfo.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
using osu.Game.Screens.Ranking.Pages;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Ranking.Types
|
||||||
|
{
|
||||||
|
public class ScoreOverviewPageInfo : IResultPageInfo
|
||||||
|
{
|
||||||
|
public FontAwesome Icon => FontAwesome.fa_asterisk;
|
||||||
|
|
||||||
|
public string Name => "Overview";
|
||||||
|
private readonly ScoreInfo score;
|
||||||
|
private readonly WorkingBeatmap beatmap;
|
||||||
|
|
||||||
|
public ScoreOverviewPageInfo(ScoreInfo score, WorkingBeatmap beatmap)
|
||||||
|
{
|
||||||
|
this.score = score;
|
||||||
|
this.beatmap = beatmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultsPage CreatePage()
|
||||||
|
{
|
||||||
|
return new ScoreResultsPage(score, beatmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,7 @@ namespace osu.Game.Screens.Select
|
|||||||
protected override Container<Drawable> Content => content;
|
protected override Container<Drawable> Content => content;
|
||||||
|
|
||||||
public readonly BeatmapDetails Details;
|
public readonly BeatmapDetails Details;
|
||||||
public readonly Leaderboard Leaderboard;
|
public readonly BeatmapLeaderboard Leaderboard;
|
||||||
|
|
||||||
private WorkingBeatmap beatmap;
|
private WorkingBeatmap beatmap;
|
||||||
public WorkingBeatmap Beatmap
|
public WorkingBeatmap Beatmap
|
||||||
@ -52,7 +52,7 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
Details.Hide();
|
Details.Hide();
|
||||||
Leaderboard.Scope = (LeaderboardScope)tab - 1;
|
Leaderboard.Scope = (BeatmapLeaderboardScope)tab - 1;
|
||||||
Leaderboard.Show();
|
Leaderboard.Show();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ namespace osu.Game.Screens.Select
|
|||||||
Alpha = 0,
|
Alpha = 0,
|
||||||
Margin = new MarginPadding { Top = details_padding },
|
Margin = new MarginPadding { Top = details_padding },
|
||||||
},
|
},
|
||||||
Leaderboard = new Leaderboard
|
Leaderboard = new BeatmapLeaderboard
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
}
|
}
|
||||||
|
87
osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
Normal file
87
osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
|
using osu.Game.Online.Leaderboards;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Select.Leaderboards
|
||||||
|
{
|
||||||
|
public class BeatmapLeaderboard : Leaderboard<BeatmapLeaderboardScope, ScoreInfo>
|
||||||
|
{
|
||||||
|
public Action<ScoreInfo> ScoreSelected;
|
||||||
|
|
||||||
|
private BeatmapInfo beatmap;
|
||||||
|
|
||||||
|
public BeatmapInfo Beatmap
|
||||||
|
{
|
||||||
|
get { return beatmap; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (beatmap == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
beatmap = value;
|
||||||
|
Scores = null;
|
||||||
|
|
||||||
|
UpdateScores();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private ScoreManager scoreManager { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IBindable<RulesetInfo> ruleset { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private APIAccess api { get; set; }
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
ruleset.ValueChanged += _ => UpdateScores();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override APIRequest FetchScores(Action<IEnumerable<ScoreInfo>> scoresCallback)
|
||||||
|
{
|
||||||
|
if (Scope == BeatmapLeaderboardScope.Local)
|
||||||
|
{
|
||||||
|
Scores = scoreManager.QueryScores(s => s.Beatmap.ID == Beatmap.ID).ToArray();
|
||||||
|
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Beatmap?.OnlineBeatmapID == null)
|
||||||
|
{
|
||||||
|
PlaceholderState = PlaceholderState.Unavailable;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Scope != BeatmapLeaderboardScope.Global && !api.LocalUser.Value.IsSupporter)
|
||||||
|
{
|
||||||
|
PlaceholderState = PlaceholderState.NotSupporter;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var req = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope);
|
||||||
|
|
||||||
|
req.Success += r => scoresCallback?.Invoke(r.Scores);
|
||||||
|
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override LeaderboardScore CreateDrawableScore(ScoreInfo model, int index) => new LeaderboardScore(model, index)
|
||||||
|
{
|
||||||
|
Action = () => ScoreSelected?.Invoke(model)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Screens.Select.Leaderboards
|
||||||
{
|
{
|
||||||
public enum LeaderboardScope
|
public enum BeatmapLeaderboardScope
|
||||||
{
|
{
|
||||||
Local,
|
Local,
|
||||||
Country,
|
Country,
|
@ -28,7 +28,7 @@ using osu.Game.Rulesets.Mods;
|
|||||||
using osu.Game.Screens.Backgrounds;
|
using osu.Game.Screens.Backgrounds;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
using osu.Game.Screens.Menu;
|
using osu.Game.Screens.Menu;
|
||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Screens.Select.Options;
|
using osu.Game.Screens.Select.Options;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ namespace osu.Game.Screens.Select
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
BeatmapDetails.Leaderboard.ScoreSelected += s => Push(new Results(s));
|
BeatmapDetails.Leaderboard.ScoreSelected += s => Push(new SoloResults(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
|
@ -3,17 +3,29 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Cursor;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
|
||||||
namespace osu.Game.Users
|
namespace osu.Game.Users
|
||||||
{
|
{
|
||||||
public class Avatar : Container
|
public class Avatar : Container
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to open the user's profile when clicked.
|
||||||
|
/// </summary>
|
||||||
|
public readonly BindableBool OpenOnClick = new BindableBool(true);
|
||||||
|
|
||||||
private readonly User user;
|
private readonly User user;
|
||||||
|
|
||||||
|
[Resolved(CanBeNull = true)]
|
||||||
|
private OsuGame game { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An avatar for specified user.
|
/// An avatar for specified user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -33,14 +45,43 @@ namespace osu.Game.Users
|
|||||||
if (user != null && user.Id > 1) texture = textures.Get($@"https://a.ppy.sh/{user.Id}");
|
if (user != null && user.Id > 1) texture = textures.Get($@"https://a.ppy.sh/{user.Id}");
|
||||||
if (texture == null) texture = textures.Get(@"Online/avatar-guest");
|
if (texture == null) texture = textures.Get(@"Online/avatar-guest");
|
||||||
|
|
||||||
Add(new Sprite
|
ClickableArea clickableArea;
|
||||||
|
Add(clickableArea = new ClickableArea
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = new Sprite
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Texture = texture,
|
Texture = texture,
|
||||||
FillMode = FillMode.Fit,
|
FillMode = FillMode.Fit,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre
|
Origin = Anchor.Centre
|
||||||
|
},
|
||||||
|
Action = openProfile
|
||||||
});
|
});
|
||||||
|
|
||||||
|
clickableArea.Enabled.BindTo(OpenOnClick);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openProfile()
|
||||||
|
{
|
||||||
|
if (!OpenOnClick)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (user != null)
|
||||||
|
game?.ShowUser(user.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ClickableArea : OsuClickableContainer, IHasTooltip
|
||||||
|
{
|
||||||
|
public string TooltipText => Enabled.Value ? @"View Profile" : null;
|
||||||
|
|
||||||
|
protected override bool OnClick(ClickEvent e)
|
||||||
|
{
|
||||||
|
if (!Enabled)
|
||||||
|
return false;
|
||||||
|
return base.OnClick(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
|
||||||
@ -35,6 +36,11 @@ namespace osu.Game.Users
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to open the user's profile when clicked.
|
||||||
|
/// </summary>
|
||||||
|
public readonly BindableBool OpenOnClick = new BindableBool(true);
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
@ -45,15 +51,18 @@ namespace osu.Game.Users
|
|||||||
{
|
{
|
||||||
displayedAvatar?.FadeOut(300);
|
displayedAvatar?.FadeOut(300);
|
||||||
displayedAvatar?.Expire();
|
displayedAvatar?.Expire();
|
||||||
|
|
||||||
if (user != null || ShowGuestOnNull)
|
if (user != null || ShowGuestOnNull)
|
||||||
{
|
{
|
||||||
Add(displayedAvatar = new DelayedLoadWrapper(
|
var avatar = new Avatar(user)
|
||||||
new Avatar(user)
|
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
OnLoadComplete = d => d.FadeInFromZero(300, Easing.OutQuint),
|
OnLoadComplete = d => d.FadeInFromZero(300, Easing.OutQuint),
|
||||||
})
|
};
|
||||||
);
|
|
||||||
|
avatar.OpenOnClick.BindTo(OpenOnClick);
|
||||||
|
|
||||||
|
Add(displayedAvatar = new DelayedLoadWrapper(avatar));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,7 @@ namespace osu.Game.Users
|
|||||||
User = user,
|
User = user,
|
||||||
Masking = true,
|
Masking = true,
|
||||||
CornerRadius = 5,
|
CornerRadius = 5,
|
||||||
|
OpenOnClick = { Value = false },
|
||||||
EdgeEffect = new EdgeEffectParameters
|
EdgeEffect = new EdgeEffectParameters
|
||||||
{
|
{
|
||||||
Type = EdgeEffectType.Shadow,
|
Type = EdgeEffectType.Shadow,
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2018.1219.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2018.1221.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
|
Loading…
Reference in New Issue
Block a user