1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-13 15:53:51 +08:00

Merge branch 'master' into slider-stuff

This commit is contained in:
Dean Herbert 2017-04-25 19:42:46 +09:00 committed by GitHub
commit 30e2e7bfe4
17 changed files with 403 additions and 147 deletions

16
.vscode/tasks.json vendored
View File

@ -10,10 +10,16 @@
"showOutput": "silent",
"command": "msbuild",
"args": [
// Ask msbuild to generate full paths for file names.
"/property:GenerateFullPaths=true",
"/property:DebugType=portable"
],
"windows": {
"args": [
"/property:GenerateFullPaths=true",
"/property:DebugType=portable",
"/m" //parallel compiling support. doesn't work well with mono atm
]
},
// Use the standard MS compiler pattern to detect errors, warnings and infos
"problemMatcher": "$msCompile",
"isBuildCommand": true
@ -29,6 +35,14 @@
"/property:DebugType=portable",
"/target:Clean,Build"
],
"windows": {
"args": [
"/property:GenerateFullPaths=true",
"/property:DebugType=portable",
"/target:Clean,Build",
"/m" //parallel compiling support. doesn't work well with mono atm
]
},
// Use the standard MS compiler pattern to detect errors, warnings and infos
"problemMatcher": "$msCompile",
"isBuildCommand": true

View File

@ -1,6 +1,4 @@
# osu! [![Build status](https://ci.appveyor.com/api/projects/status/u2p01nx7l6og8buh?svg=true)](https://ci.appveyor.com/project/peppy/osu)
# osu! [![Build status](https://ci.appveyor.com/api/projects/status/u2p01nx7l6og8buh?svg=true)](https://ci.appveyor.com/project/peppy/osu) [![CodeFactor](https://www.codefactor.io/repository/github/ppy/osu/badge)](https://www.codefactor.io/repository/github/ppy/osu)
[osu! on the web](https://osu.ppy.sh) | [dev chat](https://discord.gg/ppy)
@ -12,14 +10,14 @@ This is still heavily under development and is not intended for end-user use. Th
# Requirements
- A desktop platform which can compile .NET 4.5.
- Visual Studio or MonoDevelop is recommended.
- A desktop platform which can compile .NET 4.5 (tested on macOS, linux and windows). We recommend using [Visual Studio Code](https://code.visualstudio.com/) (all platforms) or [Visual Studio Community Edition](https://www.visualstudio.com/) (windows only), both of which are free.
- Make sure you initialise and keep submodules up-to-date.
# Contributing
We welcome all contributions, but keep in mind that we already have a lot of the UI designed. If you wish to work on something with the intention on having it included in the official distribution, please open an issue for discussion and we will give you what you need from a design perspective to proceed. If you want to make *changes* to the design, we recommend you open an issue with your intentions before spending too much time, to ensure no effort is wasted.
Contributions can be made via pull requests to this repository. We hope to credit and reward larger contributions via a [bounty system](https://goo.gl/nFdoyI). If you're unsure of what you can help with, check out the [list](https://github.com/ppy/osu/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3Abounty) of available issues with bounty.
Contributions can be made via pull requests to this repository. We hope to credit and reward larger contributions via a [bounty system](https://www.bountysource.com/teams/ppy). If you're unsure of what you can help with, check out the [list of open issues](https://github.com/ppy/osu-framework/issues).
Note that while we already have certain standards in place, nothing is set in stone. If you have an issue with the way code is structured; with any libraries we are using; with any processes involved with contributing, *please* bring it up. I welcome all feedback so we can make contributing to this project as pain-free as possible.

View File

@ -0,0 +1,69 @@
// Copyright (c) 2007-2017 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.Containers;
using osu.Game.Database;
using osu.Game.Graphics;
using OpenTK.Graphics;
namespace osu.Game.Beatmaps.Drawables
{
internal class DifficultyColouredContainer : Container, IHasAccentColour
{
public Color4 AccentColour { get; set; }
private readonly BeatmapInfo beatmap;
private OsuColour palette;
public DifficultyColouredContainer(BeatmapInfo beatmap)
{
this.beatmap = beatmap;
}
[BackgroundDependencyLoader]
private void load(OsuColour palette)
{
this.palette = palette;
AccentColour = getColour(beatmap);
}
private enum DifficultyRating
{
Easy,
Normal,
Hard,
Insane,
Expert
}
private DifficultyRating getDifficultyRating(BeatmapInfo beatmap)
{
var rating = beatmap.StarDifficulty;
if (rating < 1.5) return DifficultyRating.Easy;
if (rating < 2.25) return DifficultyRating.Normal;
if (rating < 3.75) return DifficultyRating.Hard;
if (rating < 5.25) return DifficultyRating.Insane;
return DifficultyRating.Expert;
}
private Color4 getColour(BeatmapInfo beatmap)
{
switch (getDifficultyRating(beatmap))
{
case DifficultyRating.Easy:
return palette.Green;
default:
case DifficultyRating.Normal:
return palette.Yellow;
case DifficultyRating.Hard:
return palette.Pink;
case DifficultyRating.Insane:
return palette.Purple;
case DifficultyRating.Expert:
return palette.Gray0;
}
}
}
}

View File

@ -3,7 +3,6 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Database;
using osu.Game.Graphics;
using OpenTK;
@ -11,23 +10,20 @@ using OpenTK.Graphics;
namespace osu.Game.Beatmaps.Drawables
{
internal class DifficultyIcon : Container
internal class DifficultyIcon : DifficultyColouredContainer
{
private readonly BeatmapInfo beatmap;
private OsuColour palette;
public DifficultyIcon(BeatmapInfo beatmap)
public DifficultyIcon(BeatmapInfo beatmap) : base(beatmap)
{
this.beatmap = beatmap;
const float size = 20;
Size = new Vector2(size);
Size = new Vector2(20);
}
[BackgroundDependencyLoader]
private void load(OsuColour palette)
private void load()
{
this.palette = palette;
Children = new[]
{
new TextAwesome
@ -35,7 +31,7 @@ namespace osu.Game.Beatmaps.Drawables
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
TextSize = Size.X,
Colour = getColour(beatmap),
Colour = AccentColour,
Icon = FontAwesome.fa_circle
},
new TextAwesome
@ -48,43 +44,5 @@ namespace osu.Game.Beatmaps.Drawables
}
};
}
private enum DifficultyRating
{
Easy,
Normal,
Hard,
Insane,
Expert
}
private DifficultyRating getDifficultyRating(BeatmapInfo beatmap)
{
var rating = beatmap.StarDifficulty;
if (rating < 1.5) return DifficultyRating.Easy;
if (rating < 2.25) return DifficultyRating.Normal;
if (rating < 3.75) return DifficultyRating.Hard;
if (rating < 5.25) return DifficultyRating.Insane;
return DifficultyRating.Expert;
}
private Color4 getColour(BeatmapInfo beatmap)
{
switch (getDifficultyRating(beatmap))
{
case DifficultyRating.Easy:
return palette.Green;
default:
case DifficultyRating.Normal:
return palette.Yellow;
case DifficultyRating.Hard:
return palette.Pink;
case DifficultyRating.Insane:
return palette.Purple;
case DifficultyRating.Expert:
return palette.Gray0;
}
}
}
}
}

View File

@ -4,6 +4,7 @@
using System;
using osu.Framework.Configuration;
using osu.Framework.Platform;
using osu.Game.Screens.Select;
namespace osu.Game.Configuration
{
@ -34,10 +35,15 @@ namespace osu.Game.Configuration
Set(OsuConfig.MenuParallax, true);
Set(OsuConfig.MenuVoice, true);
Set(OsuConfig.MenuMusic, true);
Set(OsuConfig.BeatmapDetailTab, BeatmapDetailTab.Details);
Set(OsuConfig.ShowInterface, true);
Set(OsuConfig.KeyOverlay, false);
//todo: implement all settings below this line (remove the Disabled set when doing so).
//todo: implement all settings below this line (remove the Disabled set when doing so).
Set(OsuConfig.AudioOffset, 0, -500.0, 500.0);
Set(OsuConfig.MouseSpeed, 1.0).Disabled = true;
@ -145,8 +151,6 @@ namespace osu.Game.Configuration
Set(OsuConfig.YahooIntegration, false).Disabled = true;
Set(OsuConfig.ForceFrameFlush, false).Disabled = true;
Set(OsuConfig.DetectPerformanceIssues, true).Disabled = true;
Set(OsuConfig.MenuMusic, true).Disabled = true;
Set(OsuConfig.MenuVoice, true).Disabled = true;
Set(OsuConfig.RawInput, false).Disabled = true;
Set(OsuConfig.AbsoluteToOsuWindow, Get<bool>(OsuConfig.RawInput)).Disabled = true;
Set(OsuConfig.ShowMenuTips, true).Disabled = true;
@ -176,7 +180,6 @@ namespace osu.Game.Configuration
Set(OsuConfig.ConfineMouse, Get<bool>(OsuConfig.ConfineMouseToFullscreen) ?
ConfineMouseMode.Fullscreen : ConfineMouseMode.Never).Disabled = true;
GetOriginalBindable<bool>(OsuConfig.SavePassword).ValueChanged += delegate
{
if (Get<bool>(OsuConfig.SavePassword)) Set(OsuConfig.SaveUsername, true);
@ -316,6 +319,7 @@ namespace osu.Game.Configuration
MenuMusic,
MenuVoice,
MenuParallax,
BeatmapDetailTab,
RawInput,
AbsoluteToOsuWindow,
ConfineMouse,
@ -340,6 +344,5 @@ namespace osu.Game.Configuration
Ticker,
CompatibilityContext,
CanForceOptimusCompatibility,
}
}

View File

@ -2,6 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using Newtonsoft.Json;
namespace osu.Game.Database
{
@ -18,11 +19,13 @@ namespace osu.Game.Database
/// <summary>
/// Points of failure on a relative time scale (usually 0..100).
/// </summary>
[JsonProperty(@"fail")]
public IEnumerable<int> Fails { get; set; }
/// <summary>
/// Points of retry on a relative time scale (usually 0..100).
/// </summary>
[JsonProperty(@"exit")]
public IEnumerable<int> Retries { get; set; }
}
}

View File

@ -0,0 +1,46 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using Newtonsoft.Json;
using osu.Game.Database;
namespace osu.Game.Online.API.Requests
{
public class GetBeatmapDetailsRequest : APIRequest<GetBeatmapDeatilsResponse>
{
private readonly BeatmapInfo beatmap;
private string lookupString => beatmap.OnlineBeatmapID > 0 ? beatmap.OnlineBeatmapID.ToString() : $@"lookup?checksum={beatmap.Hash}&filename={beatmap.Path}";
public GetBeatmapDetailsRequest(BeatmapInfo beatmap)
{
this.beatmap = beatmap;
}
protected override string Target => $@"beatmaps/{lookupString}";
}
public class GetBeatmapDeatilsResponse : BeatmapMetrics
{
//the online API returns some metrics as a nested object.
[JsonProperty(@"failtimes")]
private BeatmapMetrics failTimes
{
set
{
Fails = value.Fails;
Retries = value.Retries;
}
}
//and other metrics in the beatmap set.
[JsonProperty(@"beatmapset")]
private BeatmapMetrics beatmapSet
{
set
{
Ratings = value.Ratings;
}
}
}
}

View File

@ -294,7 +294,7 @@ namespace osu.Game.Overlays
trackManager.SetExclusive(current.Track);
current.Track.Start();
beatmapSource.Value = current;
}).ContinueWith(task => Schedule(() => task.ThrowIfFaulted()), TaskContinuationOptions.OnlyOnFaulted);
}).ContinueWith(task => Schedule(task.ThrowIfFaulted), TaskContinuationOptions.OnlyOnFaulted);
updateDisplay(current, isNext ? TransformDirection.Next : TransformDirection.Prev);
}

View File

@ -5,8 +5,10 @@ using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Audio.Track;
using osu.Framework.Configuration;
using osu.Framework.Screens;
using osu.Framework.Graphics;
using osu.Game.Configuration;
using osu.Game.Graphics.Containers;
using osu.Game.Screens.Backgrounds;
using OpenTK.Graphics;
@ -56,25 +58,33 @@ namespace osu.Game.Screens.Menu
};
}
private Bindable<bool> menuVoice;
private Bindable<bool> menuMusic;
[BackgroundDependencyLoader]
private void load(AudioManager audio)
private void load(AudioManager audio, OsuConfigManager config)
{
welcome = audio.Sample.Get(@"welcome");
seeya = audio.Sample.Get(@"seeya");
menuVoice = config.GetBindable<bool>(OsuConfig.MenuVoice);
menuMusic = config.GetBindable<bool>(OsuConfig.MenuMusic);
bgm = audio.Track.Get(@"circles");
bgm.Looping = true;
welcome = audio.Sample.Get(@"welcome");
seeya = audio.Sample.Get(@"seeya");
}
protected override void OnEntering(Screen last)
{
base.OnEntering(last);
welcome.Play();
if (menuVoice)
welcome.Play();
Scheduler.AddDelayed(delegate
{
bgm.Start();
if (menuMusic)
bgm.Start();
LoadComponentAsync(mainMenu = new MainMenu());
@ -109,15 +119,17 @@ namespace osu.Game.Screens.Menu
if (!(last is MainMenu))
Content.FadeIn(300);
double fadeOutTime = 2000;
//we also handle the exit transition.
seeya.Play();
if (menuVoice)
seeya.Play();
else
fadeOutTime = 500;
const double fade_out_time = 2000;
Scheduler.AddDelayed(Exit, fade_out_time);
Scheduler.AddDelayed(Exit, fadeOutTime);
//don't want to fade out completely else we will stop running updates and shit will hit the fan.
Game.FadeTo(0.01f, fade_out_time);
Game.FadeTo(0.01f, fadeOutTime);
base.OnResuming(last);
}

View File

@ -2,8 +2,14 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.MathUtils;
using osu.Framework.Screens;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Database;
using osu.Game.Graphics.Containers;
using osu.Game.Screens.Backgrounds;
using osu.Game.Screens.Charts;
@ -15,6 +21,7 @@ using osu.Game.Screens.Select;
using osu.Game.Screens.Tournament;
using osu.Framework.Input;
using OpenTK.Input;
using System.Threading.Tasks;
namespace osu.Game.Screens.Menu
{
@ -54,11 +61,27 @@ namespace osu.Game.Screens.Menu
};
}
private Bindable<bool> menuMusic;
private TrackManager trackManager;
private WorkingBeatmap song;
[BackgroundDependencyLoader]
private void load(OsuGame game)
private void load(OsuGame game, OsuConfigManager config, BeatmapDatabase beatmaps)
{
menuMusic = config.GetBindable<bool>(OsuConfig.MenuMusic);
LoadComponentAsync(background);
if (!menuMusic)
{
trackManager = game.Audio.Track;
int choosableBeatmapsetAmmount = beatmaps.Query<BeatmapSetInfo>().Count();
if (choosableBeatmapsetAmmount > 0)
{
song = beatmaps.GetWorkingBeatmap(beatmaps.GetWithChildren<BeatmapSetInfo>(RNG.Next(1, choosableBeatmapsetAmmount)).Beatmaps[0]);
Beatmap = song;
}
}
buttons.OnSettings = game.ToggleOptions;
preloadSongSelect();
@ -81,6 +104,17 @@ namespace osu.Game.Screens.Menu
{
base.OnEntering(last);
buttons.FadeInFromZero(500);
if (last is Intro && song != null)
{
Task.Run(() =>
{
trackManager.SetExclusive(song.Track);
song.Track.Seek(song.Beatmap.Metadata.PreviewTime);
if (song.Beatmap.Metadata.PreviewTime == -1)
song.Track.Seek(song.Track.Length * 0.4f);
song.Track.Start();
});
}
}
protected override void OnSuspending(Screen next)

View File

@ -38,8 +38,6 @@ namespace osu.Game.Screens.Play
protected override void Update()
{
base.Update();
if (parentClock == null) return;
clock.Rate = parentClock.Rate;

View File

@ -28,7 +28,7 @@ namespace osu.Game.Screens.Select
{
beatmap = value;
Leaderboard.Beatmap = beatmap?.BeatmapInfo;
Details.Beatmap = beatmap?.Beatmap.BeatmapInfo;
Details.Beatmap = beatmap?.BeatmapInfo;
}
}
@ -66,16 +66,16 @@ namespace osu.Game.Screens.Select
{
Details = new BeatmapDetails
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(5),
RelativeSizeAxes = Axes.X,
Masking = true,
Height = 352,
Alpha = 0,
},
Leaderboard = new Leaderboard
{
RelativeSizeAxes = Axes.Both,
}
});
}
}
}
}

View File

@ -4,10 +4,12 @@
using System;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
@ -21,15 +23,22 @@ namespace osu.Game.Screens.Select
public Action<BeatmapDetailTab, bool> OnFilter; //passed the selected tab and if mods is checked
private Bindable<BeatmapDetailTab> selectedTab;
private void invokeOnFilter()
{
OnFilter?.Invoke(tabs.Current, modsCheckbox.Current);
}
[BackgroundDependencyLoader]
private void load(OsuColour colour)
private void load(OsuColour colour, OsuConfigManager config)
{
modsCheckbox.AccentColour = tabs.AccentColour = colour.YellowLight;
selectedTab = config.GetBindable<BeatmapDetailTab>(OsuConfig.BeatmapDetailTab);
tabs.Current.BindTo(selectedTab);
tabs.Current.TriggerChange();
}
public BeatmapDetailAreaTabControl()
@ -62,8 +71,6 @@ namespace osu.Game.Screens.Select
tabs.Current.ValueChanged += item => invokeOnFilter();
modsCheckbox.Current.ValueChanged += item => invokeOnFilter();
tabs.Current.Value = BeatmapDetailTab.Global;
}
}

View File

@ -14,6 +14,9 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using System.Globalization;
using System.Linq;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Framework.Threading;
namespace osu.Game.Screens.Select
{
@ -39,60 +42,108 @@ namespace osu.Game.Screens.Select
private readonly BarGraph retryGraph;
private readonly BarGraph failGraph;
private ScheduledDelegate pendingBeatmapSwitch;
private BeatmapInfo beatmap;
public BeatmapInfo Beatmap
{
get
{
return beatmap;
}
get { return beatmap; }
set
{
beatmap = value;
if (beatmap == null) return;
description.Text = beatmap.Version;
source.Text = beatmap.Metadata.Source;
tags.Text = beatmap.Metadata.Tags;
circleSize.Value = beatmap.Difficulty.CircleSize;
drainRate.Value = beatmap.Difficulty.DrainRate;
overallDifficulty.Value = beatmap.Difficulty.OverallDifficulty;
approachRate.Value = beatmap.Difficulty.ApproachRate;
stars.Value = (float)beatmap.StarDifficulty;
if (beatmap.Metrics?.Ratings.Any() ?? false)
{
var ratings = beatmap.Metrics.Ratings.ToList();
ratingsContainer.Show();
negativeRatings.Text = ratings.GetRange(0, ratings.Count / 2).Sum().ToString();
positiveRatings.Text = ratings.GetRange(ratings.Count / 2, ratings.Count / 2).Sum().ToString();
ratingsBar.Length = (float)ratings.GetRange(0, ratings.Count / 2).Sum() / ratings.Sum();
ratingsGraph.Values = ratings.Select(rating => (float)rating);
}
else
ratingsContainer.Hide();
if ((beatmap.Metrics?.Retries.Any() ?? false) && beatmap.Metrics.Fails.Any())
{
var retries = beatmap.Metrics.Retries;
var fails = beatmap.Metrics.Fails;
retryFailContainer.Show();
float maxValue = fails.Zip(retries, (fail, retry) => fail + retry).Max();
failGraph.MaxValue = maxValue;
retryGraph.MaxValue = maxValue;
failGraph.Values = fails.Select(fail => (float)fail);
retryGraph.Values = retries.Zip(fails, (retry, fail) => retry + MathHelper.Clamp(fail, 0, maxValue));
}
else
retryFailContainer.Hide();
pendingBeatmapSwitch?.Cancel();
pendingBeatmapSwitch = Schedule(updateStats);
}
}
private void updateStats()
{
if (beatmap == null) return;
description.Text = beatmap.Version;
source.Text = beatmap.Metadata.Source;
tags.Text = beatmap.Metadata.Tags;
circleSize.Value = beatmap.Difficulty.CircleSize;
drainRate.Value = beatmap.Difficulty.DrainRate;
overallDifficulty.Value = beatmap.Difficulty.OverallDifficulty;
approachRate.Value = beatmap.Difficulty.ApproachRate;
stars.Value = (float)beatmap.StarDifficulty;
var requestedBeatmap = beatmap;
if (requestedBeatmap.Metrics == null)
{
var lookup = new GetBeatmapDetailsRequest(requestedBeatmap);
lookup.Success += res =>
{
if (beatmap != requestedBeatmap)
//the beatmap has been changed since we started the lookup.
return;
requestedBeatmap.Metrics = res;
Schedule(() => updateMetrics(res));
};
lookup.Failure += e => updateMetrics(null);
api.Queue(lookup);
}
updateMetrics(requestedBeatmap.Metrics, false);
}
/// <summary>
/// Update displayed metrics.
/// </summary>
/// <param name="metrics">New metrics to overwrite the existing display. Can be null.</param>
/// <param name="failOnMissing">Whether to hide the display on null or empty metrics. If false, we will dim as if waiting for further updates.</param>
private void updateMetrics(BeatmapMetrics metrics, bool failOnMissing = true)
{
var hasRatings = metrics?.Ratings.Any() ?? false;
var hasRetriesFails = (metrics?.Retries.Any() ?? false) && metrics.Fails.Any();
if (hasRatings)
{
var ratings = metrics.Ratings.ToList();
ratingsContainer.Show();
negativeRatings.Text = ratings.GetRange(0, ratings.Count / 2).Sum().ToString();
positiveRatings.Text = ratings.GetRange(ratings.Count / 2, ratings.Count / 2).Sum().ToString();
ratingsBar.Length = (float)ratings.GetRange(0, ratings.Count / 2).Sum() / ratings.Sum();
ratingsGraph.Values = ratings.Select(rating => (float)rating);
ratingsContainer.FadeColour(Color4.White, 500, EasingTypes.Out);
}
else if (failOnMissing)
ratingsGraph.Values = new float[10];
else
ratingsContainer.FadeColour(Color4.Gray, 500, EasingTypes.Out);
if (hasRetriesFails)
{
var retries = metrics.Retries;
var fails = metrics.Fails;
retryFailContainer.Show();
float maxValue = fails.Zip(retries, (fail, retry) => fail + retry).Max();
failGraph.MaxValue = maxValue;
retryGraph.MaxValue = maxValue;
failGraph.Values = fails.Select(fail => (float)fail);
retryGraph.Values = retries.Zip(fails, (retry, fail) => retry + MathHelper.Clamp(fail, 0, maxValue));
retryFailContainer.FadeColour(Color4.White, 500, EasingTypes.Out);
}
else if (failOnMissing)
{
failGraph.Values = new float[100];
retryGraph.Values = new float[100];
}
else
retryFailContainer.FadeColour(Color4.Gray, 500, EasingTypes.Out);
}
public BeatmapDetails()
{
Children = new Drawable[]
@ -113,7 +164,6 @@ namespace osu.Game.Screens.Select
Direction = FillDirection.Vertical,
LayoutDuration = 200,
LayoutEasing = EasingTypes.OutQuint,
Padding = new MarginPadding(10) { Top = 25 },
Children = new []
{
description = new MetadataSegment("Description"),
@ -148,8 +198,8 @@ namespace osu.Game.Screens.Select
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0,10),
Padding = new MarginPadding(15) { Top = 25 },
Spacing = new Vector2(0,5),
Padding = new MarginPadding(10),
Children = new []
{
circleSize = new DifficultyRow("Circle Size", 7),
@ -252,7 +302,7 @@ namespace osu.Game.Screens.Select
new Container<BarGraph>
{
RelativeSizeAxes = Axes.X,
Size = new Vector2(1/0.6f, 50),
Size = new Vector2(1 / 0.6f, 50),
Children = new[]
{
retryGraph = new BarGraph
@ -272,9 +322,13 @@ namespace osu.Game.Screens.Select
};
}
private APIAccess api;
[BackgroundDependencyLoader]
private void load(OsuColour colour)
private void load(OsuColour colour, APIAccess api)
{
this.api = api;
description.AccentColour = colour.GrayB;
source.AccentColour = colour.GrayB;
tags.AccentColour = colour.YellowLight;
@ -308,7 +362,7 @@ namespace osu.Game.Screens.Select
{
difficultyValue = value;
bar.Length = value / maxValue;
valueText.Text = value.ToString(CultureInfo.InvariantCulture);
valueText.Text = value.ToString("N1", CultureInfo.CurrentCulture);
}
}
@ -431,4 +485,4 @@ namespace osu.Game.Screens.Select
}
}
}
}
}

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
@ -148,11 +149,16 @@ namespace osu.Game.Screens.Select
},
},
},
// Text for beatmap info
new DifficultyColourBar(beatmap.BeatmapInfo)
{
RelativeSizeAxes = Axes.Y,
Width = 20,
},
new FillFlowContainer
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Name = "Top-aligned metadata",
Anchor = Anchor.TopLeft,
Origin = Anchor.TopLeft,
Direction = FillDirection.Vertical,
Margin = new MarginPadding { Top = 10, Left = 25, Right = 10, Bottom = 20 },
AutoSizeAxes = Axes.Both,
@ -161,16 +167,32 @@ namespace osu.Game.Screens.Select
new OsuSpriteText
{
Font = @"Exo2.0-MediumItalic",
Text = metadata.Artist + " -- " + metadata.Title,
Text = beatmapInfo.Version,
TextSize = 24,
},
}
},
new FillFlowContainer
{
Name = "Bottom-aligned metadata",
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Direction = FillDirection.Vertical,
Margin = new MarginPadding { Top = 15, Left = 25, Right = 10, Bottom = 20 },
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
new OsuSpriteText
{
Font = @"Exo2.0-MediumItalic",
Text = !string.IsNullOrEmpty(metadata.Source) ? metadata.Source + " — " + metadata.Title : metadata.Title,
TextSize = 28,
Shadow = true,
},
new OsuSpriteText
{
Font = @"Exo2.0-MediumItalic",
Text = beatmapInfo.Version,
Text = metadata.Artist,
TextSize = 17,
Shadow = true,
},
new FillFlowContainer
{
@ -184,20 +206,18 @@ namespace osu.Game.Screens.Select
Font = @"Exo2.0-Medium",
Text = "mapped by ",
TextSize = 15,
Shadow = true,
},
},
new OsuSpriteText
{
Font = @"Exo2.0-Bold",
Text = metadata.Author,
TextSize = 15,
Shadow = true,
},
},
}
},
new FillFlowContainer
{
Margin = new MarginPadding { Top = 20 },
Margin = new MarginPadding { Top = 20, Left = 10 },
Spacing = new Vector2(40, 0),
AutoSizeAxes = Axes.Both,
Children = labels
@ -256,5 +276,37 @@ namespace osu.Game.Screens.Select
};
}
}
private class DifficultyColourBar : DifficultyColouredContainer
{
public DifficultyColourBar(BeatmapInfo beatmap) : base(beatmap)
{
}
[BackgroundDependencyLoader]
private void load()
{
const float full_opacity_ratio = 0.7f;
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = AccentColour,
Width = full_opacity_ratio,
},
new Box
{
RelativeSizeAxes = Axes.Both,
RelativePositionAxes = Axes.Both,
Colour = AccentColour,
Alpha = 0.5f,
X = full_opacity_ratio,
Width = 1 - full_opacity_ratio,
}
};
}
}
}
}

View File

@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using System;
using osu.Framework.Allocation;
using osu.Framework.Threading;
using osu.Game.Database;
using osu.Game.Rulesets.Scoring;
using osu.Game.Online.API;
@ -93,13 +94,18 @@ namespace osu.Game.Screens.Select.Leaderboards
private BeatmapInfo beatmap;
private ScheduledDelegate pendingBeatmapSwitch;
public BeatmapInfo Beatmap
{
get { return beatmap; }
set
{
beatmap = value;
Schedule(updateScores);
Scores = null;
pendingBeatmapSwitch?.Cancel();
pendingBeatmapSwitch = Schedule(updateScores);
}
}

View File

@ -179,6 +179,7 @@
<Compile Include="Rulesets\UI\StandardHudOverlay.cs" />
<Compile Include="Online\API\IOnlineComponent.cs" />
<Compile Include="Online\API\Requests\GetScoresRequest.cs" />
<Compile Include="Online\API\Requests\GetBeatmapDetailsRequest.cs" />
<Compile Include="Online\API\Requests\GetUserRequest.cs" />
<Compile Include="Overlays\DragBar.cs" />
<Compile Include="Overlays\LoginOverlay.cs" />
@ -187,6 +188,7 @@
<Compile Include="Beatmaps\WorkingBeatmap.cs" />
<Compile Include="Beatmaps\Drawables\BeatmapSetHeader.cs" />
<Compile Include="Beatmaps\Drawables\DifficultyIcon.cs" />
<Compile Include="Beatmaps\Drawables\DifficultyColouredContainer.cs" />
<Compile Include="Beatmaps\Drawables\Panel.cs" />
<Compile Include="Rulesets\Objects\Drawables\DrawableHitObject.cs" />
<Compile Include="Rulesets\Objects\HitObject.cs" />