Merge remote-tracking branch 'upstream/master' into profile

# Conflicts:
#	osu.Game/Graphics/Containers/SectionsContainer.cs
This commit is contained in:
Dean Herbert
2017-07-13 13:44:21 +09:00
59 changed files with 590 additions and 360 deletions

View File

@ -67,7 +67,7 @@ namespace osu.Game.Overlays.Chat
var displayMessages = newMessages.Skip(Math.Max(0, newMessages.Count() - Channel.MAX_HISTORY));
//up to last Channel.MAX_HISTORY messages
flow.Add(displayMessages.Select(m => new ChatLine(m)));
flow.AddRange(displayMessages.Select(m => new ChatLine(m)));
if (!IsLoaded) return;

View File

@ -1,14 +1,12 @@
// 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.Linq;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Textures;
using osu.Framework.Localisation;
using osu.Game.Database;
using osu.Game.Graphics;
@ -50,7 +48,7 @@ namespace osu.Game.Overlays.Direct
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, LocalisationEngine localisation, TextureStore textures)
private void load(OsuColour colours, LocalisationEngine localisation)
{
Children = new[]
{
@ -59,7 +57,7 @@ namespace osu.Game.Overlays.Direct
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
},
GetBackground(textures),
CreateBackground(),
new Box
{
RelativeSizeAxes = Axes.Both,
@ -180,11 +178,11 @@ namespace osu.Game.Overlays.Direct
Margin = new MarginPadding { Top = vertical_padding, Right = vertical_padding },
Children = new[]
{
new Statistic(FontAwesome.fa_play_circle, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.PlayCount ?? 0)
new Statistic(FontAwesome.fa_play_circle, SetInfo.OnlineInfo?.PlayCount ?? 0)
{
Margin = new MarginPadding { Right = 1 },
},
new Statistic(FontAwesome.fa_heart, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.FavouriteCount ?? 0),
new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0),
},
},
};

View File

@ -12,8 +12,6 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Database;
using osu.Framework.Allocation;
using osu.Framework.Localisation;
using osu.Framework.Graphics.Textures;
using System.Linq;
using osu.Framework.Input;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
@ -49,7 +47,7 @@ namespace osu.Game.Overlays.Direct
}
[BackgroundDependencyLoader]
private void load(LocalisationEngine localisation, TextureStore textures)
private void load(LocalisationEngine localisation)
{
Children = new[]
{
@ -58,7 +56,7 @@ namespace osu.Game.Overlays.Direct
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
},
GetBackground(textures),
CreateBackground(),
new Box
{
RelativeSizeAxes = Axes.Both,
@ -105,11 +103,11 @@ namespace osu.Game.Overlays.Direct
Margin = new MarginPadding { Right = height - vertical_padding * 2 + vertical_padding },
Children = new Drawable[]
{
new Statistic(FontAwesome.fa_play_circle, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.PlayCount ?? 0)
new Statistic(FontAwesome.fa_play_circle, SetInfo.OnlineInfo?.PlayCount ?? 0)
{
Margin = new MarginPadding { Right = 1 },
},
new Statistic(FontAwesome.fa_heart, SetInfo.Beatmaps.FirstOrDefault()?.OnlineInfo.FavouriteCount ?? 0),
new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0),
new FillFlowContainer
{
Anchor = Anchor.TopRight,

View File

@ -2,8 +2,8 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using System.Linq;
using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@ -34,21 +34,25 @@ namespace osu.Game.Overlays.Direct
return icons;
}
protected Drawable GetBackground(TextureStore textures)
protected Drawable CreateBackground() => new DelayedLoadWrapper(new BeatmapSetBackgroundSprite(SetInfo)
{
return new AsyncLoadWrapper(new BeatmapBackgroundSprite(new OnlineWorkingBeatmap(SetInfo.Beatmaps.FirstOrDefault(), textures, null))
{
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fill,
OnLoadComplete = d => d.FadeInFromZero(400, EasingTypes.Out),
}) { RelativeSizeAxes = Axes.Both };
}
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fill,
OnLoadComplete = d => d.FadeInFromZero(400, EasingTypes.Out),
})
{
RelativeSizeAxes = Axes.Both,
TimeBeforeLoad = 300
};
public class Statistic : FillFlowContainer
{
private readonly SpriteText text;
private int value;
public int Value
{
get { return value; }
@ -85,5 +89,23 @@ namespace osu.Game.Overlays.Direct
Value = value;
}
}
private class BeatmapSetBackgroundSprite : Sprite
{
private readonly BeatmapSetInfo set;
public BeatmapSetBackgroundSprite(BeatmapSetInfo set)
{
this.set = set;
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
string resource = set.OnlineInfo.Covers.Card;
if (resource != null)
Texture = textures.Get(resource);
}
}
}
}

View File

@ -14,12 +14,13 @@ using osu.Game.Overlays.SearchableList;
namespace osu.Game.Overlays.Direct
{
public class FilterControl : SearchableListFilterControl<DirectSortCritera, RankStatus>
public class FilterControl : SearchableListFilterControl<DirectSortCriteria, RankStatus>
{
public readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
private FillFlowContainer<RulesetToggleButton> modeButtons;
protected override Color4 BackgroundColour => OsuColour.FromHex(@"384552");
protected override DirectSortCritera DefaultTab => DirectSortCritera.Title;
protected override DirectSortCriteria DefaultTab => DirectSortCriteria.Ranked;
protected override Drawable CreateSupplementaryControls()
{
modeButtons = new FillFlowContainer<RulesetToggleButton>
@ -36,10 +37,10 @@ namespace osu.Game.Overlays.Direct
{
DisplayStyleControl.Dropdown.AccentColour = colours.BlueDark;
var b = new Bindable<RulesetInfo>(); //backup bindable incase the game is null
Ruleset.BindTo(game?.Ruleset ?? new Bindable<RulesetInfo>() { Value = rulesets.GetRuleset(0) });
foreach (var r in rulesets.AllRulesets)
{
modeButtons.Add(new RulesetToggleButton(game?.Ruleset ?? b, r));
modeButtons.Add(new RulesetToggleButton(Ruleset, r));
}
}
@ -95,7 +96,7 @@ namespace osu.Game.Overlays.Direct
}
}
public enum DirectSortCritera
public enum DirectSortCriteria
{
Title,
Artist,
@ -103,5 +104,6 @@ namespace osu.Game.Overlays.Direct
Difficulty,
Ranked,
Rating,
Plays,
}
}

View File

@ -30,10 +30,10 @@ namespace osu.Game.Overlays.Direct
{
Search,
[Description("Newest Maps")]
NewestMaps,
NewestMaps = DirectSortCriteria.Ranked,
[Description("Top Rated")]
TopRated,
TopRated = DirectSortCriteria.Rating,
[Description("Most Played")]
MostPlayed
MostPlayed = DirectSortCriteria.Plays,
}
}

View File

@ -5,21 +5,28 @@ using System.Collections.Generic;
using System.Linq;
using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Threading;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Overlays.Direct;
using osu.Game.Overlays.SearchableList;
using OpenTK.Graphics;
namespace osu.Game.Overlays
{
public class DirectOverlay : SearchableListOverlay<DirectTab, DirectSortCritera, RankStatus>
public class DirectOverlay : SearchableListOverlay<DirectTab, DirectSortCriteria, RankStatus>
{
private const float panel_padding = 10f;
private APIAccess api;
private RulesetDatabase rulesets;
private readonly FillFlowContainer resultCountsContainer;
private readonly OsuSpriteText resultCountsText;
private readonly FillFlowContainer<DirectPanel> panels;
@ -29,7 +36,7 @@ namespace osu.Game.Overlays
protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"3f5265");
protected override SearchableListHeader<DirectTab> CreateHeader() => new Header();
protected override SearchableListFilterControl<DirectSortCritera, RankStatus> CreateFilterControl() => new FilterControl();
protected override SearchableListFilterControl<DirectSortCriteria, RankStatus> CreateFilterControl() => new FilterControl();
private IEnumerable<BeatmapSetInfo> beatmapSets;
public IEnumerable<BeatmapSetInfo> BeatmapSets
@ -40,6 +47,17 @@ namespace osu.Game.Overlays
if (beatmapSets?.Equals(value) ?? false) return;
beatmapSets = value;
if (BeatmapSets == null)
{
foreach (var p in panels.Children)
{
p.FadeOut(200);
p.Expire();
}
return;
}
recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value);
}
}
@ -98,22 +116,60 @@ namespace osu.Game.Overlays
},
};
Header.Tabs.Current.ValueChanged += tab => { if (tab != DirectTab.Search) Filter.Search.Text = string.Empty; };
Filter.Search.Current.ValueChanged += text => { if (text != string.Empty) Header.Tabs.Current.Value = DirectTab.Search; };
((FilterControl)Filter).Ruleset.ValueChanged += ruleset => Scheduler.AddOnce(updateSearch);
Filter.DisplayStyleControl.DisplayStyle.ValueChanged += recreatePanels;
Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += rankStatus => Scheduler.AddOnce(updateSearch);
Header.Tabs.Current.ValueChanged += tab =>
{
if (tab != DirectTab.Search)
{
currentQuery.Value = string.Empty;
Filter.Tabs.Current.Value = (DirectSortCriteria)Header.Tabs.Current.Value;
Scheduler.AddOnce(updateSearch);
}
};
currentQuery.ValueChanged += v =>
{
queryChangedDebounce?.Cancel();
if (string.IsNullOrEmpty(v))
Scheduler.AddOnce(updateSearch);
else
{
BeatmapSets = null;
ResultAmounts = null;
queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500);
}
};
currentQuery.BindTo(Filter.Search.Current);
Filter.Tabs.Current.ValueChanged += sortCriteria =>
{
if (Header.Tabs.Current.Value != DirectTab.Search && sortCriteria != (DirectSortCriteria)Header.Tabs.Current.Value)
Header.Tabs.Current.Value = DirectTab.Search;
Scheduler.AddOnce(updateSearch);
};
updateResultCounts();
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OsuColour colours, APIAccess api, RulesetDatabase rulesets)
{
this.api = api;
this.rulesets = rulesets;
resultCountsContainer.Colour = colours.Yellow;
}
private void updateResultCounts()
{
resultCountsContainer.FadeTo(ResultAmounts == null ? 0f : 1f, 200, EasingTypes.Out);
resultCountsContainer.FadeTo(ResultAmounts == null ? 0f : 1f, 200, EasingTypes.OutQuint);
if (ResultAmounts == null) return;
resultCountsText.Text = pluralize("Artist", ResultAmounts.Artists) + ", " +
@ -129,9 +185,68 @@ namespace osu.Game.Overlays
private void recreatePanels(PanelDisplayStyle displayStyle)
{
if (BeatmapSets == null) return;
panels.ChildrenEnumerable = BeatmapSets.Select(b => displayStyle == PanelDisplayStyle.Grid ? (DirectPanel)new DirectGridPanel(b) { Width = 400 } : new DirectListPanel(b));
panels.ChildrenEnumerable = BeatmapSets.Select<BeatmapSetInfo, DirectPanel>(b =>
{
switch (displayStyle)
{
case PanelDisplayStyle.Grid:
return new DirectGridPanel(b) { Width = 400 };
default:
return new DirectListPanel(b);
}
});
}
private GetBeatmapSetsRequest getSetsRequest;
private readonly Bindable<string> currentQuery = new Bindable<string>();
private ScheduledDelegate queryChangedDebounce;
private void updateSearch()
{
queryChangedDebounce?.Cancel();
if (!IsLoaded) return;
BeatmapSets = null;
ResultAmounts = null;
getSetsRequest?.Cancel();
if (api == null) return;
if (Header.Tabs.Current.Value == DirectTab.Search && (Filter.Search.Text == string.Empty || currentQuery == string.Empty)) return;
getSetsRequest = new GetBeatmapSetsRequest(currentQuery,
((FilterControl)Filter).Ruleset.Value,
Filter.DisplayStyleControl.Dropdown.Current.Value,
Filter.Tabs.Current.Value); //todo: sort direction (?)
getSetsRequest.Success += r =>
{
BeatmapSets = r?.Select(response => response.ToBeatmapSet(rulesets));
if (BeatmapSets == null) return;
var artists = new List<string>();
var songs = new List<string>();
var tags = new List<string>();
foreach (var s in BeatmapSets)
{
artists.Add(s.Metadata.Artist);
songs.Add(s.Metadata.Title);
tags.AddRange(s.Metadata.Tags.Split(' '));
}
ResultAmounts = new ResultCounts(distinctCount(artists), distinctCount(songs), distinctCount(tags));
};
api.Queue(getSetsRequest);
}
private int distinctCount(List<string> list) => list.Distinct().ToArray().Length;
public class ResultCounts
{
public readonly int Artists;

View File

@ -199,7 +199,7 @@ namespace osu.Game.Overlays.Mods
iconsContainer.Clear();
if (Mods.Length > 1)
{
iconsContainer.Add(new[]
iconsContainer.AddRange(new[]
{
backgroundIcon = new ModIcon(Mods[1])
{

View File

@ -49,7 +49,7 @@ namespace osu.Game.Overlays.Notifications
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
AddInternal(new Drawable[]
AddRangeInternal(new Drawable[]
{
Light = new NotificationLight
{

View File

@ -69,7 +69,7 @@ namespace osu.Game.Overlays.Notifications
Left = 20,
};
AddInternal(new Drawable[]
AddRangeInternal(new Drawable[]
{
new Container
{

View File

@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Notifications
public SimpleNotification()
{
IconContent.Add(new Drawable[]
IconContent.AddRange(new Drawable[]
{
IconBackgound = new Box
{

View File

@ -380,15 +380,15 @@ namespace osu.Game.Overlays.Profile
scoreText.Add(createScoreText("Replay Watched by Others"));
scoreNumberText.Add(createScoreNumberText(user.Statistics.ReplayWatched.ToString(@"#,0")));
gradeSS.Count = user.Statistics.GradesCount.SS;
gradeSS.DisplayCount = user.Statistics.GradesCount.SS;
gradeSS.Show();
gradeS.Count = user.Statistics.GradesCount.S;
gradeS.DisplayCount = user.Statistics.GradesCount.S;
gradeS.Show();
gradeA.Count = user.Statistics.GradesCount.A;
gradeA.DisplayCount = user.Statistics.GradesCount.A;
gradeA.Show();
gradeSPlus.Count = 0;
gradeSSPlus.Count = 0;
gradeSPlus.DisplayCount = 0;
gradeSSPlus.DisplayCount = 0;
chartContainer.Add(new RankChart(user) { RelativeSizeAxes = Axes.Both });
}
@ -426,7 +426,7 @@ namespace osu.Game.Overlays.Profile
private readonly Sprite badge;
private readonly SpriteText numberText;
public int Count
public int DisplayCount
{
set
{

View File

@ -120,6 +120,7 @@ namespace osu.Game.Overlays.SearchableList
{
protected override Color4 BackgroundUnfocused => backgroundColour;
protected override Color4 BackgroundFocused => backgroundColour;
protected override bool AllowCommit => true;
private Color4 backgroundColour;

View File

@ -34,7 +34,7 @@ namespace osu.Game.Overlays.SearchableList
{
public SlimMenu()
{
Background.Colour = Color4.Black.Opacity(0.25f);
Background.Colour = Color4.Black.Opacity(0.7f);
}
}
}

View File

@ -44,7 +44,7 @@ namespace osu.Game.Overlays.Settings
const int header_size = 26;
const int header_margin = 25;
const int border_size = 2;
AddInternal(new Drawable[]
AddRangeInternal(new Drawable[]
{
new Box
{

View File

@ -33,7 +33,7 @@ namespace osu.Game.Overlays.Settings
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Direction = FillDirection.Vertical;
AddInternal(new Drawable[]
AddRangeInternal(new Drawable[]
{
new OsuSpriteText
{