Rename to BeatmapSetOverlay

This commit is contained in:
Dean Herbert
2017-09-25 17:26:27 +08:00
parent b83596b44d
commit 5be11f539b
14 changed files with 55 additions and 55 deletions

View File

@ -0,0 +1,107 @@
// 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.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Sprites;
using osu.Game.Users;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Overlays.BeatmapSet
{
public class AuthorInfo : Container
{
private const float height = 50;
private readonly UpdateableAvatar avatar;
private readonly FillFlowContainer fields;
private BeatmapSetInfo beatmapSet;
public BeatmapSetInfo BeatmapSet
{
get { return beatmapSet; }
set
{
if (value == beatmapSet) return;
beatmapSet = value;
var i = BeatmapSet.OnlineInfo;
avatar.User = i.Author;
fields.Children = new Drawable[]
{
new Field("made by", i.Author.Username, @"Exo2.0-RegularItalic"),
new Field("submitted on", i.Submitted.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold")
{
Margin = new MarginPadding { Top = 5 },
},
};
if (i.Ranked.HasValue)
{
fields.Add(new Field("ranked on ", i.Ranked.Value.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold"));
}
else if (i.LastUpdated.HasValue)
{
fields.Add(new Field("last updated on ", i.LastUpdated.Value.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold"));
}
}
}
public AuthorInfo()
{
RelativeSizeAxes = Axes.X;
Height = height;
Children = new Drawable[]
{
avatar = new UpdateableAvatar
{
Size = new Vector2(height),
CornerRadius = 3,
Masking = true,
EdgeEffect = new EdgeEffectParameters
{
Colour = Color4.Black.Opacity(0.25f),
Type = EdgeEffectType.Shadow,
Radius = 3,
Offset = new Vector2(0f, 1f),
},
},
fields = new FillFlowContainer
{
RelativeSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Padding = new MarginPadding { Left = height + 5 },
},
};
}
private class Field : FillFlowContainer
{
public Field(string first, string second, string secondFont)
{
AutoSizeAxes = Axes.Both;
Direction = FillDirection.Horizontal;
Children = new[]
{
new OsuSpriteText
{
Text = $"{first} ",
TextSize = 13,
},
new OsuSpriteText
{
Text = second,
TextSize = 13,
Font = secondFont,
},
};
}
}
}
}

View File

@ -0,0 +1,130 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using OpenTK;
namespace osu.Game.Overlays.BeatmapSet
{
public class BasicStats : Container
{
private readonly Statistic length, bpm, circleCount, sliderCount;
private BeatmapSetInfo beatmapSet;
public BeatmapSetInfo BeatmapSet
{
get { return beatmapSet; }
set
{
if (value == beatmapSet) return;
beatmapSet = value;
bpm.Value = BeatmapSet.OnlineInfo.BPM.ToString(@"0.##");
}
}
private BeatmapInfo beatmap;
public BeatmapInfo Beatmap
{
get { return beatmap; }
set
{
if (value == beatmap) return;
beatmap = value;
length.Value = TimeSpan.FromMilliseconds(beatmap.OnlineInfo.Length).ToString(@"m\:ss");
circleCount.Value = beatmap.OnlineInfo.CircleCount.ToString("N0");
sliderCount.Value = beatmap.OnlineInfo.SliderCount.ToString("N0");
}
}
public BasicStats()
{
Child = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Horizontal,
Children = new[]
{
length = new Statistic(FontAwesome.fa_clock_o, "Length") { Width = 0.25f },
bpm = new Statistic(FontAwesome.fa_circle, "BPM") { Width = 0.25f },
circleCount = new Statistic(FontAwesome.fa_circle_o, "Circle Count") { Width = 0.25f },
sliderCount = new Statistic(FontAwesome.fa_circle, "Slider Count") { Width = 0.25f },
},
};
}
private class Statistic : Container, IHasTooltip
{
private readonly string name;
private readonly OsuSpriteText value;
public string TooltipText => name;
public string Value
{
get { return value.Text; }
set { this.value.Text = value; }
}
public Statistic(FontAwesome icon, string name)
{
this.name = name;
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Children = new Drawable[]
{
new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
new SpriteIcon
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.Centre,
Icon = FontAwesome.fa_square,
Size = new Vector2(13),
Rotation = 45,
Colour = OsuColour.FromHex(@"441288"),
},
new SpriteIcon
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.Centre,
Icon = icon,
Size = new Vector2(13),
Colour = OsuColour.FromHex(@"f7dd55"),
Scale = new Vector2(0.8f),
},
value = new OsuSpriteText
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
TextSize = 13,
Font = @"Exo2.0-Bold",
Margin = new MarginPadding { Left = 10 },
},
},
},
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colour)
{
value.Colour = colour.Yellow;
}
}
}
}

View File

@ -0,0 +1,312 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Linq;
using osu.Framework;
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.Shapes;
using osu.Framework.Input;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Overlays.BeatmapSet
{
public class BeatmapPicker : Container
{
private const float tile_icon_padding = 7;
private const float tile_spacing = 2;
private readonly DifficultiesContainer difficulties;
private readonly OsuSpriteText version, starRating;
private readonly Statistic plays, favourites;
public readonly Bindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
private BeatmapSetInfo beatmapSet;
public BeatmapSetInfo BeatmapSet
{
get { return beatmapSet; }
set
{
if (value == beatmapSet) return;
beatmapSet = value;
Beatmap.Value = BeatmapSet.Beatmaps.First();
plays.Value = BeatmapSet.OnlineInfo.PlayCount;
favourites.Value = BeatmapSet.OnlineInfo.FavouriteCount;
difficulties.ChildrenEnumerable = BeatmapSet.Beatmaps.Select(b => new DifficultySelectorButton(b)
{
State = DifficultySelectorState.NotSelected,
OnHovered = beatmap =>
{
showBeatmap(beatmap);
starRating.Text = beatmap.StarDifficulty.ToString("Star Difficulty 0.##");
starRating.FadeIn(100);
},
OnClicked = beatmap =>
{
Beatmap.Value = beatmap;
},
});
updateDifficultyButtons();
}
}
public BeatmapPicker()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Children = new Drawable[]
{
new FillFlowContainer
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
difficulties = new DifficultiesContainer
{
AutoSizeAxes = Axes.Both,
Margin = new MarginPadding { Left = -(tile_icon_padding + tile_spacing / 2) },
OnLostHover = () =>
{
showBeatmap(Beatmap.Value);
starRating.FadeOut(100);
},
},
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Margin = new MarginPadding { Top = 10 },
Spacing = new Vector2(5f),
Children = new[]
{
version = new OsuSpriteText
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
TextSize = 20,
Font = @"Exo2.0-Bold",
},
starRating = new OsuSpriteText
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
TextSize = 13,
Font = @"Exo2.0-Bold",
Text = "Star Difficulty",
Alpha = 0,
Margin = new MarginPadding { Bottom = 1 },
},
},
},
new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(10f),
Margin = new MarginPadding { Top = 5 },
Children = new[]
{
plays = new Statistic(FontAwesome.fa_play_circle),
favourites = new Statistic(FontAwesome.fa_heart),
},
},
},
},
};
Beatmap.ValueChanged += b =>
{
showBeatmap(b);
updateDifficultyButtons();
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
starRating.Colour = colours.Yellow;
}
protected override void LoadComplete()
{
base.LoadComplete();
// done here so everything can bind in intialization and get the first trigger
Beatmap.TriggerChange();
}
private void showBeatmap(BeatmapInfo beatmap) => version.Text = beatmap.Version;
private void updateDifficultyButtons()
{
difficulties.Children.ToList().ForEach(diff => diff.State = diff.Beatmap == Beatmap.Value ? DifficultySelectorState.Selected : DifficultySelectorState.NotSelected);
}
private class DifficultiesContainer : FillFlowContainer<DifficultySelectorButton>
{
public Action OnLostHover;
protected override void OnHoverLost(InputState state)
{
base.OnHoverLost(state);
OnLostHover?.Invoke();
}
}
private class DifficultySelectorButton : OsuClickableContainer, IStateful<DifficultySelectorState>
{
private const float transition_duration = 100;
private const float size = 52;
private readonly Container bg;
private readonly DifficultyIcon icon;
public readonly BeatmapInfo Beatmap;
public Action<BeatmapInfo> OnHovered;
public Action<BeatmapInfo> OnClicked;
public event Action<DifficultySelectorState> StateChanged;
private DifficultySelectorState state;
public DifficultySelectorState State
{
get { return state; }
set
{
if (value == state) return;
state = value;
StateChanged?.Invoke(State);
if (value == DifficultySelectorState.Selected)
fadeIn();
else
fadeOut();
}
}
public DifficultySelectorButton(BeatmapInfo beatmap)
{
Beatmap = beatmap;
Size = new Vector2(size);
Margin = new MarginPadding { Horizontal = tile_spacing / 2 };
Children = new Drawable[]
{
bg = new Container
{
RelativeSizeAxes = Axes.Both,
Masking = true,
CornerRadius = 4,
Child = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(0.5f),
},
},
icon = new DifficultyIcon(beatmap)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(size - tile_icon_padding * 2),
Margin = new MarginPadding { Bottom = 1 },
},
};
}
protected override bool OnHover(InputState state)
{
fadeIn();
OnHovered?.Invoke(Beatmap);
return base.OnHover(state);
}
protected override void OnHoverLost(InputState state)
{
if (State == DifficultySelectorState.NotSelected)
fadeOut();
base.OnHoverLost(state);
}
protected override bool OnClick(InputState state)
{
OnClicked?.Invoke(Beatmap);
return base.OnClick(state);
}
private void fadeIn()
{
bg.FadeIn(transition_duration);
icon.FadeIn(transition_duration);
}
private void fadeOut()
{
bg.FadeOut();
icon.FadeTo(0.7f, transition_duration);
}
}
private class Statistic : FillFlowContainer
{
private readonly OsuSpriteText text;
private int value;
public int Value
{
get { return value; }
set
{
this.value = value;
text.Text = Value.ToString(@"N0");
}
}
public Statistic(FontAwesome icon)
{
AutoSizeAxes = Axes.Both;
Direction = FillDirection.Horizontal;
Spacing = new Vector2(2f);
Children = new Drawable[]
{
new SpriteIcon
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Icon = icon,
Shadow = true,
Size = new Vector2(13),
},
text = new OsuSpriteText
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Font = @"Exo2.0-SemiBoldItalic",
TextSize = 14,
},
};
}
}
private enum DifficultySelectorState
{
Selected,
NotSelected,
}
}
}

View File

@ -0,0 +1,118 @@
// 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.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps;
using osu.Game.Screens.Select.Details;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Overlays.BeatmapSet
{
public class Details : FillFlowContainer
{
private readonly PreviewButton preview;
private readonly BasicStats basic;
private readonly AdvancedStats advanced;
private readonly UserRatings ratings;
private BeatmapSetInfo beatmapSet;
public BeatmapSetInfo BeatmapSet
{
get { return beatmapSet; }
set
{
if (value == beatmapSet) return;
beatmapSet = value;
basic.BeatmapSet = preview.BeatmapSet = BeatmapSet;
}
}
private BeatmapInfo beatmap;
public BeatmapInfo Beatmap
{
get { return beatmap; }
set
{
if (value == beatmap) return;
beatmap = value;
basic.Beatmap = advanced.Beatmap = Beatmap;
ratings.Metrics = Beatmap.Metrics;
}
}
public Details()
{
Width = BeatmapSetOverlay.RIGHT_WIDTH;
AutoSizeAxes = Axes.Y;
Spacing = new Vector2(1f);
Children = new Drawable[]
{
preview = new PreviewButton
{
RelativeSizeAxes = Axes.X,
},
new DetailBox
{
Child = basic = new BasicStats
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Margin = new MarginPadding { Vertical = 10 },
},
},
new DetailBox
{
Child = advanced = new AdvancedStats
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Margin = new MarginPadding { Vertical = 7.5f },
},
},
new DetailBox
{
Child = ratings = new UserRatings
{
RelativeSizeAxes = Axes.X,
Height = 95,
Margin = new MarginPadding { Top = 10 },
},
},
};
}
private class DetailBox : Container
{
private readonly Container content;
protected override Container<Drawable> Content => content;
public DetailBox()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
InternalChildren = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(0.5f),
},
content = new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Horizontal = 15 },
},
};
}
}
}
}

View File

@ -0,0 +1,59 @@
// 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.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using OpenTK;
namespace osu.Game.Overlays.BeatmapSet
{
public class DownloadButton : HeaderButton
{
public DownloadButton(string title, string subtitle)
{
Width = 120;
RelativeSizeAxes = Axes.Y;
Child = new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Horizontal = 10 },
Children = new Drawable[]
{
new FillFlowContainer
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Children = new[]
{
new OsuSpriteText
{
Text = title,
TextSize = 13,
Font = @"Exo2.0-Bold",
},
new OsuSpriteText
{
Text = subtitle,
TextSize = 11,
Font = @"Exo2.0-Bold",
},
},
},
new SpriteIcon
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Icon = FontAwesome.fa_download,
Size = new Vector2(16),
Margin = new MarginPadding { Right = 5 },
},
},
};
}
}
}

View File

@ -0,0 +1,80 @@
// 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.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using OpenTK;
namespace osu.Game.Overlays.BeatmapSet
{
public class FavouriteButton : HeaderButton
{
public readonly Bindable<bool> Favourited = new Bindable<bool>();
public FavouriteButton()
{
RelativeSizeAxes = Axes.Y;
Container pink;
SpriteIcon icon;
Children = new Drawable[]
{
pink = new Container
{
RelativeSizeAxes = Axes.Both,
Alpha = 0f,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex(@"9f015f"),
},
new Triangles
{
RelativeSizeAxes = Axes.Both,
ColourLight = OsuColour.FromHex(@"cb2187"),
ColourDark = OsuColour.FromHex(@"9f015f"),
TriangleScale = 1.5f,
},
},
},
icon = new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.fa_heart_o,
Size = new Vector2(18),
Shadow = false,
},
};
Favourited.ValueChanged += value =>
{
if (value)
{
pink.FadeIn(200);
icon.Icon = FontAwesome.fa_heart;
}
else
{
pink.FadeOut(200);
icon.Icon = FontAwesome.fa_heart_o;
}
};
Action = () => Favourited.Value = !Favourited.Value;
}
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
Width = DrawHeight;
}
}
}

View File

@ -0,0 +1,228 @@
// 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.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Overlays.BeatmapSet
{
public class Header : Container
{
private const float transition_duration = 250;
private const float tabs_height = 50;
private const float buttons_height = 45;
private const float buttons_spacing = 5;
private readonly Box tabsBg;
private readonly Container coverContainer;
private readonly OsuSpriteText title, artist;
private readonly AuthorInfo author;
private readonly Details details;
private DelayedLoadWrapper cover;
public readonly BeatmapPicker Picker;
private BeatmapSetInfo beatmapSet;
public BeatmapSetInfo BeatmapSet
{
get { return beatmapSet; }
set
{
if (value == beatmapSet) return;
beatmapSet = value;
Picker.BeatmapSet = author.BeatmapSet = details.BeatmapSet = BeatmapSet;
title.Text = BeatmapSet.Metadata.Title;
artist.Text = BeatmapSet.Metadata.Artist;
cover?.FadeOut(400, Easing.Out);
coverContainer.Add(cover = new DelayedLoadWrapper(new BeatmapSetCover(BeatmapSet)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fill,
OnLoadComplete = d =>
{
d.FadeInFromZero(400, Easing.Out);
},
})
{
RelativeSizeAxes = Axes.Both,
TimeBeforeLoad = 300
});
}
}
public Header()
{
RelativeSizeAxes = Axes.X;
Height = 400;
Masking = true;
EdgeEffect = new EdgeEffectParameters
{
Colour = Color4.Black.Opacity(0.25f),
Type = EdgeEffectType.Shadow,
Radius = 3,
Offset = new Vector2(0f, 1f),
};
Container noVideoButtons;
FillFlowContainer videoButtons;
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.X,
Height = tabs_height,
Children = new[]
{
tabsBg = new Box
{
RelativeSizeAxes = Axes.Both,
},
},
},
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Top = tabs_height },
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
},
coverContainer = new Container
{
RelativeSizeAxes = Axes.Both,
},
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.3f), Color4.Black.Opacity(0.8f)),
},
},
},
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Top = 20, Bottom = 30, Horizontal = BeatmapSetOverlay.X_PADDING },
Child = new FillFlowContainer
{
RelativeSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.X,
Height = 113,
Child = Picker = new BeatmapPicker(),
},
title = new OsuSpriteText
{
Font = @"Exo2.0-BoldItalic",
TextSize = 37,
},
artist = new OsuSpriteText
{
Font = @"Exo2.0-SemiBoldItalic",
TextSize = 25,
},
new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Margin = new MarginPadding { Top = 20 },
Child = author = new AuthorInfo(),
},
new Container
{
RelativeSizeAxes = Axes.X,
Height = buttons_height,
Margin = new MarginPadding { Top = 10 },
Children = new Drawable[]
{
new FavouriteButton(),
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = buttons_height + buttons_spacing },
Children = new Drawable[]
{
noVideoButtons = new Container
{
RelativeSizeAxes = Axes.Both,
Alpha = 0f,
Child = new DownloadButton("Download", @""),
},
videoButtons = new FillFlowContainer
{
RelativeSizeAxes = Axes.Both,
Spacing = new Vector2(buttons_spacing),
Alpha = 0f,
Children = new[]
{
new DownloadButton("Download", "with Video"),
new DownloadButton("Download", "without Video"),
},
},
},
},
},
},
},
},
},
details = new Details
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Margin = new MarginPadding { Right = BeatmapSetOverlay.X_PADDING },
},
},
},
};
Picker.Beatmap.ValueChanged += b =>
{
details.Beatmap = b;
if (b.OnlineInfo.HasVideo)
{
noVideoButtons.FadeOut(transition_duration);
videoButtons.FadeIn(transition_duration);
}
else
{
noVideoButtons.FadeIn(transition_duration);
videoButtons.FadeOut(transition_duration);
}
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
tabsBg.Colour = colours.Gray3;
}
}
}

View File

@ -0,0 +1,45 @@
// 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.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.BeatmapSet
{
public class HeaderButton : OsuClickableContainer
{
private readonly Container content;
protected override Container<Drawable> Content => content;
public HeaderButton()
{
CornerRadius = 3;
Masking = true;
InternalChildren = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex(@"094c5f"),
},
new Triangles
{
RelativeSizeAxes = Axes.Both,
ColourLight = OsuColour.FromHex(@"0f7c9b"),
ColourDark = OsuColour.FromHex(@"094c5f"),
TriangleScale = 1.5f,
},
content = new Container
{
RelativeSizeAxes = Axes.Both,
},
};
}
}
}

View File

@ -0,0 +1,196 @@
// 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.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Overlays.BeatmapSet
{
public class Info : Container
{
private const float transition_duration = 250;
private const float metadata_width = 225;
private const float spacing = 20;
private readonly MetadataSection description, source, tags;
private readonly Box successRateBackground;
private readonly SuccessRate successRate;
private BeatmapSetInfo beatmapSet;
public BeatmapSetInfo BeatmapSet
{
get { return beatmapSet; }
set
{
if (value == beatmapSet) return;
beatmapSet = value;
source.Text = BeatmapSet.Metadata.Source;
tags.Text = BeatmapSet.Metadata.Tags;
}
}
public BeatmapInfo Beatmap
{
get { return successRate.Beatmap; }
set { successRate.Beatmap = value; }
}
public Info()
{
RelativeSizeAxes = Axes.X;
Height = 220;
Masking = true;
EdgeEffect = new EdgeEffectParameters
{
Colour = Color4.Black.Opacity(0.25f),
Type = EdgeEffectType.Shadow,
Radius = 3,
Offset = new Vector2(0f, 1f),
};
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.White,
},
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Top = 15, Horizontal = BeatmapSetOverlay.X_PADDING },
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Right = metadata_width + BeatmapSetOverlay.RIGHT_WIDTH + spacing * 2 },
Child = new ScrollContainer
{
RelativeSizeAxes = Axes.Both,
ScrollbarVisible = false,
Child = description = new MetadataSection("Description"),
},
},
new ScrollContainer
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
RelativeSizeAxes = Axes.Y,
Width = metadata_width,
ScrollbarVisible = false,
Padding = new MarginPadding { Horizontal = 10 },
Margin = new MarginPadding { Right = BeatmapSetOverlay.RIGHT_WIDTH + spacing },
Child = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
LayoutDuration = transition_duration,
Children = new[]
{
source = new MetadataSection("Source"),
tags = new MetadataSection("Tags"),
},
},
},
new Container
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
RelativeSizeAxes = Axes.Y,
Width = BeatmapSetOverlay.RIGHT_WIDTH,
Children = new Drawable[]
{
successRateBackground = new Box
{
RelativeSizeAxes = Axes.Both,
},
successRate = new SuccessRate
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Top = 20, Horizontal = 15 },
},
},
},
},
},
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
successRateBackground.Colour = colours.GrayE;
source.TextColour = description.TextColour = colours.Gray5;
tags.TextColour = colours.BlueDark;
}
private class MetadataSection : FillFlowContainer
{
private readonly OsuSpriteText header;
private readonly TextFlowContainer textFlow;
public string Text
{
set
{
if (string.IsNullOrEmpty(value))
{
this.FadeOut(transition_duration);
return;
}
this.FadeIn(transition_duration);
textFlow.Clear();
textFlow.AddText(value, s => s.TextSize = 14);
}
}
public Color4 TextColour
{
get { return textFlow.Colour; }
set { textFlow.Colour = value; }
}
public MetadataSection(string title)
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Spacing = new Vector2(5f);
InternalChildren = new Drawable[]
{
header = new OsuSpriteText
{
Text = title,
Font = @"Exo2.0-Bold",
TextSize = 14,
Shadow = false,
Margin = new MarginPadding { Top = 20 },
},
textFlow = new TextFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
},
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
header.Colour = colours.Gray5;
}
}
}
}

View File

@ -0,0 +1,218 @@
// 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.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Overlays.BeatmapSet
{
public class PreviewButton : OsuClickableContainer
{
private const float transition_duration = 500;
private readonly Container audioWrapper;
private readonly Box bg, progress;
private readonly SpriteIcon icon;
private readonly LoadingAnimation loadingAnimation;
private Track preview;
private bool loading
{
set
{
if (value)
{
loadingAnimation.Show();
icon.FadeOut(transition_duration * 5, Easing.OutQuint);
}
else
{
loadingAnimation.Hide();
icon.FadeIn(transition_duration, Easing.OutQuint);
}
}
}
private BeatmapSetInfo beatmapSet;
public BeatmapSetInfo BeatmapSet
{
get { return beatmapSet; }
set
{
if (value == beatmapSet) return;
beatmapSet = value;
Playing = false;
preview = null;
}
}
private bool playing;
public bool Playing
{
get { return playing; }
set
{
if (value == playing) return;
playing = value;
if (preview == null)
{
loading = true;
audioWrapper.Child = new AsyncLoadWrapper(new AudioLoadWrapper(BeatmapSet)
{
OnLoadComplete = d =>
{
loading = false;
preview = (d as AudioLoadWrapper)?.Preview;
Playing = Playing;
updatePlayingState();
},
});
return;
}
updatePlayingState();
}
}
public PreviewButton()
{
Height = 42;
Children = new Drawable[]
{
audioWrapper = new Container(),
bg = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(0.25f),
},
new Container
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
RelativeSizeAxes = Axes.X,
Height = 3,
Child = progress = new Box
{
RelativeSizeAxes = Axes.Both,
Width = 0f,
Alpha = 0f,
},
},
icon = new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.fa_play,
Size = new Vector2(18),
Shadow = false,
},
loadingAnimation = new LoadingAnimation
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
};
Action = () => Playing = !Playing;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
progress.Colour = colours.Yellow;
}
protected override void Update()
{
base.Update();
if (Playing && preview != null)
{
progress.Width = (float)(preview.CurrentTime / preview.Length);
if (preview.HasCompleted)
{
Playing = false;
preview = null;
}
}
}
protected override void Dispose(bool isDisposing)
{
Playing = false;
base.Dispose(isDisposing);
}
protected override bool OnHover(InputState state)
{
bg.FadeColour(Color4.Black.Opacity(0.5f), 100);
return base.OnHover(state);
}
protected override void OnHoverLost(InputState state)
{
bg.FadeColour(Color4.Black.Opacity(0.25f), 100);
base.OnHoverLost(state);
}
private void updatePlayingState()
{
if (preview == null) return;
if (Playing)
{
icon.Icon = FontAwesome.fa_stop;
progress.FadeIn(100);
preview.Seek(0);
preview.Start();
}
else
{
icon.Icon = FontAwesome.fa_play;
progress.FadeOut(100);
preview.Stop();
}
}
private class AudioLoadWrapper : Drawable
{
private readonly string preview;
public Track Preview;
public AudioLoadWrapper(BeatmapSetInfo set)
{
preview = set.OnlineInfo.Preview;
}
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
if (!string.IsNullOrEmpty(preview))
{
Preview = audio.Track.Get(preview);
Preview.Volume.Value = 0.5;
}
}
}
}
}

View File

@ -0,0 +1,113 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Select.Details;
namespace osu.Game.Overlays.BeatmapSet
{
public class SuccessRate : Container
{
private readonly FillFlowContainer header;
private readonly OsuSpriteText successRateLabel, successPercent, graphLabel;
private readonly Bar successRate;
private readonly Container percentContainer;
private readonly FailRetryGraph graph;
private BeatmapInfo beatmap;
public BeatmapInfo Beatmap
{
get { return beatmap; }
set
{
if (value == beatmap) return;
beatmap = value;
var rate = (float)beatmap.OnlineInfo.PassCount / beatmap.OnlineInfo.PlayCount;
successPercent.Text = $"{Math.Round(rate * 100)}%";
successRate.Length = rate;
percentContainer.ResizeWidthTo(successRate.Length, 250, Easing.InOutCubic);
graph.Metrics = Beatmap.Metrics;
}
}
public SuccessRate()
{
Children = new Drawable[]
{
header = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
successRateLabel = new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = "Success Rate",
TextSize = 13,
},
successRate = new Bar
{
RelativeSizeAxes = Axes.X,
Height = 5,
Margin = new MarginPadding { Top = 5 },
},
percentContainer = new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Width = 0f,
Child = successPercent = new OsuSpriteText
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopCentre,
Text = @"0%",
TextSize = 13,
},
},
graphLabel = new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = "Points of Failure",
TextSize = 13,
Margin = new MarginPadding { Vertical = 20 },
},
},
},
graph = new FailRetryGraph
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
RelativeSizeAxes = Axes.Both,
},
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
successRateLabel.Colour = successPercent.Colour = graphLabel.Colour = colours.Gray5;
successRate.AccentColour = colours.Green;
successRate.BackgroundColour = colours.GrayD;
}
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
graph.Padding = new MarginPadding { Top = header.DrawHeight };
}
}
}