1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 18:07:24 +08:00
osu-lazer/osu.Game/Screens/Select/BeatmapDetails.cs

524 lines
20 KiB
C#
Raw Normal View History

2017-03-25 06:02:24 +08:00
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
2017-03-26 06:33:03 +08:00
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
2017-03-25 06:02:24 +08:00
using osu.Framework.Graphics;
2017-03-26 06:33:03 +08:00
using osu.Framework.Graphics.Containers;
2017-03-25 06:02:24 +08:00
using osu.Framework.Graphics.Primitives;
2017-03-26 06:33:03 +08:00
using osu.Framework.Graphics.Sprites;
using osu.Game.Database;
2017-03-25 06:02:24 +08:00
using osu.Game.Graphics;
2017-04-02 00:12:44 +08:00
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using System.Collections.Generic;
2017-03-29 22:10:07 +08:00
using System.Globalization;
2017-03-26 06:33:03 +08:00
using System.Linq;
2017-03-25 06:02:24 +08:00
namespace osu.Game.Screens.Select
2017-03-25 06:02:24 +08:00
{
public class BeatmapDetails : Container
2017-03-25 06:02:24 +08:00
{
private readonly MetadataSegment description;
private readonly MetadataSegment source;
private readonly MetadataSegment tags;
2017-03-26 06:33:03 +08:00
private readonly DifficultyRow circleSize;
private readonly DifficultyRow drainRate;
private readonly DifficultyRow overallDifficulty;
private readonly DifficultyRow approachRate;
private readonly DifficultyRow stars;
2017-03-26 06:33:03 +08:00
private readonly Container ratingsContainer;
private readonly Bar ratingsBar;
2017-04-02 00:12:44 +08:00
private readonly OsuSpriteText negativeRatings;
private readonly OsuSpriteText positiveRatings;
private readonly BarGraph ratingsGraph;
private readonly FillFlowContainer retryAndFailContainer;
private readonly BarGraph retryGraph;
private readonly BarGraph failGraph;
2017-03-29 02:18:56 +08:00
2017-03-26 06:33:03 +08:00
private BeatmapInfo beatmap;
public BeatmapInfo Beatmap
2017-03-25 06:02:24 +08:00
{
get
{
2017-03-26 06:33:03 +08:00
return beatmap;
2017-03-25 06:02:24 +08:00
}
set
{
2017-03-26 06:33:03 +08:00
if (beatmap == value) return;
beatmap = value;
description.ContentText = beatmap.Version;
source.ContentText = beatmap.Metadata.Source;
tags.ContentText = beatmap.Metadata.Tags;
2017-03-26 06:33:03 +08:00
circleSize.Value = beatmap.Difficulty.CircleSize;
drainRate.Value = beatmap.Difficulty.DrainRate;
overallDifficulty.Value = beatmap.Difficulty.OverallDifficulty;
approachRate.Value = beatmap.Difficulty.ApproachRate;
2017-04-04 23:27:08 +08:00
stars.Value = (float)beatmap.StarDifficulty;
2017-03-25 06:02:24 +08:00
}
}
private List<int> ratings;
public IEnumerable<int> Ratings
{
get
{
return ratings;
}
set
{
2017-04-08 02:32:09 +08:00
ratings = value?.ToList() ?? new List<int>();
if(ratings.Count == 0)
ratingsContainer.FadeOut(250);
else
{
ratingsContainer.FadeIn(250);
negativeRatings.Text = ratings.GetRange(0, 5).Sum().ToString();
positiveRatings.Text = ratings.GetRange(5, 5).Sum().ToString();
ratingsBar.Length = (float)ratings.GetRange(0, 5).Sum() / ratings.Sum();
ratingsGraph.Values = ratings.Select(rating => (float)rating);
}
}
}
2017-03-29 02:18:56 +08:00
private List<int> retries;
2017-03-29 02:18:56 +08:00
public IEnumerable<int> Retries
{
get
{
return retries;
}
set
{
2017-04-08 02:32:09 +08:00
retries = value?.ToList() ?? new List<int>();
calcRetryAndFailGraph();
2017-03-29 02:18:56 +08:00
}
}
private List<int> fails;
2017-03-29 02:18:56 +08:00
public IEnumerable<int> Fails
{
get
{
return fails;
}
set
{
2017-04-08 02:32:09 +08:00
fails = value?.ToList() ?? new List<int>();
calcRetryAndFailGraph();
2017-03-29 02:18:56 +08:00
}
}
private void calcRetryAndFailGraph()
2017-03-29 02:18:56 +08:00
{
if ((fails?.Count ?? 0) == 0 || (retries?.Count ?? 0) == 0)
retryAndFailContainer.FadeOut(250);
else
{
retryAndFailContainer.FadeIn(250);
failGraph.Values = fails.Select(fail => (float)fail);
2017-04-08 02:32:09 +08:00
retryGraph.Values = retries?.Select((retry, index) => (float)retry + fails[index]);
}
2017-03-29 02:18:56 +08:00
}
public BeatmapDetails()
2017-03-25 06:02:24 +08:00
{
2017-03-26 06:33:03 +08:00
Children = new Drawable[]
2017-03-25 06:02:24 +08:00
{
2017-03-26 06:33:03 +08:00
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
Alpha = 0.5f,
},
new FillFlowContainer<MetadataSegment>()
2017-03-25 06:02:24 +08:00
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Width = 0.4f,
Direction = FillDirection.Vertical,
LayoutDuration = 1,
LayoutEasing = EasingTypes.OutQuint,
Padding = new MarginPadding(10) { Top = 25 },
Children = new []
2017-03-25 06:02:24 +08:00
{
description = new MetadataSegment
2017-03-26 06:33:03 +08:00
{
HeaderText = "Description",
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
2017-03-26 06:33:03 +08:00
},
source = new MetadataSegment
2017-03-25 06:02:24 +08:00
{
HeaderText = "Source",
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
2017-03-25 06:02:24 +08:00
},
tags = new MetadataSegment
2017-03-25 06:02:24 +08:00
{
HeaderText = "Tags",
2017-03-25 06:02:24 +08:00
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
}
2017-03-25 06:02:24 +08:00
},
2017-03-26 06:33:03 +08:00
},
new FillFlowContainer
2017-03-26 06:33:03 +08:00
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Width = 0.6f,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0,15),
Padding = new MarginPadding(10) { Top = 0 },
Children = new Drawable[]
2017-03-26 06:33:03 +08:00
{
new Container
2017-03-26 06:33:03 +08:00
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Children = new Drawable[]
2017-03-26 06:33:03 +08:00
{
new Box
2017-03-26 06:33:03 +08:00
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
Alpha = 0.5f,
2017-03-26 06:33:03 +08:00
},
new FillFlowContainer
2017-03-26 06:33:03 +08:00
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0,10),
Padding = new MarginPadding(15) { Top = 25 },
Children = new []
{
circleSize = new DifficultyRow
{
DifficultyName = "Circle Size",
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
MaxValue = 7,
},
drainRate = new DifficultyRow
{
DifficultyName = "HP Drain",
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
},
overallDifficulty = new DifficultyRow
{
DifficultyName = "Accuracy",
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
},
approachRate = new DifficultyRow
{
DifficultyName = "Approach Rate",
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
},
stars = new DifficultyRow
{
DifficultyName = "Star Difficulty",
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
},
},
2017-03-26 06:33:03 +08:00
},
},
},
ratingsContainer = new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Alpha = 0,
AlwaysPresent = true,
Children = new Drawable[]
{
new Box
2017-03-26 06:33:03 +08:00
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
Alpha = 0.5f,
2017-03-26 06:33:03 +08:00
},
new FillFlowContainer
2017-03-26 06:33:03 +08:00
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Padding = new MarginPadding(15) { Top = 25, Bottom = 0 },
Children = new Drawable[]
{
2017-04-02 00:12:44 +08:00
new OsuSpriteText
{
Text = "User Rating",
Font = @"Exo2.0-Medium",
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
},
ratingsBar = new Bar
{
RelativeSizeAxes = Axes.X,
Height = 5,
Length = 0,
},
new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Children = new[]
{
2017-04-02 00:12:44 +08:00
negativeRatings = new OsuSpriteText
{
2017-04-04 05:03:49 +08:00
Font = @"Exo2.0-Regular",
Text = "0",
},
2017-04-02 00:12:44 +08:00
positiveRatings = new OsuSpriteText
{
2017-04-04 05:03:49 +08:00
Font = @"Exo2.0-Regular",
Text = "0",
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
},
},
},
2017-04-02 00:12:44 +08:00
new OsuSpriteText
{
Text = "Rating Spread",
TextSize = 14,
2017-04-04 05:03:49 +08:00
Font = @"Exo2.0-Regular",
2017-03-29 02:18:56 +08:00
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
},
ratingsGraph = new BarGraph
{
RelativeSizeAxes = Axes.X,
Height = 50,
2017-03-29 02:18:56 +08:00
},
},
2017-03-26 06:33:03 +08:00
},
},
},
retryAndFailContainer = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Alpha = 0,
Children = new Drawable[]
{
new OsuSpriteText
{
Text = "Points of Failure",
Font = @"Exo2.0-Regular",
},
new Container<BarGraph>
{
RelativeSizeAxes = Axes.X,
Size = new Vector2(1/0.6f, 50),
Children = new[]
{
retryGraph = new BarGraph
{
RelativeSizeAxes = Axes.Both,
},
failGraph = new BarGraph
{
RelativeSizeAxes = Axes.Both,
},
},
},
}
2017-03-29 02:18:56 +08:00
},
},
},
2017-03-25 06:02:24 +08:00
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colour)
{
description.AccentColour = colour.GrayB;
source.AccentColour = colour.GrayB;
tags.AccentColour = colour.YellowLight;
stars.AccentColour = colour.Yellow;
ratingsBar.BackgroundColour = colour.Green;
ratingsBar.BarColour = colour.YellowDark;
ratingsGraph.Colour = colour.BlueDark;
failGraph.Colour = colour.YellowDarker;
retryGraph.Colour = colour.Yellow;
2017-03-26 06:33:03 +08:00
}
private class DifficultyRow : Container, IHasAccentColour
2017-03-26 06:33:03 +08:00
{
2017-04-02 00:12:44 +08:00
private readonly OsuSpriteText name;
private readonly Bar bar;
2017-04-02 00:12:44 +08:00
private readonly OsuSpriteText valueText;
2017-03-26 06:33:03 +08:00
private float difficultyValue;
2017-04-04 23:27:08 +08:00
2017-03-26 06:33:03 +08:00
public float Value
{
get
{
return difficultyValue;
}
set
{
difficultyValue = value;
2017-04-04 23:27:08 +08:00
bar.Length = value / maxValue;
2017-03-29 22:10:07 +08:00
valueText.Text = value.ToString(CultureInfo.InvariantCulture);
2017-03-26 06:33:03 +08:00
}
}
private float maxValue = 10;
2017-04-04 23:27:08 +08:00
2017-03-26 06:33:03 +08:00
public float MaxValue
{
get
{
return maxValue;
}
set
{
maxValue = value;
2017-04-04 23:27:08 +08:00
bar.Length = Value / value;
2017-03-26 06:33:03 +08:00
}
}
public string DifficultyName
{
get
{
return name.Text;
}
set
{
name.Text = value;
}
}
public Color4 AccentColour
2017-03-26 06:33:03 +08:00
{
get
{
return bar.BarColour;
}
set
{
bar.BarColour = value;
}
}
public DifficultyRow()
{
Children = new Drawable[]
{
2017-04-02 00:12:44 +08:00
name = new OsuSpriteText
2017-03-26 06:33:03 +08:00
{
2017-04-04 05:03:49 +08:00
Font = @"Exo2.0-Regular",
2017-03-26 06:33:03 +08:00
},
bar = new Bar
2017-03-26 06:33:03 +08:00
{
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(1, 0.35f),
Padding = new MarginPadding { Left = 100, Right = 25 },
},
2017-04-02 00:12:44 +08:00
valueText = new OsuSpriteText
2017-03-26 06:33:03 +08:00
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
2017-04-04 05:03:49 +08:00
Font = @"Exo2.0-Regular",
2017-03-26 06:33:03 +08:00
},
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colour)
{
name.Colour = colour.GrayB;
bar.BackgroundColour = colour.Gray7;
valueText.Colour = colour.GrayB;
}
2017-03-25 06:02:24 +08:00
}
private class MetadataSegment : Container, IHasAccentColour
{
private readonly OsuSpriteText header;
private readonly FillFlowContainer<OsuSpriteText> content;
private const int fade_time = 250;
public string HeaderText
{
set
{
header.Text = value;
}
}
public string ContentText
{
set
{
if (value == "")
FadeOut(fade_time);
else
{
FadeIn(fade_time);
content.Children = value.Split(' ').Select(text => new OsuSpriteText
{
Text = text + " ",
Font = "Exo2.0-Regular",
});
}
}
}
public Color4 AccentColour
{
get
{
return content.Colour;
}
set
{
content.Colour = value;
}
}
public MetadataSegment()
{
Children = new Drawable[]
{
header = new OsuSpriteText
{
Font = @"Exo2.0-Bold",
},
content = new FillFlowContainer<OsuSpriteText>
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Full,
Margin = new MarginPadding { Top = header.TextSize }
}
};
}
}
2017-03-25 06:02:24 +08:00
}
2017-04-04 23:27:08 +08:00
}