From 4c2d7bf343999b55213b8d8900b62aee79d56276 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sun, 13 Aug 2017 17:41:13 +0200 Subject: [PATCH 01/93] Parse the mods of a leaderboard's score --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 18 +++++++++ osu.Game.Rulesets.Mania/ManiaRuleset.cs | 30 +++++++++++++++ osu.Game.Rulesets.Mania/Mods/ManiaMod.cs | 4 ++ .../Mods/ManiaModGravity.cs | 1 + osu.Game.Rulesets.Osu/Mods/OsuMod.cs | 3 ++ osu.Game.Rulesets.Osu/OsuRuleset.cs | 21 ++++++++++ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 18 +++++++++ osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 + osu.Game/Rulesets/Mods/Mod.cs | 5 +++ osu.Game/Rulesets/Mods/ModAutoplay.cs | 1 + osu.Game/Rulesets/Mods/ModCinema.cs | 1 + osu.Game/Rulesets/Mods/ModDaycore.cs | 1 + osu.Game/Rulesets/Mods/ModDoubleTime.cs | 1 + osu.Game/Rulesets/Mods/ModEasy.cs | 1 + osu.Game/Rulesets/Mods/ModFlashlight.cs | 1 + osu.Game/Rulesets/Mods/ModHalfTime.cs | 1 + osu.Game/Rulesets/Mods/ModHardRock.cs | 1 + osu.Game/Rulesets/Mods/ModHidden.cs | 1 + osu.Game/Rulesets/Mods/ModNightcore.cs | 1 + osu.Game/Rulesets/Mods/ModNoFail.cs | 1 + osu.Game/Rulesets/Mods/ModPerfect.cs | 1 + osu.Game/Rulesets/Mods/ModRelax.cs | 1 + osu.Game/Rulesets/Mods/ModSuddenDeath.cs | 1 + osu.Game/Rulesets/Mods/MultiMod.cs | 1 + osu.Game/Rulesets/Ruleset.cs | 15 +++++++- osu.Game/Rulesets/Scoring/Score.cs | 38 ++++++++++++++++++- .../Select/Leaderboards/Leaderboard.cs | 6 ++- .../Select/Leaderboards/LeaderboardScore.cs | 19 +++++++++- 28 files changed, 188 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 8d45ea8fa2..69f22f7121 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -20,6 +20,24 @@ namespace osu.Game.Rulesets.Catch { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new CatchRulesetContainer(this, beatmap, isForCurrentRuleset); + public override IEnumerable GetAllMods() => new Mod[] + { + new CatchModEasy(), + new CatchModNoFail(), + new CatchModHalfTime(), + new CatchModDaycore(), + new CatchModHardRock(), + new CatchModSuddenDeath(), + new CatchModPerfect(), + new CatchModDoubleTime(), + new CatchModNightcore(), + new CatchModHidden(), + new CatchModFlashlight(), + new CatchModRelax(), + new ModAutoplay(), + new ModCinema() + }; + public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 50ad6960ae..3a7c072604 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -19,6 +19,36 @@ namespace osu.Game.Rulesets.Mania { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new ManiaRulesetContainer(this, beatmap, isForCurrentRuleset); + public override IEnumerable GetAllMods() => new Mod[] + { + new ManiaModEasy(), + new ManiaModNoFail(), + new ManiaModHalfTime(), + new ManiaModDaycore(), + new ManiaModHardRock(), + new ManiaModSuddenDeath(), + new ManiaModPerfect(), + new ManiaModDoubleTime(), + new ManiaModNightcore(), + new ManiaModFadeIn(), + new ManiaModHidden(), + new ManiaModFlashlight(), + new ManiaModKey4(), + new ManiaModKey5(), + new ManiaModKey6(), + new ManiaModKey7(), + new ManiaModKey8(), + new ManiaModKey9(), + new ManiaModKey1(), + new ManiaModKey2(), + new ManiaModKey3(), + new ManiaModRandom(), + new ManiaModKeyCoop(), + new ModAutoplay(), + new ModCinema(), + new ManiaModGravity() + }; + public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs index f44ad6fd60..12aa9b0886 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs @@ -68,6 +68,7 @@ namespace osu.Game.Rulesets.Mania.Mods public class ManiaModFadeIn : Mod { public override string Name => "FadeIn"; + public override string ShortenedName => "FI"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden; public override ModType Type => ModType.DifficultyIncrease; public override double ScoreMultiplier => 1; @@ -78,12 +79,14 @@ namespace osu.Game.Rulesets.Mania.Mods public class ManiaModRandom : Mod { public override string Name => "Random"; + public override string ShortenedName => "RD"; public override string Description => @"Shuffle around the notes!"; public override double ScoreMultiplier => 1; } public abstract class ManiaKeyMod : Mod { + public override string ShortenedName => Name; public abstract int KeyCount { get; } public override double ScoreMultiplier => 1; // TODO: Implement the mania key mod score multiplier public override bool Ranked => true; @@ -146,6 +149,7 @@ namespace osu.Game.Rulesets.Mania.Mods public class ManiaModKeyCoop : Mod { public override string Name => "KeyCoop"; + public override string ShortenedName => "CO"; public override string Description => @"Double the key amount, double the fun!"; public override double ScoreMultiplier => 1; public override bool Ranked => true; diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs index a054e0db56..132c49ab31 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs @@ -15,6 +15,7 @@ namespace osu.Game.Rulesets.Mania.Mods public class ManiaModGravity : Mod, IGenerateSpeedAdjustments { public override string Name => "Gravity"; + public override string ShortenedName => "GR"; public override double ScoreMultiplier => 0; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs index 3b0cfc1ef1..649e6cfb3c 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs @@ -78,6 +78,7 @@ namespace osu.Game.Rulesets.Osu.Mods public class OsuModSpunOut : Mod { public override string Name => "Spun Out"; + public override string ShortenedName => "SO"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_spunout; public override string Description => @"Spinners will be automatically completed"; public override double ScoreMultiplier => 0.9; @@ -88,6 +89,7 @@ namespace osu.Game.Rulesets.Osu.Mods public class OsuModAutopilot : Mod { public override string Name => "Autopilot"; + public override string ShortenedName => "AP"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_autopilot; public override string Description => @"Automatic cursor movement - just follow the rhythm."; public override double ScoreMultiplier => 0; @@ -108,6 +110,7 @@ namespace osu.Game.Rulesets.Osu.Mods public class OsuModTarget : Mod { public override string Name => "Target"; + public override string ShortenedName => "TP"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_target; public override string Description => @""; public override double ScoreMultiplier => 1; diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 212c634aaf..fbcb5e3abf 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -24,6 +24,27 @@ namespace osu.Game.Rulesets.Osu { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new OsuRulesetContainer(this, beatmap, isForCurrentRuleset); + public override IEnumerable GetAllMods() => new Mod[] + { + new OsuModEasy(), + new OsuModNoFail(), + new OsuModHalfTime(), + new OsuModDaycore(), + new OsuModHardRock(), + new OsuModSuddenDeath(), + new OsuModPerfect(), + new OsuModDoubleTime(), + new OsuModNightcore(), + new OsuModHidden(), + new OsuModFlashlight(), + new OsuModRelax(), + new OsuModAutopilot(), + new OsuModSpunOut(), + new OsuModAutoplay(), + new ModCinema(), + new OsuModTarget(), + }; + public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new[] { new BeatmapStatistic diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 4d4bbb7bc5..3e126cec4e 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -20,6 +20,24 @@ namespace osu.Game.Rulesets.Taiko { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new TaikoRulesetContainer(this, beatmap, isForCurrentRuleset); + public override IEnumerable GetAllMods() => new Mod[] + { + new TaikoModEasy(), + new TaikoModNoFail(), + new TaikoModHalfTime(), + new TaikoModDaycore(), + new TaikoModHardRock(), + new TaikoModSuddenDeath(), + new TaikoModPerfect(), + new TaikoModDoubleTime(), + new TaikoModNightcore(), + new TaikoModHidden(), + new TaikoModFlashlight(), + new TaikoModRelax(), + new TaikoModAutoplay(), + new ModCinema() + }; + public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 2fb9a568f8..f807b5828f 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -58,6 +58,8 @@ namespace osu.Game.Beatmaps private class DummyRuleset : Ruleset { + public override IEnumerable GetAllMods() => new Mod[] { }; + public override IEnumerable GetModsFor(ModType type) => new Mod[] { }; public override Mod GetAutoplayMod() => new ModAutoplay(); diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index f54267af29..7b0034863e 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -16,6 +16,11 @@ namespace osu.Game.Rulesets.Mods /// public abstract string Name { get; } + /// + /// The shortened name of this mod. + /// + public abstract string ShortenedName { get; } + /// /// The icon of this mod. /// diff --git a/osu.Game/Rulesets/Mods/ModAutoplay.cs b/osu.Game/Rulesets/Mods/ModAutoplay.cs index ca120e446e..2b10d098f3 100644 --- a/osu.Game/Rulesets/Mods/ModAutoplay.cs +++ b/osu.Game/Rulesets/Mods/ModAutoplay.cs @@ -24,6 +24,7 @@ namespace osu.Game.Rulesets.Mods public class ModAutoplay : Mod { public override string Name => "Autoplay"; + public override string ShortenedName => "AT"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_auto; public override string Description => "Watch a perfect automated play through the song"; public override double ScoreMultiplier => 0; diff --git a/osu.Game/Rulesets/Mods/ModCinema.cs b/osu.Game/Rulesets/Mods/ModCinema.cs index 332bd2c5ac..581fbc5e3a 100644 --- a/osu.Game/Rulesets/Mods/ModCinema.cs +++ b/osu.Game/Rulesets/Mods/ModCinema.cs @@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Mods public class ModCinema : ModAutoplay { public override string Name => "Cinema"; + public override string ShortenedName => "CN"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_cinema; } } \ No newline at end of file diff --git a/osu.Game/Rulesets/Mods/ModDaycore.cs b/osu.Game/Rulesets/Mods/ModDaycore.cs index 3e878d7104..cbad224316 100644 --- a/osu.Game/Rulesets/Mods/ModDaycore.cs +++ b/osu.Game/Rulesets/Mods/ModDaycore.cs @@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModDaycore : ModHalfTime { public override string Name => "Daycore"; + public override string ShortenedName => "DC"; public override FontAwesome Icon => FontAwesome.fa_question; public override string Description => "whoaaaaa"; diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs index 1aab56a9fc..d8aa5ea1d2 100644 --- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs +++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs @@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods public class ModDoubleTime : Mod, IApplicableToClock { public override string Name => "Double Time"; + public override string ShortenedName => "DT"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_doubletime; public override ModType Type => ModType.DifficultyIncrease; public override string Description => "Zoooooooooom"; diff --git a/osu.Game/Rulesets/Mods/ModEasy.cs b/osu.Game/Rulesets/Mods/ModEasy.cs index 075a62b0d7..aaf083fd9e 100644 --- a/osu.Game/Rulesets/Mods/ModEasy.cs +++ b/osu.Game/Rulesets/Mods/ModEasy.cs @@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModEasy : Mod, IApplicableToDifficulty { public override string Name => "Easy"; + public override string ShortenedName => "EZ"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_easy; public override ModType Type => ModType.DifficultyReduction; public override string Description => "Reduces overall difficulty - larger circles, more forgiving HP drain, less accuracy required."; diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index b5ad859172..b7499e624a 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModFlashlight : Mod { public override string Name => "Flashlight"; + public override string ShortenedName => "FL"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_flashlight; public override ModType Type => ModType.DifficultyIncrease; public override string Description => "Restricted view area."; diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs index 14aede0809..a9e49bb4b0 100644 --- a/osu.Game/Rulesets/Mods/ModHalfTime.cs +++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs @@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModHalfTime : Mod, IApplicableToClock { public override string Name => "Half Time"; + public override string ShortenedName => "HT"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_halftime; public override ModType Type => ModType.DifficultyReduction; public override string Description => "Less zoom"; diff --git a/osu.Game/Rulesets/Mods/ModHardRock.cs b/osu.Game/Rulesets/Mods/ModHardRock.cs index f33f46a207..36d82362e3 100644 --- a/osu.Game/Rulesets/Mods/ModHardRock.cs +++ b/osu.Game/Rulesets/Mods/ModHardRock.cs @@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModHardRock : Mod, IApplicableToDifficulty { public override string Name => "Hard Rock"; + public override string ShortenedName => "HR"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_hardrock; public override ModType Type => ModType.DifficultyIncrease; public override string Description => "Everything just got a bit harder..."; diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index 89b9b3b62d..25f6ad024d 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModHidden : Mod { public override string Name => "Hidden"; + public override string ShortenedName => "HD"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden; public override ModType Type => ModType.DifficultyIncrease; public override bool Ranked => true; diff --git a/osu.Game/Rulesets/Mods/ModNightcore.cs b/osu.Game/Rulesets/Mods/ModNightcore.cs index d04643fb8b..5cefd89023 100644 --- a/osu.Game/Rulesets/Mods/ModNightcore.cs +++ b/osu.Game/Rulesets/Mods/ModNightcore.cs @@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModNightcore : ModDoubleTime { public override string Name => "Nightcore"; + public override string ShortenedName => "NC"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_nightcore; public override string Description => "uguuuuuuuu"; diff --git a/osu.Game/Rulesets/Mods/ModNoFail.cs b/osu.Game/Rulesets/Mods/ModNoFail.cs index d41c4e3956..3a3878d77e 100644 --- a/osu.Game/Rulesets/Mods/ModNoFail.cs +++ b/osu.Game/Rulesets/Mods/ModNoFail.cs @@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModNoFail : Mod { public override string Name => "NoFail"; + public override string ShortenedName => "NF"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail; public override ModType Type => ModType.DifficultyReduction; public override string Description => "You can't fail, no matter what."; diff --git a/osu.Game/Rulesets/Mods/ModPerfect.cs b/osu.Game/Rulesets/Mods/ModPerfect.cs index 35217c8305..082370ea5d 100644 --- a/osu.Game/Rulesets/Mods/ModPerfect.cs +++ b/osu.Game/Rulesets/Mods/ModPerfect.cs @@ -6,6 +6,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModPerfect : ModSuddenDeath { public override string Name => "Perfect"; + public override string ShortenedName => "PF"; public override string Description => "SS or quit."; } } \ No newline at end of file diff --git a/osu.Game/Rulesets/Mods/ModRelax.cs b/osu.Game/Rulesets/Mods/ModRelax.cs index 5491f8fc58..a3f38e4ff6 100644 --- a/osu.Game/Rulesets/Mods/ModRelax.cs +++ b/osu.Game/Rulesets/Mods/ModRelax.cs @@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModRelax : Mod { public override string Name => "Relax"; + public override string ShortenedName => "RX"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_relax; public override double ScoreMultiplier => 0; public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModNoFail), typeof(ModSuddenDeath) }; diff --git a/osu.Game/Rulesets/Mods/ModSuddenDeath.cs b/osu.Game/Rulesets/Mods/ModSuddenDeath.cs index 2bf0278046..999cb40f89 100644 --- a/osu.Game/Rulesets/Mods/ModSuddenDeath.cs +++ b/osu.Game/Rulesets/Mods/ModSuddenDeath.cs @@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModSuddenDeath : Mod { public override string Name => "Sudden Death"; + public override string ShortenedName => "SD"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_suddendeath; public override ModType Type => ModType.DifficultyIncrease; public override string Description => "Miss a note and fail."; diff --git a/osu.Game/Rulesets/Mods/MultiMod.cs b/osu.Game/Rulesets/Mods/MultiMod.cs index c5fac250d0..c40d107bda 100644 --- a/osu.Game/Rulesets/Mods/MultiMod.cs +++ b/osu.Game/Rulesets/Mods/MultiMod.cs @@ -6,6 +6,7 @@ namespace osu.Game.Rulesets.Mods public class MultiMod : Mod { public override string Name => string.Empty; + public override string ShortenedName => string.Empty; public override string Description => string.Empty; public override double ScoreMultiplier => 0.0; diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index ba040403ba..b6bcd48562 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -1,12 +1,12 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; using osu.Game.Screens.Play; -using System.Collections.Generic; using osu.Framework.Graphics; using osu.Game.Rulesets.Scoring; using osu.Game.Overlays.Settings; @@ -19,8 +19,21 @@ namespace osu.Game.Rulesets public virtual IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new BeatmapStatistic[] { }; + public abstract IEnumerable GetAllMods(); + public abstract IEnumerable GetModsFor(ModType type); + public Mod GetModByShortenedName(string shortenedName) + { + foreach(Mod mod in GetAllMods()) + { + if (string.Equals(mod.ShortenedName, shortenedName)) + return mod; + } + + return null; + } + public abstract Mod GetAutoplayMod(); protected Ruleset(RulesetInfo rulesetInfo) diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index 6169bb7380..8377b95cb2 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Reflection; using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; @@ -27,10 +28,31 @@ namespace osu.Game.Rulesets.Scoring public int Combo { get; set; } + private string[] modStrings; [JsonProperty(@"mods")] - protected string[] ModStrings { get; set; } //todo: parse to Mod objects + protected string[] ModStrings { + get { return modStrings; } + set + { + modStrings = value; - public RulesetInfo Ruleset { get; set; } + if (ruleset != null) + handleModString(); + } + } + + private RulesetInfo ruleset; + public RulesetInfo Ruleset + { + get { return ruleset; } + set + { + ruleset = value; + + if (modStrings != null) + handleModString(); + } + } public Mod[] Mods { get; set; } @@ -80,5 +102,17 @@ namespace osu.Game.Rulesets.Scoring } public Dictionary Statistics = new Dictionary(); + + private void handleModString() + { + List modList = new List(); + + Ruleset rulesetInstance = Ruleset.CreateInstance(); + + foreach (string modShortenedName in modStrings) + modList.Add(rulesetInstance.GetModByShortenedName(modShortenedName)); + + Mods = modList.ToArray(); + } } } diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 5a375e55d4..341e24baf0 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -1,15 +1,15 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Collections.Generic; using OpenTK; using OpenTK.Graphics; +using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; -using System; -using osu.Framework.Allocation; using osu.Framework.Threading; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; @@ -55,6 +55,8 @@ namespace osu.Game.Screens.Select.Leaderboards i = 0; foreach (var s in scores) { + s.Ruleset = beatmap.Ruleset; + var ls = new LeaderboardScore(s, 1 + i) { AlwaysPresent = true, diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs index ac3b0b5c3b..993186ffdf 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs @@ -256,8 +256,23 @@ namespace osu.Game.Screens.Select.Leaderboards { foreach (Mod mod in Score.Mods) { - // TODO: Get actual mod colours - modsContainer.Add(new ScoreModIcon(mod.Icon, OsuColour.FromHex(@"ffcc22"))); + Color4 modColor; + + switch (mod.Type) + { + default: + case ModType.DifficultyIncrease: + modColor = OsuColour.FromHex(@"ffcc22"); + break; + case ModType.DifficultyReduction: + modColor = OsuColour.FromHex(@"88b300"); + break; + case ModType.Special: + modColor = OsuColour.FromHex(@"66ccff"); + break; + } + + modsContainer.Add(new ScoreModIcon(mod.Icon, modColor)); } } } From 997d0c9053c0b7cd641fa7047c0508203dac3744 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sun, 13 Aug 2017 17:45:46 +0200 Subject: [PATCH 02/93] CI fix --- osu.Game/Rulesets/Scoring/Score.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index 8377b95cb2..0200e883ba 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Reflection; using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; From e1e4eb78e324b972241d3ae57161f3da631f23aa Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sun, 13 Aug 2017 18:00:53 +0200 Subject: [PATCH 03/93] Fix nullref in the leaderboard's test case --- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 341e24baf0..740dc90586 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Select.Leaderboards i = 0; foreach (var s in scores) { - s.Ruleset = beatmap.Ruleset; + s.Ruleset = beatmap?.Ruleset; var ls = new LeaderboardScore(s, 1 + i) { From d9c26f98c7d132a8109f37174cfcbc791b7ac9ab Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sun, 13 Aug 2017 19:54:07 +0200 Subject: [PATCH 04/93] Suggested changes --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 18 ----- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 30 --------- osu.Game.Rulesets.Osu/OsuRuleset.cs | 21 ------ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 18 ----- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 - osu.Game/Rulesets/Ruleset.cs | 28 +++++--- osu.Game/Rulesets/Scoring/Score.cs | 10 +-- osu.Game/Rulesets/UI/ModIcon.cs | 6 +- .../Select/Leaderboards/LeaderboardScore.cs | 67 ++++--------------- 9 files changed, 38 insertions(+), 162 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 69f22f7121..8d45ea8fa2 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -20,24 +20,6 @@ namespace osu.Game.Rulesets.Catch { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new CatchRulesetContainer(this, beatmap, isForCurrentRuleset); - public override IEnumerable GetAllMods() => new Mod[] - { - new CatchModEasy(), - new CatchModNoFail(), - new CatchModHalfTime(), - new CatchModDaycore(), - new CatchModHardRock(), - new CatchModSuddenDeath(), - new CatchModPerfect(), - new CatchModDoubleTime(), - new CatchModNightcore(), - new CatchModHidden(), - new CatchModFlashlight(), - new CatchModRelax(), - new ModAutoplay(), - new ModCinema() - }; - public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 3a7c072604..50ad6960ae 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -19,36 +19,6 @@ namespace osu.Game.Rulesets.Mania { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new ManiaRulesetContainer(this, beatmap, isForCurrentRuleset); - public override IEnumerable GetAllMods() => new Mod[] - { - new ManiaModEasy(), - new ManiaModNoFail(), - new ManiaModHalfTime(), - new ManiaModDaycore(), - new ManiaModHardRock(), - new ManiaModSuddenDeath(), - new ManiaModPerfect(), - new ManiaModDoubleTime(), - new ManiaModNightcore(), - new ManiaModFadeIn(), - new ManiaModHidden(), - new ManiaModFlashlight(), - new ManiaModKey4(), - new ManiaModKey5(), - new ManiaModKey6(), - new ManiaModKey7(), - new ManiaModKey8(), - new ManiaModKey9(), - new ManiaModKey1(), - new ManiaModKey2(), - new ManiaModKey3(), - new ManiaModRandom(), - new ManiaModKeyCoop(), - new ModAutoplay(), - new ModCinema(), - new ManiaModGravity() - }; - public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index fbcb5e3abf..212c634aaf 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -24,27 +24,6 @@ namespace osu.Game.Rulesets.Osu { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new OsuRulesetContainer(this, beatmap, isForCurrentRuleset); - public override IEnumerable GetAllMods() => new Mod[] - { - new OsuModEasy(), - new OsuModNoFail(), - new OsuModHalfTime(), - new OsuModDaycore(), - new OsuModHardRock(), - new OsuModSuddenDeath(), - new OsuModPerfect(), - new OsuModDoubleTime(), - new OsuModNightcore(), - new OsuModHidden(), - new OsuModFlashlight(), - new OsuModRelax(), - new OsuModAutopilot(), - new OsuModSpunOut(), - new OsuModAutoplay(), - new ModCinema(), - new OsuModTarget(), - }; - public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new[] { new BeatmapStatistic diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 3e126cec4e..4d4bbb7bc5 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -20,24 +20,6 @@ namespace osu.Game.Rulesets.Taiko { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new TaikoRulesetContainer(this, beatmap, isForCurrentRuleset); - public override IEnumerable GetAllMods() => new Mod[] - { - new TaikoModEasy(), - new TaikoModNoFail(), - new TaikoModHalfTime(), - new TaikoModDaycore(), - new TaikoModHardRock(), - new TaikoModSuddenDeath(), - new TaikoModPerfect(), - new TaikoModDoubleTime(), - new TaikoModNightcore(), - new TaikoModHidden(), - new TaikoModFlashlight(), - new TaikoModRelax(), - new TaikoModAutoplay(), - new ModCinema() - }; - public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index f807b5828f..2fb9a568f8 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -58,8 +58,6 @@ namespace osu.Game.Beatmaps private class DummyRuleset : Ruleset { - public override IEnumerable GetAllMods() => new Mod[] { }; - public override IEnumerable GetModsFor(ModType type) => new Mod[] { }; public override Mod GetAutoplayMod() => new ModAutoplay(); diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index b6bcd48562..56a255eda5 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Linq; using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Graphics; @@ -19,19 +21,29 @@ namespace osu.Game.Rulesets public virtual IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new BeatmapStatistic[] { }; - public abstract IEnumerable GetAllMods(); + public IEnumerable GetAllMods() + { + List modList = new List(); + + foreach (ModType type in Enum.GetValues(typeof(ModType))) + modList.AddRange(GetModsFor(type).SelectMany(mod => + { + var multiMod = mod as MultiMod; + + if (multiMod != null) + return multiMod.Mods; + + return new Mod[] { mod }; + })); + + return modList.ToArray(); + } public abstract IEnumerable GetModsFor(ModType type); public Mod GetModByShortenedName(string shortenedName) { - foreach(Mod mod in GetAllMods()) - { - if (string.Equals(mod.ShortenedName, shortenedName)) - return mod; - } - - return null; + return GetAllMods().First(mod => mod.ShortenedName == shortenedName); } public abstract Mod GetAutoplayMod(); diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index 0200e883ba..b9fe54677d 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Linq; using System.Collections.Generic; using Newtonsoft.Json; using osu.Game.Beatmaps; @@ -104,14 +105,7 @@ namespace osu.Game.Rulesets.Scoring private void handleModString() { - List modList = new List(); - - Ruleset rulesetInstance = Ruleset.CreateInstance(); - - foreach (string modShortenedName in modStrings) - modList.Add(rulesetInstance.GetModByShortenedName(modShortenedName)); - - Mods = modList.ToArray(); + Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); } } } diff --git a/osu.Game/Rulesets/UI/ModIcon.cs b/osu.Game/Rulesets/UI/ModIcon.cs index 986d8c92dc..47a39d4644 100644 --- a/osu.Game/Rulesets/UI/ModIcon.cs +++ b/osu.Game/Rulesets/UI/ModIcon.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.UI private readonly SpriteIcon modIcon; private readonly SpriteIcon background; - private const float icon_size = 80; + private const float background_size = 80; public FontAwesome Icon { @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.UI { Origin = Anchor.Centre, Anchor = Anchor.Centre, - Size = new Vector2(icon_size), + Size = new Vector2(background_size), Icon = FontAwesome.fa_osu_mod_bg, Shadow = true, }, @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.UI Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Colour = OsuColour.Gray(84), - Size = new Vector2(icon_size - 35), + Size = new Vector2(background_size - 35), Y = 25, Icon = mod.Icon }, diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs index 993186ffdf..fcd87363d6 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs @@ -3,17 +3,18 @@ using OpenTK; using OpenTK.Graphics; +using osu.Framework; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Framework.Extensions.Color4Extensions; -using osu.Game.Rulesets.Mods; -using osu.Game.Users; -using osu.Framework; -using osu.Game.Rulesets.Scoring; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; +using osu.Game.Users; namespace osu.Game.Screens.Select.Leaderboards { @@ -38,7 +39,7 @@ namespace osu.Game.Screens.Select.Leaderboards private readonly ScoreComponentLabel maxCombo; private readonly ScoreComponentLabel accuracy; private readonly Container flagBadgeContainer; - private readonly FillFlowContainer modsContainer; + private readonly FillFlowContainer modsContainer; private Visibility state; public Visibility State @@ -239,7 +240,7 @@ namespace osu.Game.Screens.Select.Leaderboards }, }, }, - modsContainer = new FillFlowContainer + modsContainer = new FillFlowContainer { Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, @@ -256,23 +257,11 @@ namespace osu.Game.Screens.Select.Leaderboards { foreach (Mod mod in Score.Mods) { - Color4 modColor; - - switch (mod.Type) + modsContainer.Add(new ModIcon(mod) { - default: - case ModType.DifficultyIncrease: - modColor = OsuColour.FromHex(@"ffcc22"); - break; - case ModType.DifficultyReduction: - modColor = OsuColour.FromHex(@"88b300"); - break; - case ModType.Special: - modColor = OsuColour.FromHex(@"66ccff"); - break; - } - - modsContainer.Add(new ScoreModIcon(mod.Icon, modColor)); + AutoSizeAxes = Axes.Both, + Scale = new Vector2(0.375f) + }); } } } @@ -341,36 +330,6 @@ namespace osu.Game.Screens.Select.Leaderboards } } - private class ScoreModIcon : Container - { - public ScoreModIcon(FontAwesome icon, Color4 colour) - { - AutoSizeAxes = Axes.Both; - - Children = new[] - { - new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Icon = FontAwesome.fa_osu_mod_bg, - Colour = colour, - Shadow = true, - Size = new Vector2(30), - }, - new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Icon = icon, - Colour = OsuColour.Gray(84), - Size = new Vector2(18), - Position = new Vector2(0f, 2f), - }, - }; - } - } - private class ScoreComponentLabel : Container { public ScoreComponentLabel(FontAwesome icon, string value) From 81289db33b3a9f9d219ce930359e78222cdc234d Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sun, 13 Aug 2017 20:12:01 +0200 Subject: [PATCH 05/93] CI fix, fixed nullref and removed abstraction of GetAutoplayMod --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 -- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 -- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 -- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 -- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 -- osu.Game/Rulesets/Ruleset.cs | 6 +++--- 6 files changed, 3 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 8d45ea8fa2..a5c9cf67b3 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -84,8 +84,6 @@ namespace osu.Game.Rulesets.Catch } } - public override Mod GetAutoplayMod() => new ModAutoplay(); - public override string Description => "osu!catch"; public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o }; diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 50ad6960ae..90732df1f2 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -105,8 +105,6 @@ namespace osu.Game.Rulesets.Mania } } - public override Mod GetAutoplayMod() => new ModAutoplay(); - public override string Description => "osu!mania"; public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o }; diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 212c634aaf..92cfbf8afa 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -105,8 +105,6 @@ namespace osu.Game.Rulesets.Osu } } - public override Mod GetAutoplayMod() => new OsuModAutoplay(); - public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_osu_o }; public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new OsuDifficultyCalculator(beatmap); diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 4d4bbb7bc5..7fa053161d 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -84,8 +84,6 @@ namespace osu.Game.Rulesets.Taiko } } - public override Mod GetAutoplayMod() => new TaikoModAutoplay(); - public override string Description => "osu!taiko"; public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o }; diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 2fb9a568f8..22ad4f38ff 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -60,8 +60,6 @@ namespace osu.Game.Beatmaps { public override IEnumerable GetModsFor(ModType type) => new Mod[] { }; - public override Mod GetAutoplayMod() => new ModAutoplay(); - public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) { throw new NotImplementedException(); diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 56a255eda5..46ab53a7d2 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -26,14 +26,14 @@ namespace osu.Game.Rulesets List modList = new List(); foreach (ModType type in Enum.GetValues(typeof(ModType))) - modList.AddRange(GetModsFor(type).SelectMany(mod => + modList.AddRange(GetModsFor(type).Where(mod => mod != null).SelectMany(mod => { var multiMod = mod as MultiMod; if (multiMod != null) return multiMod.Mods; - return new Mod[] { mod }; + return new[] { mod }; })); return modList.ToArray(); @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets return GetAllMods().First(mod => mod.ShortenedName == shortenedName); } - public abstract Mod GetAutoplayMod(); + public Mod GetAutoplayMod() => GetAllMods().First(mod => mod is ModAutoplay); protected Ruleset(RulesetInfo rulesetInfo) { From 2f89fc432b3ed495a239170b2261aac6b3470a10 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sun, 13 Aug 2017 20:28:30 +0200 Subject: [PATCH 06/93] Removed unused function --- osu.Game/Rulesets/Ruleset.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 46ab53a7d2..cd4480bbb9 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -41,11 +41,6 @@ namespace osu.Game.Rulesets public abstract IEnumerable GetModsFor(ModType type); - public Mod GetModByShortenedName(string shortenedName) - { - return GetAllMods().First(mod => mod.ShortenedName == shortenedName); - } - public Mod GetAutoplayMod() => GetAllMods().First(mod => mod is ModAutoplay); protected Ruleset(RulesetInfo rulesetInfo) From e54f659916c4a897fb2ca5e51f13805923a1bb9e Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sun, 13 Aug 2017 22:37:39 +0200 Subject: [PATCH 07/93] Suggested changes --- osu.Game.Rulesets.Mania/Mods/ManiaMod.cs | 2 +- osu.Game/Rulesets/Ruleset.cs | 2 +- osu.Game/Rulesets/Scoring/Score.cs | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs index 12aa9b0886..bb11a05fc8 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs @@ -149,7 +149,7 @@ namespace osu.Game.Rulesets.Mania.Mods public class ManiaModKeyCoop : Mod { public override string Name => "KeyCoop"; - public override string ShortenedName => "CO"; + public override string ShortenedName => "2P"; public override string Description => @"Double the key amount, double the fun!"; public override double ScoreMultiplier => 1; public override bool Ranked => true; diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index cd4480bbb9..bb08850af9 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets return new[] { mod }; })); - return modList.ToArray(); + return modList; } public abstract IEnumerable GetModsFor(ModType type); diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index b9fe54677d..399a805bcc 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -30,7 +30,8 @@ namespace osu.Game.Rulesets.Scoring private string[] modStrings; [JsonProperty(@"mods")] - protected string[] ModStrings { + protected string[] ModStrings + { get { return modStrings; } set { From 6b1184e8aff6f4de5fabe58a430595e0e1e19b02 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 14 Aug 2017 00:27:54 +0200 Subject: [PATCH 08/93] General formatting --- .../Select/Leaderboards/LeaderboardScore.cs | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs index fcd87363d6..2971600a74 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs @@ -8,6 +8,7 @@ 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.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -253,16 +254,13 @@ namespace osu.Game.Screens.Select.Leaderboards }, }; - if (Score.Mods != null) + foreach (Mod mod in Score.Mods) { - foreach (Mod mod in Score.Mods) + modsContainer.Add(new ModIcon(mod) { - modsContainer.Add(new ModIcon(mod) - { - AutoSizeAxes = Axes.Both, - Scale = new Vector2(0.375f) - }); - } + AutoSizeAxes = Axes.Both, + Scale = new Vector2(0.375f) + }); } } @@ -271,13 +269,13 @@ namespace osu.Game.Screens.Select.Leaderboards public override void Hide() => State = Visibility.Hidden; public override void Show() => State = Visibility.Visible; - protected override bool OnHover(Framework.Input.InputState state) + protected override bool OnHover(InputState state) { background.FadeTo(0.5f, 300, Easing.OutQuint); return base.OnHover(state); } - protected override void OnHoverLost(Framework.Input.InputState state) + protected override void OnHoverLost(InputState state) { background.FadeTo(background_alpha, 200, Easing.OutQuint); base.OnHoverLost(state); @@ -307,8 +305,8 @@ namespace osu.Game.Screens.Select.Leaderboards Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = font, - TextSize = textSize, FixedWidth = true, + TextSize = textSize, Text = text, Colour = glowColour, Shadow = false, From 718eefa362e326efdb07331d2a6a2e7c52d53e1f Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 14 Aug 2017 01:16:19 +0200 Subject: [PATCH 09/93] Fixed wrong test case accuracy format --- .../Visual/TestCaseLeaderboard.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs b/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs index 5f8ee8795c..2386881d24 100644 --- a/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs +++ b/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs @@ -24,7 +24,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.XH, - Accuracy = 100, + Accuracy = 1, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -42,7 +42,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.X, - Accuracy = 100, + Accuracy = 1, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -60,7 +60,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.SH, - Accuracy = 100, + Accuracy = 1, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -78,7 +78,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.S, - Accuracy = 100, + Accuracy = 1, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -96,7 +96,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.A, - Accuracy = 100, + Accuracy = 1, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -114,7 +114,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.B, - Accuracy = 98.26, + Accuracy = 0.9826, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -132,7 +132,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.C, - Accuracy = 96.54, + Accuracy = 0.9654, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -150,7 +150,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.F, - Accuracy = 60.25, + Accuracy = 0.6025, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -168,7 +168,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.F, - Accuracy = 51.40, + Accuracy = 0.5140, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -186,7 +186,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.F, - Accuracy = 42.22, + Accuracy = 0.4222, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, From 2ae3ce8b91e03e201efbb88cb13a862830d3d148 Mon Sep 17 00:00:00 2001 From: naoey Date: Thu, 3 Aug 2017 20:55:52 +0530 Subject: [PATCH 10/93] Add ability to close chat tabs. --- osu.Game/Overlays/Chat/ChatTabControl.cs | 45 +++++++++++++++++++++--- osu.Game/Overlays/ChatOverlay.cs | 12 +++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index 4ff9169877..b44d50e936 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -16,15 +16,16 @@ using osu.Game.Online.Chat; using OpenTK; using OpenTK.Graphics; using osu.Framework.Configuration; +using System; namespace osu.Game.Overlays.Chat { public class ChatTabControl : OsuTabControl { - protected override TabItem CreateTabItem(Channel value) => new ChannelTabItem(value); - private const float shear_width = 10; + public Action OnRequestLeave; + public readonly Bindable ChannelSelectorActive = new Bindable(); private readonly ChannelTabItem.ChannelSelectorTabItem selectorTab; @@ -49,6 +50,14 @@ namespace osu.Game.Overlays.Chat ChannelSelectorActive.BindTo(selectorTab.Active); } + protected override TabItem CreateTabItem(Channel value) + { + ChannelTabItem tab = new ChannelTabItem(value); + tab.OnRequestClose = () => OnRequestLeave?.Invoke(value); + + return tab; + } + protected override void SelectTab(TabItem tab) { if (tab is ChannelTabItem.ChannelSelectorTabItem) @@ -68,12 +77,17 @@ namespace osu.Game.Overlays.Chat private Color4 backgroundHover; private Color4 backgroundActive; + protected override bool isClosable => !Pinned; + private readonly SpriteText text; private readonly SpriteText textBold; + private readonly Button closeButton; private readonly Box box; private readonly Box highlightBox; private readonly SpriteIcon icon; + public Action OnRequestClose; + private void updateState() { if (Active) @@ -88,6 +102,7 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1.1f), transition_length, Easing.OutQuint); + closeButton?.MoveToX(-5f, 0.5f, EasingTypes.OutElastic); box.FadeColour(backgroundActive, transition_length, Easing.OutQuint); highlightBox.FadeIn(transition_length, Easing.OutQuint); @@ -99,6 +114,7 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1), transition_length, Easing.OutQuint); + closeButton?.MoveToX(5f, 0.5f, EasingTypes.InElastic); box.FadeColour(backgroundInactive, transition_length, Easing.OutQuint); highlightBox.FadeOut(transition_length, Easing.OutQuint); @@ -108,6 +124,8 @@ namespace osu.Game.Overlays.Chat protected override bool OnHover(InputState state) { + closeButton?.FadeIn(1f, EasingTypes.InBounce); + if (!Active) box.FadeColour(backgroundHover, transition_length, Easing.OutQuint); return true; @@ -115,6 +133,7 @@ namespace osu.Game.Overlays.Chat protected override void OnHoverLost(InputState state) { + closeButton?.FadeOut(1f, EasingTypes.OutBounce); updateState(); } @@ -204,13 +223,31 @@ namespace osu.Game.Overlays.Chat Font = @"Exo2.0-Bold", TextSize = 18, }, - } - } + }, + }, }; + + if (isClosable) + { + Add(closeButton = new Button + { + Alpha = 0, + Width = 20, + Height = 20, + Margin = new MarginPadding { Right = 10 }, + Origin = Anchor.CentreRight, + Anchor = Anchor.CentreRight, + Text = @"x", + BackgroundColour = Color4.Transparent, + Action = () => OnRequestClose?.Invoke(), + }); + } } public class ChannelSelectorTabItem : ChannelTabItem { + protected override bool isClosable => false; + public ChannelSelectorTabItem(Channel value) : base(value) { Depth = float.MaxValue; diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 29b7548ada..cc4177edc6 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -160,6 +160,7 @@ namespace osu.Game.Overlays channelTabs = new ChatTabControl { RelativeSizeAxes = Axes.Both, + OnRequestLeave = removeChannel, }, } }, @@ -305,6 +306,7 @@ namespace osu.Game.Overlays addChannel(channels.Find(c => c.Name == @"#lobby")); channelSelection.OnRequestJoin = addChannel; + channelSelection.OnRequestLeave = removeChannel; channelSelection.Sections = new[] { new ChannelSection @@ -391,6 +393,16 @@ namespace osu.Game.Overlays channel.Joined.Value = true; } + private void removeChannel(Channel channel) + { + if (channel == null) return; + + careChannels.Remove(channel); + channelTabs.RemoveItem(channel); + + channel.Joined.Value = false; + } + private void fetchInitialMessages(Channel channel) { var req = new GetMessagesRequest(new List { channel }, null); From 3b6ffadcc7207c24a081df017d64686752bb9893 Mon Sep 17 00:00:00 2001 From: naoey Date: Thu, 3 Aug 2017 22:02:25 +0530 Subject: [PATCH 11/93] Renaming to match framework changes. - IsClosable -> IsRemovable - EasingTypes -> Easing - Also remove all messages on a channel being un-joined --- osu.Game/Overlays/Chat/ChatTabControl.cs | 14 +++++++------- osu.Game/Overlays/Chat/DrawableChannel.cs | 7 +++++++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index b44d50e936..735a37e334 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -77,7 +77,7 @@ namespace osu.Game.Overlays.Chat private Color4 backgroundHover; private Color4 backgroundActive; - protected override bool isClosable => !Pinned; + protected override bool IsRemovable => !Pinned; private readonly SpriteText text; private readonly SpriteText textBold; @@ -102,7 +102,7 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1.1f), transition_length, Easing.OutQuint); - closeButton?.MoveToX(-5f, 0.5f, EasingTypes.OutElastic); + closeButton?.MoveToX(-5f, 0.5f, Easing.OutElastic); box.FadeColour(backgroundActive, transition_length, Easing.OutQuint); highlightBox.FadeIn(transition_length, Easing.OutQuint); @@ -114,7 +114,7 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1), transition_length, Easing.OutQuint); - closeButton?.MoveToX(5f, 0.5f, EasingTypes.InElastic); + closeButton?.MoveToX(5f, 0.5f, Easing.InElastic); box.FadeColour(backgroundInactive, transition_length, Easing.OutQuint); highlightBox.FadeOut(transition_length, Easing.OutQuint); @@ -124,7 +124,7 @@ namespace osu.Game.Overlays.Chat protected override bool OnHover(InputState state) { - closeButton?.FadeIn(1f, EasingTypes.InBounce); + closeButton?.FadeIn(1f, Easing.InBounce); if (!Active) box.FadeColour(backgroundHover, transition_length, Easing.OutQuint); @@ -133,7 +133,7 @@ namespace osu.Game.Overlays.Chat protected override void OnHoverLost(InputState state) { - closeButton?.FadeOut(1f, EasingTypes.OutBounce); + closeButton?.FadeOut(1f, Easing.OutBounce); updateState(); } @@ -227,7 +227,7 @@ namespace osu.Game.Overlays.Chat }, }; - if (isClosable) + if (IsRemovable) { Add(closeButton = new Button { @@ -246,7 +246,7 @@ namespace osu.Game.Overlays.Chat public class ChannelSelectorTabItem : ChannelTabItem { - protected override bool isClosable => false; + protected override bool IsRemovable => false; public ChannelSelectorTabItem(Channel value) : base(value) { diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 8a2fa95ed1..3736a97981 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -46,6 +46,7 @@ namespace osu.Game.Overlays.Chat }; channel.NewMessagesArrived += newMessagesArrived; + channel.Joined.ValueChanged += channelJoinStatusChanged; } [BackgroundDependencyLoader] @@ -64,6 +65,7 @@ namespace osu.Game.Overlays.Chat { base.Dispose(isDisposing); Channel.NewMessagesArrived -= newMessagesArrived; + Channel.Joined.ValueChanged -= channelJoinStatusChanged; } private void newMessagesArrived(IEnumerable newMessages) @@ -90,6 +92,11 @@ namespace osu.Game.Overlays.Chat } } + private void channelJoinStatusChanged(bool joined) + { + if (!joined) flow.Clear(); + } + private void scrollToEnd() => ScheduleAfterChildren(() => scroll.ScrollToEnd()); } } From 8dbbc623c73e1b3731fcfe4c6e7d870e95691793 Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 5 Aug 2017 10:22:06 +0530 Subject: [PATCH 12/93] Add next tab selection logic in game, make IsRemovable public. - Don't clear DrawableChannel when unjoined --- osu.Game/Overlays/Chat/ChatTabControl.cs | 21 ++++++++++++++++++--- osu.Game/Overlays/Chat/DrawableChannel.cs | 7 ------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index 735a37e334..baa6fb3ab6 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -53,7 +53,7 @@ namespace osu.Game.Overlays.Chat protected override TabItem CreateTabItem(Channel value) { ChannelTabItem tab = new ChannelTabItem(value); - tab.OnRequestClose = () => OnRequestLeave?.Invoke(value); + tab.OnRequestClose = () => onTabClose(tab); return tab; } @@ -71,13 +71,28 @@ namespace osu.Game.Overlays.Chat base.SelectTab(tab); } + private void onTabClose(TabItem tab) + { + int totalTabs = TabContainer.Children.Count - 1; // account for selectorTab + int currentIndex = MathHelper.Clamp(TabContainer.IndexOf(tab), 1, totalTabs); + + if (tab == SelectedTab && totalTabs > 1) + // Select the tab after tab-to-be-removed's index, or the tab before if current == last + SelectTab(TabContainer.Children[currentIndex == totalTabs ? currentIndex - 1 : currentIndex + 1]); + else if (totalTabs == 1 && !selectorTab.Active) + // Open channel selection overlay if all channel tabs will be closed after removing this tab + SelectTab(selectorTab); + + OnRequestLeave?.Invoke(tab.Value); + } + private class ChannelTabItem : TabItem { private Color4 backgroundInactive; private Color4 backgroundHover; private Color4 backgroundActive; - protected override bool IsRemovable => !Pinned; + public override bool IsRemovable => !Pinned; private readonly SpriteText text; private readonly SpriteText textBold; @@ -246,7 +261,7 @@ namespace osu.Game.Overlays.Chat public class ChannelSelectorTabItem : ChannelTabItem { - protected override bool IsRemovable => false; + public override bool IsRemovable => false; public ChannelSelectorTabItem(Channel value) : base(value) { diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 3736a97981..8a2fa95ed1 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -46,7 +46,6 @@ namespace osu.Game.Overlays.Chat }; channel.NewMessagesArrived += newMessagesArrived; - channel.Joined.ValueChanged += channelJoinStatusChanged; } [BackgroundDependencyLoader] @@ -65,7 +64,6 @@ namespace osu.Game.Overlays.Chat { base.Dispose(isDisposing); Channel.NewMessagesArrived -= newMessagesArrived; - Channel.Joined.ValueChanged -= channelJoinStatusChanged; } private void newMessagesArrived(IEnumerable newMessages) @@ -92,11 +90,6 @@ namespace osu.Game.Overlays.Chat } } - private void channelJoinStatusChanged(bool joined) - { - if (!joined) flow.Clear(); - } - private void scrollToEnd() => ScheduleAfterChildren(() => scroll.ScrollToEnd()); } } From 381c709639ec9f3bbac4d93a4b3e1dc962be5b4a Mon Sep 17 00:00:00 2001 From: naoey Date: Fri, 11 Aug 2017 10:10:55 +0530 Subject: [PATCH 13/93] Fix selectorTab Depth if it's wonky when new tabs are added. --- osu.Game/Overlays/Chat/ChatTabControl.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index baa6fb3ab6..ef4760d166 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -50,6 +50,15 @@ namespace osu.Game.Overlays.Chat ChannelSelectorActive.BindTo(selectorTab.Active); } + protected override void AddTabItem(TabItem item, bool addToDropdown = true) + { + if (selectorTab.Depth < float.MaxValue) + // performTabSort might've made selectorTab's position wonky, fix it + TabContainer.ChangeChildDepth(selectorTab, float.MaxValue); + + base.AddTabItem(item, addToDropdown); + } + protected override TabItem CreateTabItem(Channel value) { ChannelTabItem tab = new ChannelTabItem(value); From 920710e7d0b3e37f027becbe059394f8e1345eb2 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 14 Aug 2017 13:30:54 +0200 Subject: [PATCH 14/93] Assign a score's beatmap and cleanup to the Score class --- osu.Game/Rulesets/Scoring/Score.cs | 23 ++++--------------- .../Select/Leaderboards/Leaderboard.cs | 1 + 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index 399a805bcc..15217352d0 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -28,19 +28,8 @@ namespace osu.Game.Rulesets.Scoring public int Combo { get; set; } - private string[] modStrings; [JsonProperty(@"mods")] - protected string[] ModStrings - { - get { return modStrings; } - set - { - modStrings = value; - - if (ruleset != null) - handleModString(); - } - } + protected string[] ModStrings { get; set; } private RulesetInfo ruleset; public RulesetInfo Ruleset @@ -50,8 +39,9 @@ namespace osu.Game.Rulesets.Scoring { ruleset = value; - if (modStrings != null) - handleModString(); + // Handle the mod strings if they are assigned + if (ModStrings != null) + Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => ModStrings.Contains(mod.ShortenedName)).ToArray(); } } @@ -103,10 +93,5 @@ namespace osu.Game.Rulesets.Scoring } public Dictionary Statistics = new Dictionary(); - - private void handleModString() - { - Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); - } } } diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 740dc90586..5ec76a59ac 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -55,6 +55,7 @@ namespace osu.Game.Screens.Select.Leaderboards i = 0; foreach (var s in scores) { + s.Beatmap = beatmap; s.Ruleset = beatmap?.Ruleset; var ls = new LeaderboardScore(s, 1 + i) From 5ed717ef861d15e02a7319127dcc060fd0cad1a3 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 14 Aug 2017 15:16:22 +0200 Subject: [PATCH 15/93] Shortened GetAllMods() using LINQ --- osu.Game/Rulesets/Ruleset.cs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index bb08850af9..af51a2cd3f 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -4,14 +4,14 @@ using System; using System.Linq; using System.Collections.Generic; +using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Screens.Play; -using osu.Framework.Graphics; -using osu.Game.Rulesets.Scoring; -using osu.Game.Overlays.Settings; namespace osu.Game.Rulesets { @@ -23,10 +23,9 @@ namespace osu.Game.Rulesets public IEnumerable GetAllMods() { - List modList = new List(); - - foreach (ModType type in Enum.GetValues(typeof(ModType))) - modList.AddRange(GetModsFor(type).Where(mod => mod != null).SelectMany(mod => + return Enum.GetValues(typeof(ModType)).Cast().SelectMany(type => + { + return GetModsFor(type).Where(mod => mod != null).SelectMany(mod => { var multiMod = mod as MultiMod; @@ -34,9 +33,8 @@ namespace osu.Game.Rulesets return multiMod.Mods; return new[] { mod }; - })); - - return modList; + }); + }); } public abstract IEnumerable GetModsFor(ModType type); From e908a3675ee2ac024abce62243a1261539a1956d Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 14 Aug 2017 18:24:54 +0200 Subject: [PATCH 16/93] Formatted the GetAllMods() function --- osu.Game/Rulesets/Ruleset.cs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index af51a2cd3f..b875dff44f 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -21,21 +21,7 @@ namespace osu.Game.Rulesets public virtual IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new BeatmapStatistic[] { }; - public IEnumerable GetAllMods() - { - return Enum.GetValues(typeof(ModType)).Cast().SelectMany(type => - { - return GetModsFor(type).Where(mod => mod != null).SelectMany(mod => - { - var multiMod = mod as MultiMod; - - if (multiMod != null) - return multiMod.Mods; - - return new[] { mod }; - }); - }); - } + public IEnumerable GetAllMods() => Enum.GetValues(typeof(ModType)).Cast().SelectMany(type => GetModsFor(type).Where(mod => mod != null).SelectMany(mod => (mod as MultiMod)?.Mods ?? new[] { mod })); public abstract IEnumerable GetModsFor(ModType type); From 21ced322976ddf9d0892f2d939858fe782d82d97 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Tue, 15 Aug 2017 12:03:43 +0200 Subject: [PATCH 17/93] Formatted and commented the GetAllMods() function --- osu.Game/Rulesets/Ruleset.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index b875dff44f..65cc6199f0 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -21,7 +21,14 @@ namespace osu.Game.Rulesets public virtual IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new BeatmapStatistic[] { }; - public IEnumerable GetAllMods() => Enum.GetValues(typeof(ModType)).Cast().SelectMany(type => GetModsFor(type).Where(mod => mod != null).SelectMany(mod => (mod as MultiMod)?.Mods ?? new[] { mod })); + public IEnumerable GetAllMods() => Enum.GetValues(typeof(ModType)).Cast() + //Get all mod types as an IEnumerable + .SelectMany(type => GetModsFor(type)) + // Confine all mods of each mod type into a single IEnumerable + .Where(mod => mod != null) + // Filter out all null mods + .SelectMany(mod => (mod as MultiMod)?.Mods ?? new[] { mod }); + // Resolve MultiMods as their .Mods property public abstract IEnumerable GetModsFor(ModType type); From 2c287e13486419e771572fadd682d73d870c2261 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Tue, 15 Aug 2017 12:27:51 +0200 Subject: [PATCH 18/93] CI and comment fix --- osu.Game/Rulesets/Ruleset.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 65cc6199f0..fa12199a58 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -22,8 +22,8 @@ namespace osu.Game.Rulesets public virtual IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new BeatmapStatistic[] { }; public IEnumerable GetAllMods() => Enum.GetValues(typeof(ModType)).Cast() - //Get all mod types as an IEnumerable - .SelectMany(type => GetModsFor(type)) + // Get all mod types as an IEnumerable + .SelectMany(GetModsFor) // Confine all mods of each mod type into a single IEnumerable .Where(mod => mod != null) // Filter out all null mods From 105048500ad9a30f173d04892c5dd56ec28e5cdc Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Tue, 15 Aug 2017 15:30:53 +0200 Subject: [PATCH 19/93] Made modString private and moved the beatmap assignment inside GetScoresRequest --- osu.Game/Online/API/Requests/GetScoresRequest.cs | 11 +++++++++++ osu.Game/Rulesets/Scoring/Score.cs | 6 +++--- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 3 --- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index 966049429e..a902c8c807 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -16,6 +16,17 @@ namespace osu.Game.Online.API.Requests public GetScoresRequest(BeatmapInfo beatmap) { this.beatmap = beatmap; + + Success += onSuccess; + } + + private void onSuccess(GetScoresResponse r) + { + foreach (Score score in r.Scores) + { + score.Beatmap = beatmap; + score.Ruleset = beatmap.Ruleset; + } } protected override WebRequest CreateWebRequest() diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index 15217352d0..e42c3b2df0 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Scoring public int Combo { get; set; } [JsonProperty(@"mods")] - protected string[] ModStrings { get; set; } + private string[] modStrings { get; set; } private RulesetInfo ruleset; public RulesetInfo Ruleset @@ -40,8 +40,8 @@ namespace osu.Game.Rulesets.Scoring ruleset = value; // Handle the mod strings if they are assigned - if (ModStrings != null) - Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => ModStrings.Contains(mod.ShortenedName)).ToArray(); + if (modStrings != null) + Mods = ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); } } diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 5ec76a59ac..0506784614 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -55,9 +55,6 @@ namespace osu.Game.Screens.Select.Leaderboards i = 0; foreach (var s in scores) { - s.Beatmap = beatmap; - s.Ruleset = beatmap?.Ruleset; - var ls = new LeaderboardScore(s, 1 + i) { AlwaysPresent = true, From 4f7ae1ed8b6ecc2bee77d24b269b980031a0a7dc Mon Sep 17 00:00:00 2001 From: naoey Date: Thu, 17 Aug 2017 08:20:44 +0530 Subject: [PATCH 20/93] Clear messages when the current channel is removed. - Stop using TabContainer.Children --- osu.Game/Overlays/Chat/ChatTabControl.cs | 4 ++-- osu.Game/Overlays/ChatOverlay.cs | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index ef4760d166..5f8db6fa71 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -82,12 +82,12 @@ namespace osu.Game.Overlays.Chat private void onTabClose(TabItem tab) { - int totalTabs = TabContainer.Children.Count - 1; // account for selectorTab + int totalTabs = TabContainer.Count - 1; // account for selectorTab int currentIndex = MathHelper.Clamp(TabContainer.IndexOf(tab), 1, totalTabs); if (tab == SelectedTab && totalTabs > 1) // Select the tab after tab-to-be-removed's index, or the tab before if current == last - SelectTab(TabContainer.Children[currentIndex == totalTabs ? currentIndex - 1 : currentIndex + 1]); + SelectTab(TabContainer[currentIndex == totalTabs ? currentIndex - 1 : currentIndex + 1]); else if (totalTabs == 1 && !selectorTab.Active) // Open channel selection overlay if all channel tabs will be closed after removing this tab SelectTab(selectorTab); diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index cc4177edc6..855fb5a1d6 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -397,7 +397,11 @@ namespace osu.Game.Overlays { if (channel == null) return; + if (channel == CurrentChannel) + currentChannelContainer.Clear(false); + careChannels.Remove(channel); + loadedChannels.Remove(loadedChannels.Find(c => c.Channel == channel)); channelTabs.RemoveItem(channel); channel.Joined.Value = false; From 586a652b08ea3591a7c237f193afebafb9f6d268 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Thu, 17 Aug 2017 12:24:22 +0200 Subject: [PATCH 21/93] Changed Mods to be a property --- .../Visual/TestCaseLeaderboard.cs | 2 +- osu.Game/Rulesets/Scoring/Score.cs | 24 ++++++++++++------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs b/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs index 2386881d24..f67db2f41a 100644 --- a/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs +++ b/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs @@ -1,13 +1,13 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using OpenTK; using osu.Framework.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Select.Leaderboards; using osu.Game.Users; -using OpenTK; namespace osu.Desktop.Tests.Visual { diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index e42c3b2df0..e83cb916bb 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -31,22 +31,28 @@ namespace osu.Game.Rulesets.Scoring [JsonProperty(@"mods")] private string[] modStrings { get; set; } - private RulesetInfo ruleset; - public RulesetInfo Ruleset + public RulesetInfo Ruleset; + + private Mod[] mods; + public Mod[] Mods { - get { return ruleset; } + get + { + // Evaluate the mod strings + if (mods == null) + mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); + + return mods; + } set { - ruleset = value; + mods = value; - // Handle the mod strings if they are assigned - if (modStrings != null) - Mods = ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); + // Assign the mod strings + modStrings = mods.Select(mod => mod.ShortenedName).ToArray(); } } - public Mod[] Mods { get; set; } - [JsonProperty(@"user")] public User User; From 7ad4c046dbe06f30a2b564db87d46f8fc1c8e8a7 Mon Sep 17 00:00:00 2001 From: naoey Date: Fri, 18 Aug 2017 13:35:48 +0530 Subject: [PATCH 22/93] Make current value behaviour between channels and tabs consistent. - Trim whitespace --- osu.Game/Overlays/Chat/ChatTabControl.cs | 5 ++++- osu.Game/Overlays/ChatOverlay.cs | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index 5f8db6fa71..c11e474b76 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -57,6 +57,9 @@ namespace osu.Game.Overlays.Chat TabContainer.ChangeChildDepth(selectorTab, float.MaxValue); base.AddTabItem(item, addToDropdown); + + if (SelectedTab == null) + SelectTab(item); } protected override TabItem CreateTabItem(Channel value) @@ -149,7 +152,7 @@ namespace osu.Game.Overlays.Chat protected override bool OnHover(InputState state) { closeButton?.FadeIn(1f, Easing.InBounce); - + if (!Active) box.FadeColour(backgroundHover, transition_length, Easing.OutQuint); return true; diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 855fb5a1d6..6f8bf69779 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -398,7 +398,10 @@ namespace osu.Game.Overlays if (channel == null) return; if (channel == CurrentChannel) + { + currentChannel = null; currentChannelContainer.Clear(false); + } careChannels.Remove(channel); loadedChannels.Remove(loadedChannels.Find(c => c.Channel == channel)); From f831832c59b0b015abd22fe2e5d529f962b4196c Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sat, 19 Aug 2017 00:13:06 +0200 Subject: [PATCH 23/93] CI fix --- osu.Game/Rulesets/Scoring/Score.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index e83cb916bb..154188a2fa 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -38,11 +38,8 @@ namespace osu.Game.Rulesets.Scoring { get { - // Evaluate the mod strings - if (mods == null) - mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); - - return mods; + // Evaluate the mod strings if necessary + return mods ?? (mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray()); } set { From 2cace0e1ab045c172b9571dcd0154b56751decfe Mon Sep 17 00:00:00 2001 From: naoey Date: Thu, 24 Aug 2017 09:48:53 +0530 Subject: [PATCH 24/93] Don't use virtual methods in ctor, always create closeButton. --- osu.Game/Overlays/Chat/ChatTabControl.cs | 41 ++++++++++++------------ 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index c11e474b76..5b65f7c036 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Chat Margin = new MarginPadding(10), }); - AddTabItem(selectorTab = new ChannelTabItem.ChannelSelectorTabItem(new Channel { Name = "+" })); + base.AddTabItem(selectorTab = new ChannelTabItem.ChannelSelectorTabItem(new Channel { Name = "+" })); ChannelSelectorActive.BindTo(selectorTab.Active); } @@ -129,7 +129,7 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1.1f), transition_length, Easing.OutQuint); - closeButton?.MoveToX(-5f, 0.5f, Easing.OutElastic); + closeButton.MoveToX(-5f, 0.5f, Easing.OutElastic); box.FadeColour(backgroundActive, transition_length, Easing.OutQuint); highlightBox.FadeIn(transition_length, Easing.OutQuint); @@ -141,7 +141,7 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1), transition_length, Easing.OutQuint); - closeButton?.MoveToX(5f, 0.5f, Easing.InElastic); + closeButton.MoveToX(5f, 0.5f, Easing.InElastic); box.FadeColour(backgroundInactive, transition_length, Easing.OutQuint); highlightBox.FadeOut(transition_length, Easing.OutQuint); @@ -151,7 +151,8 @@ namespace osu.Game.Overlays.Chat protected override bool OnHover(InputState state) { - closeButton?.FadeIn(1f, Easing.InBounce); + if (IsRemovable) + closeButton.FadeIn(1f, Easing.InBounce); if (!Active) box.FadeColour(backgroundHover, transition_length, Easing.OutQuint); @@ -160,7 +161,9 @@ namespace osu.Game.Overlays.Chat protected override void OnHoverLost(InputState state) { - closeButton?.FadeOut(1f, Easing.OutBounce); + if (closeButton.IsPresent) + closeButton.FadeOut(1f, Easing.OutBounce); + updateState(); } @@ -250,25 +253,21 @@ namespace osu.Game.Overlays.Chat Font = @"Exo2.0-Bold", TextSize = 18, }, + closeButton = new Button + { + Alpha = 0, + Width = 20, + Height = 20, + Margin = new MarginPadding { Right = 10 }, + Origin = Anchor.CentreRight, + Anchor = Anchor.CentreRight, + Text = @"x", + BackgroundColour = Color4.Transparent, + Action = delegate { if (IsRemovable) OnRequestClose?.Invoke(); }, + }, }, }, }; - - if (IsRemovable) - { - Add(closeButton = new Button - { - Alpha = 0, - Width = 20, - Height = 20, - Margin = new MarginPadding { Right = 10 }, - Origin = Anchor.CentreRight, - Anchor = Anchor.CentreRight, - Text = @"x", - BackgroundColour = Color4.Transparent, - Action = () => OnRequestClose?.Invoke(), - }); - } } public class ChannelSelectorTabItem : ChannelTabItem From 6291bd5ced4d8834afbb7b8e9ec5d90e575106a9 Mon Sep 17 00:00:00 2001 From: naoey Date: Thu, 24 Aug 2017 10:40:42 +0530 Subject: [PATCH 25/93] Handle null current channel in setter, update framework. --- osu-framework | 2 +- osu.Game/Overlays/ChatOverlay.cs | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/osu-framework b/osu-framework index 1ba1e8ef1e..d492c2ffe6 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 1ba1e8ef1e5ec0466632be02492023a081cb85ab +Subproject commit d492c2ffe6ce5dac2a8e05118d86e6907186329b diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 38432860c3..b20019ed1a 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -334,7 +334,15 @@ namespace osu.Game.Overlays set { - if (currentChannel == value || value == null) return; + if (currentChannel == value) return; + + if (value == null) + { + currentChannel = null; + textbox.Current.Disabled = true; + currentChannelContainer.Clear(false); + return; + } currentChannel = value; @@ -397,11 +405,7 @@ namespace osu.Game.Overlays { if (channel == null) return; - if (channel == CurrentChannel) - { - currentChannel = null; - currentChannelContainer.Clear(false); - } + if (channel == CurrentChannel) CurrentChannel = null; careChannels.Remove(channel); loadedChannels.Remove(loadedChannels.Find(c => c.Channel == channel)); From 511fccdba733a8f70112024fd9a182ac636342c8 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 24 Aug 2017 17:28:47 +0900 Subject: [PATCH 26/93] Add editor menu bar test case. --- osu-framework | 2 +- .../Visual/TestCaseEditorMenuBar.cs | 184 ++++++++++++++++++ osu.Desktop.Tests/osu.Desktop.Tests.csproj | 1 + 3 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs diff --git a/osu-framework b/osu-framework index 1ba1e8ef1e..fbbcd942e2 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 1ba1e8ef1e5ec0466632be02492023a081cb85ab +Subproject commit fbbcd942e262778b166acde2cc89a10782734f2d diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs new file mode 100644 index 0000000000..455c25f385 --- /dev/null +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -0,0 +1,184 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +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.UserInterface; +using osu.Framework.Testing; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; + +namespace osu.Desktop.Tests.Visual +{ + public class TestCaseEditorMenuBar : TestCase + { + public TestCaseEditorMenuBar() + { + Add(new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = 500, + Child = new EditorMenuBar + { + Items = new[] + { + new EditorMenuBarItem("File") + { + Items = new OsuContextMenuItem[] + { + new EditorContextMenuItem("Clear All Notes"), + new EditorContextMenuItem("Open Difficulty..."), + new EditorContextMenuItem("Save"), + new EditorContextMenuItem("Create a new Difficulty..."), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Revert to Saved"), + new EditorContextMenuItem("Revert to Saved (Full)"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Test Beatmap"), + new EditorContextMenuItem("Open AiMod"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Upload Beatmap..."), + new EditorContextMenuItem("Export Package"), + new EditorContextMenuItem("Export Map Package"), + new EditorContextMenuItem("Import from..."), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Open Song Folder"), + new EditorContextMenuItem("Open .osu in Notepad"), + new EditorContextMenuItem("Open .osb in Notepad"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Exit"), + } + }, + new EditorMenuBarItem("Timing") + { + Items = new[] + { + new EditorContextMenuItem("Time Signature"), + new EditorContextMenuItem("Metronome Clicks"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Add Timing Section"), + new EditorContextMenuItem("Add Inheriting Section"), + new EditorContextMenuItem("Reset Current Section"), + new EditorContextMenuItem("Delete Timing Section"), + new EditorContextMenuItem("Resnap Current Section"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Timing Setup"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Resnap All Notes", MenuItemType.Destructive), + new EditorContextMenuItem("Move all notes in time...", MenuItemType.Destructive), + new EditorContextMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive), + new EditorContextMenuItem("Delete All Timing Sections", MenuItemType.Destructive), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Set Current Position as Preview Point"), + } + }, + new EditorMenuBarItem("Testing") + { + Items = new[] + { + new EditorContextMenuItem("Item 1"), + new EditorContextMenuItem("Item 2"), + new EditorContextMenuItem("Item 3"), + } + }, + } + } + }); + } + } + + public class EditorMenuBar : MenuBar + { + } + + public class EditorMenuBarItem : MenuBarItem + { + private const int fade_duration = 250; + private const float text_size = 17; + + private readonly Container background; + + private Color4 normalColour; + + public EditorMenuBarItem(string title) + : base(title) + { + Content.Padding = new MarginPadding(8); + + AddInternal(background = new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + Depth = float.MaxValue, + Alpha = 0, + Child = new Container + { + // The following is done so we can have top rounded corners but not bottom corners + RelativeSizeAxes = Axes.Both, + Height = 2, + Masking = true, + CornerRadius = 5, + Child = new Box { RelativeSizeAxes = Axes.Both } + } + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Gray3; + ContextMenu.Menu.Background.Colour = colours.Gray3; + TitleText.Colour = normalColour = colours.BlueLight; + } + + public override void Open() + { + base.Open(); + + background.FadeIn(fade_duration, Easing.OutQuint); + TitleText.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + } + + public override void Close() + { + base.Close(); + + background.FadeOut(fade_duration, Easing.OutQuint); + TitleText.FadeColour(normalColour, fade_duration, Easing.OutQuint); + } + + protected override SpriteText CreateTitleText() => new OsuSpriteText { TextSize = text_size }; + + protected override ContextMenu CreateContextMenu() => new OsuContextMenu + { + OriginPosition = new Vector2(8, 0) + }; + } + + public class EditorContextMenuSpacer : EditorContextMenuItem + { + public override bool HandleInput => false; + + public EditorContextMenuSpacer() + : base(" ") + { + } + } + + public class EditorContextMenuItem : OsuContextMenuItem + { + private const int min_text_length = 40; + + public EditorContextMenuItem(string title, MenuItemType type = MenuItemType.Standard) + : base(title.PadRight(min_text_length), type) + { + } + } +} diff --git a/osu.Desktop.Tests/osu.Desktop.Tests.csproj b/osu.Desktop.Tests/osu.Desktop.Tests.csproj index 24d112a45c..86268e6110 100644 --- a/osu.Desktop.Tests/osu.Desktop.Tests.csproj +++ b/osu.Desktop.Tests/osu.Desktop.Tests.csproj @@ -87,6 +87,7 @@ + From 26a4238a383a034feca20a3c586476d41832b57b Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 24 Aug 2017 17:31:23 +0900 Subject: [PATCH 27/93] Make classes private for now. --- .../Visual/TestCaseEditorMenuBar.cs | 146 +++++++++--------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index 455c25f385..7c46107365 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -92,93 +92,93 @@ namespace osu.Desktop.Tests.Visual } }); } - } - public class EditorMenuBar : MenuBar - { - } - - public class EditorMenuBarItem : MenuBarItem - { - private const int fade_duration = 250; - private const float text_size = 17; - - private readonly Container background; - - private Color4 normalColour; - - public EditorMenuBarItem(string title) - : base(title) + private class EditorMenuBar : MenuBar { - Content.Padding = new MarginPadding(8); + } - AddInternal(background = new Container + private class EditorMenuBarItem : MenuBarItem + { + private const int fade_duration = 250; + private const float text_size = 17; + + private readonly Container background; + + private Color4 normalColour; + + public EditorMenuBarItem(string title) + : base(title) { - RelativeSizeAxes = Axes.Both, - Masking = true, - Depth = float.MaxValue, - Alpha = 0, - Child = new Container + Content.Padding = new MarginPadding(8); + + AddInternal(background = new Container { - // The following is done so we can have top rounded corners but not bottom corners RelativeSizeAxes = Axes.Both, - Height = 2, Masking = true, - CornerRadius = 5, - Child = new Box { RelativeSizeAxes = Axes.Both } - } - }); + Depth = float.MaxValue, + Alpha = 0, + Child = new Container + { + // The following is done so we can have top rounded corners but not bottom corners + RelativeSizeAxes = Axes.Both, + Height = 2, + Masking = true, + CornerRadius = 5, + Child = new Box { RelativeSizeAxes = Axes.Both } + } + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Gray3; + ContextMenu.Menu.Background.Colour = colours.Gray3; + TitleText.Colour = normalColour = colours.BlueLight; + } + + public override void Open() + { + base.Open(); + + background.FadeIn(fade_duration, Easing.OutQuint); + TitleText.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + } + + public override void Close() + { + base.Close(); + + background.FadeOut(fade_duration, Easing.OutQuint); + TitleText.FadeColour(normalColour, fade_duration, Easing.OutQuint); + } + + protected override SpriteText CreateTitleText() => new OsuSpriteText { TextSize = text_size }; + + protected override ContextMenu CreateContextMenu() => new OsuContextMenu + { + OriginPosition = new Vector2(8, 0) + }; } - [BackgroundDependencyLoader] - private void load(OsuColour colours) + private class EditorContextMenuSpacer : EditorContextMenuItem { - background.Colour = colours.Gray3; - ContextMenu.Menu.Background.Colour = colours.Gray3; - TitleText.Colour = normalColour = colours.BlueLight; + public override bool HandleInput => false; + + public EditorContextMenuSpacer() + : base(" ") + { + } } - public override void Open() + private class EditorContextMenuItem : OsuContextMenuItem { - base.Open(); + private const int min_text_length = 40; - background.FadeIn(fade_duration, Easing.OutQuint); - TitleText.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - } - - public override void Close() - { - base.Close(); - - background.FadeOut(fade_duration, Easing.OutQuint); - TitleText.FadeColour(normalColour, fade_duration, Easing.OutQuint); - } - - protected override SpriteText CreateTitleText() => new OsuSpriteText { TextSize = text_size }; - - protected override ContextMenu CreateContextMenu() => new OsuContextMenu - { - OriginPosition = new Vector2(8, 0) - }; - } - - public class EditorContextMenuSpacer : EditorContextMenuItem - { - public override bool HandleInput => false; - - public EditorContextMenuSpacer() - : base(" ") - { - } - } - - public class EditorContextMenuItem : OsuContextMenuItem - { - private const int min_text_length = 40; - - public EditorContextMenuItem(string title, MenuItemType type = MenuItemType.Standard) - : base(title.PadRight(min_text_length), type) - { + public EditorContextMenuItem(string title, MenuItemType type = MenuItemType.Standard) + : base(title.PadRight(min_text_length), type) + { + } } } } From a863eb2a2ffef640a85be6e287de46980af71a1f Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 24 Aug 2017 17:43:56 +0900 Subject: [PATCH 28/93] Add EditorMenuBarItem colours. --- osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index 7c46107365..8d14f5f2df 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -31,7 +31,7 @@ namespace osu.Desktop.Tests.Visual { new EditorMenuBarItem("File") { - Items = new OsuContextMenuItem[] + Items = new[] { new EditorContextMenuItem("Clear All Notes"), new EditorContextMenuItem("Open Difficulty..."), @@ -179,6 +179,13 @@ namespace osu.Desktop.Tests.Visual : base(title.PadRight(min_text_length), type) { } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Gray3; + BackgroundColourHover = colours.Gray2; + } } } } From c39bb6e64777933287fabcf1f7a6b25945638ba2 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 24 Aug 2017 17:50:22 +0900 Subject: [PATCH 29/93] Pretty-ifying test case. --- .../Visual/TestCaseEditorMenuBar.cs | 127 +++++++++--------- 1 file changed, 60 insertions(+), 67 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index 8d14f5f2df..49a382c9f9 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -20,83 +20,76 @@ namespace osu.Desktop.Tests.Visual { public TestCaseEditorMenuBar() { - Add(new Container + Add(new MenuBar { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Width = 500, - Child = new EditorMenuBar + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Y = 50, + Items = new[] { - Items = new[] + new EditorMenuBarItem("File") { - new EditorMenuBarItem("File") + Items = new[] { - Items = new[] - { - new EditorContextMenuItem("Clear All Notes"), - new EditorContextMenuItem("Open Difficulty..."), - new EditorContextMenuItem("Save"), - new EditorContextMenuItem("Create a new Difficulty..."), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Revert to Saved"), - new EditorContextMenuItem("Revert to Saved (Full)"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Test Beatmap"), - new EditorContextMenuItem("Open AiMod"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Upload Beatmap..."), - new EditorContextMenuItem("Export Package"), - new EditorContextMenuItem("Export Map Package"), - new EditorContextMenuItem("Import from..."), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Open Song Folder"), - new EditorContextMenuItem("Open .osu in Notepad"), - new EditorContextMenuItem("Open .osb in Notepad"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Exit"), - } - }, - new EditorMenuBarItem("Timing") + new EditorContextMenuItem("Clear All Notes"), + new EditorContextMenuItem("Open Difficulty..."), + new EditorContextMenuItem("Save"), + new EditorContextMenuItem("Create a new Difficulty..."), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Revert to Saved"), + new EditorContextMenuItem("Revert to Saved (Full)"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Test Beatmap"), + new EditorContextMenuItem("Open AiMod"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Upload Beatmap..."), + new EditorContextMenuItem("Export Package"), + new EditorContextMenuItem("Export Map Package"), + new EditorContextMenuItem("Import from..."), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Open Song Folder"), + new EditorContextMenuItem("Open .osu in Notepad"), + new EditorContextMenuItem("Open .osb in Notepad"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Exit"), + } + }, + new EditorMenuBarItem("Timing") + { + Items = new[] { - Items = new[] - { - new EditorContextMenuItem("Time Signature"), - new EditorContextMenuItem("Metronome Clicks"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Add Timing Section"), - new EditorContextMenuItem("Add Inheriting Section"), - new EditorContextMenuItem("Reset Current Section"), - new EditorContextMenuItem("Delete Timing Section"), - new EditorContextMenuItem("Resnap Current Section"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Timing Setup"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Resnap All Notes", MenuItemType.Destructive), - new EditorContextMenuItem("Move all notes in time...", MenuItemType.Destructive), - new EditorContextMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive), - new EditorContextMenuItem("Delete All Timing Sections", MenuItemType.Destructive), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Set Current Position as Preview Point"), - } - }, - new EditorMenuBarItem("Testing") + new EditorContextMenuItem("Time Signature"), + new EditorContextMenuItem("Metronome Clicks"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Add Timing Section"), + new EditorContextMenuItem("Add Inheriting Section"), + new EditorContextMenuItem("Reset Current Section"), + new EditorContextMenuItem("Delete Timing Section"), + new EditorContextMenuItem("Resnap Current Section"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Timing Setup"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Resnap All Notes", MenuItemType.Destructive), + new EditorContextMenuItem("Move all notes in time...", MenuItemType.Destructive), + new EditorContextMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive), + new EditorContextMenuItem("Delete All Timing Sections", MenuItemType.Destructive), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Set Current Position as Preview Point"), + } + }, + new EditorMenuBarItem("Testing") + { + Items = new[] { - Items = new[] - { - new EditorContextMenuItem("Item 1"), - new EditorContextMenuItem("Item 2"), - new EditorContextMenuItem("Item 3"), - } - }, - } + new EditorContextMenuItem("Item 1"), + new EditorContextMenuItem("Item 2"), + new EditorContextMenuItem("Item 3"), + } + }, } }); } - private class EditorMenuBar : MenuBar - { - } - private class EditorMenuBarItem : MenuBarItem { private const int fade_duration = 250; From 4ab209bdce8a5fbc234c6bf899e62a9c8290db5b Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 24 Aug 2017 19:05:51 +0900 Subject: [PATCH 30/93] Add EditorContextMenu in line with framework changes To avoid public Menu. --- osu-framework | 2 +- osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/osu-framework b/osu-framework index fbbcd942e2..a5fd0c82c8 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit fbbcd942e262778b166acde2cc89a10782734f2d +Subproject commit a5fd0c82c8f86d41c80ac1b0b07727cb312330f1 diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index 49a382c9f9..7a9c97f5d5 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -126,7 +126,6 @@ namespace osu.Desktop.Tests.Visual private void load(OsuColour colours) { background.Colour = colours.Gray3; - ContextMenu.Menu.Background.Colour = colours.Gray3; TitleText.Colour = normalColour = colours.BlueLight; } @@ -148,12 +147,21 @@ namespace osu.Desktop.Tests.Visual protected override SpriteText CreateTitleText() => new OsuSpriteText { TextSize = text_size }; - protected override ContextMenu CreateContextMenu() => new OsuContextMenu + protected override ContextMenu CreateContextMenu() => new EditorContextMenu { OriginPosition = new Vector2(8, 0) }; } + private class EditorContextMenu : OsuContextMenu + { + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Menu.Background.Colour = colours.Gray3; + } + } + private class EditorContextMenuSpacer : EditorContextMenuItem { public override bool HandleInput => false; From 5dae408ecb1204293a664862b78a9e8567fbfc5a Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 28 Aug 2017 15:32:12 +0900 Subject: [PATCH 31/93] Reimplement TestCaseEditorMenuBar. --- osu-framework | 2 +- .../Visual/TestCaseEditorMenuBar.cs | 272 ++++++++++-------- 2 files changed, 157 insertions(+), 117 deletions(-) diff --git a/osu-framework b/osu-framework index 2cb3e59c8b..f6a1df24ee 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 2cb3e59c8bc7e67edef4dfe7f9c7dfc01db386a7 +Subproject commit f6a1df24eeef78e89f2d6e24fe1b43756eaae51e diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index 7a9c97f5d5..b7a4bc355d 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; @@ -20,7 +21,7 @@ namespace osu.Desktop.Tests.Visual { public TestCaseEditorMenuBar() { - Add(new MenuBar + Add(new EditorMenuBar { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -31,162 +32,201 @@ namespace osu.Desktop.Tests.Visual { Items = new[] { - new EditorContextMenuItem("Clear All Notes"), - new EditorContextMenuItem("Open Difficulty..."), - new EditorContextMenuItem("Save"), - new EditorContextMenuItem("Create a new Difficulty..."), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Revert to Saved"), - new EditorContextMenuItem("Revert to Saved (Full)"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Test Beatmap"), - new EditorContextMenuItem("Open AiMod"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Upload Beatmap..."), - new EditorContextMenuItem("Export Package"), - new EditorContextMenuItem("Export Map Package"), - new EditorContextMenuItem("Import from..."), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Open Song Folder"), - new EditorContextMenuItem("Open .osu in Notepad"), - new EditorContextMenuItem("Open .osb in Notepad"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Exit"), + new EditorMenuItem("Clear All Notes"), + new EditorMenuItem("Open Difficulty..."), + new EditorMenuItem("Save"), + new EditorMenuItem("Create a new Difficulty..."), + new EditorMenuSpacer(), + new EditorMenuItem("Revert to Saved"), + new EditorMenuItem("Revert to Saved (Full)"), + new EditorMenuSpacer(), + new EditorMenuItem("Test Beatmap"), + new EditorMenuItem("Open AiMod"), + new EditorMenuSpacer(), + new EditorMenuItem("Upload Beatmap..."), + new EditorMenuItem("Export Package"), + new EditorMenuItem("Export Map Package"), + new EditorMenuItem("Import from..."), + new EditorMenuSpacer(), + new EditorMenuItem("Open Song Folder"), + new EditorMenuItem("Open .osu in Notepad"), + new EditorMenuItem("Open .osb in Notepad"), + new EditorMenuSpacer(), + new EditorMenuItem("Exit"), } }, new EditorMenuBarItem("Timing") { Items = new[] { - new EditorContextMenuItem("Time Signature"), - new EditorContextMenuItem("Metronome Clicks"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Add Timing Section"), - new EditorContextMenuItem("Add Inheriting Section"), - new EditorContextMenuItem("Reset Current Section"), - new EditorContextMenuItem("Delete Timing Section"), - new EditorContextMenuItem("Resnap Current Section"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Timing Setup"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Resnap All Notes", MenuItemType.Destructive), - new EditorContextMenuItem("Move all notes in time...", MenuItemType.Destructive), - new EditorContextMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive), - new EditorContextMenuItem("Delete All Timing Sections", MenuItemType.Destructive), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Set Current Position as Preview Point"), + new EditorMenuItem("Time Signature"), + new EditorMenuItem("Metronome Clicks"), + new EditorMenuSpacer(), + new EditorMenuItem("Add Timing Section"), + new EditorMenuItem("Add Inheriting Section"), + new EditorMenuItem("Reset Current Section"), + new EditorMenuItem("Delete Timing Section"), + new EditorMenuItem("Resnap Current Section"), + new EditorMenuSpacer(), + new EditorMenuItem("Timing Setup"), + new EditorMenuSpacer(), + new EditorMenuItem("Resnap All Notes", MenuItemType.Destructive), + new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive), + new EditorMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive), + new EditorMenuItem("Delete All Timing Sections", MenuItemType.Destructive), + new EditorMenuSpacer(), + new EditorMenuItem("Set Current Position as Preview Point"), } }, new EditorMenuBarItem("Testing") { Items = new[] { - new EditorContextMenuItem("Item 1"), - new EditorContextMenuItem("Item 2"), - new EditorContextMenuItem("Item 3"), + new EditorMenuItem("Item 1"), + new EditorMenuItem("Item 2"), + new EditorMenuItem("Item 3"), } }, } }); } - private class EditorMenuBarItem : MenuBarItem + private class EditorMenuBar : MenuBar { - private const int fade_duration = 250; - private const float text_size = 17; + protected override DrawableMenuBarItem CreateDrawableMenuBarItem(MenuItem item) => new DrawableEditorMenuBarItem(item); - private readonly Container background; - - private Color4 normalColour; - - public EditorMenuBarItem(string title) - : base(title) + private class DrawableEditorMenuBarItem : DrawableMenuBarItem { - Content.Padding = new MarginPadding(8); + private const int fade_duration = 250; + private const float text_size = 17; - AddInternal(background = new Container + private readonly Container background; + + private Color4 normalColour; + + public DrawableEditorMenuBarItem(MenuItem item) + : base(item) { - RelativeSizeAxes = Axes.Both, - Masking = true, - Depth = float.MaxValue, - Alpha = 0, - Child = new Container + if (!(item is EditorMenuBarItem)) + throw new ArgumentException($"{nameof(item)} must be a {nameof(EditorMenuBarItem)}."); + + Text.Padding = new MarginPadding(8); + + AddInternal(background = new Container { - // The following is done so we can have top rounded corners but not bottom corners RelativeSizeAxes = Axes.Both, - Height = 2, Masking = true, - CornerRadius = 5, - Child = new Box { RelativeSizeAxes = Axes.Both } + Depth = float.MaxValue, + Alpha = 0, + Child = new Container + { + // The following is done so we can have top rounded corners but not bottom corners + RelativeSizeAxes = Axes.Both, + Height = 2, + Masking = true, + CornerRadius = 5, + Child = new Box { RelativeSizeAxes = Axes.Both } + } + }); + + Menu.OnOpen += menuOpen; + Menu.OnClose += menuClose; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Gray3; + Text.Colour = normalColour = colours.BlueLight; + } + + private void menuOpen() + { + background.FadeIn(fade_duration, Easing.OutQuint); + Text.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + } + + private void menuClose() + { + background.FadeOut(fade_duration, Easing.OutQuint); + Text.FadeColour(normalColour, fade_duration, Easing.OutQuint); + } + + protected override SpriteText CreateText() => new OsuSpriteText { TextSize = text_size }; + + protected override Menu CreateMenu() => new EditorMenu(); + + private class EditorMenu : OsuMenu + { + public EditorMenu() + { + Anchor = Anchor.BottomLeft; + BypassAutoSizeAxes = Axes.Both; + OriginPosition = new Vector2(8, 0); } - }); - } - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - background.Colour = colours.Gray3; - TitleText.Colour = normalColour = colours.BlueLight; - } + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Gray3; + } - public override void Open() - { - base.Open(); + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableEditorMenuItem(item); - background.FadeIn(fade_duration, Easing.OutQuint); - TitleText.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - } + private class DrawableEditorMenuItem : DrawableOsuMenuItem + { + public override bool HandleInput => !isSpacer; + private readonly bool isSpacer; - public override void Close() - { - base.Close(); + public DrawableEditorMenuItem(MenuItem item) + : base(item) + { + if (!(item is EditorMenuItem)) + throw new ArgumentException($"{nameof(item)} must be a {nameof(EditorMenuItem)}."); - background.FadeOut(fade_duration, Easing.OutQuint); - TitleText.FadeColour(normalColour, fade_duration, Easing.OutQuint); - } + isSpacer = item is EditorMenuSpacer; + } - protected override SpriteText CreateTitleText() => new OsuSpriteText { TextSize = text_size }; - - protected override ContextMenu CreateContextMenu() => new EditorContextMenu - { - OriginPosition = new Vector2(8, 0) - }; - } - - private class EditorContextMenu : OsuContextMenu - { - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - Menu.Background.Colour = colours.Gray3; + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Gray3; + BackgroundColourHover = colours.Gray2; + } + } + } } } - private class EditorContextMenuSpacer : EditorContextMenuItem + private class EditorMenuBarItem : MenuItem { - public override bool HandleInput => false; + public EditorMenuBarItem(string text) + : base(text) + { + } + } - public EditorContextMenuSpacer() + private class EditorMenuItem : OsuMenuItem + { + private const int min_text_length = 40; + + public EditorMenuItem(string text, MenuItemType type = MenuItemType.Standard) + : base(text.PadRight(min_text_length), type) + { + } + + public EditorMenuItem(string text, MenuItemType type, Action action) + : base(text.PadRight(min_text_length), type, action) + { + } + } + + private class EditorMenuSpacer : EditorMenuItem + { + public EditorMenuSpacer() : base(" ") { } } - - private class EditorContextMenuItem : OsuContextMenuItem - { - private const int min_text_length = 40; - - public EditorContextMenuItem(string title, MenuItemType type = MenuItemType.Standard) - : base(title.PadRight(min_text_length), type) - { - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - BackgroundColour = colours.Gray3; - BackgroundColourHover = colours.Gray2; - } - } } } From 7c9c7f93aece86a7e976c9be7032f391832d188d Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 28 Aug 2017 15:42:21 +0900 Subject: [PATCH 32/93] Remove unnecessary exception, replace with default styling. --- osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index b7a4bc355d..95d34543bb 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -107,8 +107,6 @@ namespace osu.Desktop.Tests.Visual public DrawableEditorMenuBarItem(MenuItem item) : base(item) { - if (!(item is EditorMenuBarItem)) - throw new ArgumentException($"{nameof(item)} must be a {nameof(EditorMenuBarItem)}."); Text.Padding = new MarginPadding(8); @@ -181,8 +179,6 @@ namespace osu.Desktop.Tests.Visual public DrawableEditorMenuItem(MenuItem item) : base(item) { - if (!(item is EditorMenuItem)) - throw new ArgumentException($"{nameof(item)} must be a {nameof(EditorMenuItem)}."); isSpacer = item is EditorMenuSpacer; } From b17d9ac06ea649b977ead563b7b5e4ecefe70ab9 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 28 Aug 2017 17:55:50 +0900 Subject: [PATCH 33/93] Move EditorMenuBar into the Edit namespace, and fix a minor styling issue. --- osu-framework | 2 +- .../Visual/TestCaseEditorMenuBar.cs | 145 +-------------- osu.Game/Graphics/UserInterface/OsuMenu.cs | 5 +- osu.Game/Screens/Edit/Editor.cs | 174 ++++++++++++++++++ osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 131 +++++++++++++ .../Screens/Edit/Menus/EditorMenuBarItem.cs | 15 ++ osu.Game/Screens/Edit/Menus/EditorMenuItem.cs | 23 +++ .../Edit/Menus/EditorMenuItemSpacer.cs | 13 ++ osu.Game/osu.Game.csproj | 4 + 9 files changed, 365 insertions(+), 147 deletions(-) create mode 100644 osu.Game/Screens/Edit/Menus/EditorMenuBar.cs create mode 100644 osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs create mode 100644 osu.Game/Screens/Edit/Menus/EditorMenuItem.cs create mode 100644 osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs diff --git a/osu-framework b/osu-framework index f6a1df24ee..c7457f0ce9 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit f6a1df24eeef78e89f2d6e24fe1b43756eaae51e +Subproject commit c7457f0ce9ef3f663ee800f6b7fc574e9abff1da diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index 95d34543bb..9ff4f4c591 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -1,19 +1,10 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using OpenTK; -using OpenTK.Graphics; -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.UserInterface; using osu.Framework.Testing; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Screens.Edit.Menus; namespace osu.Desktop.Tests.Visual { @@ -90,139 +81,5 @@ namespace osu.Desktop.Tests.Visual } }); } - - private class EditorMenuBar : MenuBar - { - protected override DrawableMenuBarItem CreateDrawableMenuBarItem(MenuItem item) => new DrawableEditorMenuBarItem(item); - - private class DrawableEditorMenuBarItem : DrawableMenuBarItem - { - private const int fade_duration = 250; - private const float text_size = 17; - - private readonly Container background; - - private Color4 normalColour; - - public DrawableEditorMenuBarItem(MenuItem item) - : base(item) - { - - Text.Padding = new MarginPadding(8); - - AddInternal(background = new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Depth = float.MaxValue, - Alpha = 0, - Child = new Container - { - // The following is done so we can have top rounded corners but not bottom corners - RelativeSizeAxes = Axes.Both, - Height = 2, - Masking = true, - CornerRadius = 5, - Child = new Box { RelativeSizeAxes = Axes.Both } - } - }); - - Menu.OnOpen += menuOpen; - Menu.OnClose += menuClose; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - background.Colour = colours.Gray3; - Text.Colour = normalColour = colours.BlueLight; - } - - private void menuOpen() - { - background.FadeIn(fade_duration, Easing.OutQuint); - Text.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - } - - private void menuClose() - { - background.FadeOut(fade_duration, Easing.OutQuint); - Text.FadeColour(normalColour, fade_duration, Easing.OutQuint); - } - - protected override SpriteText CreateText() => new OsuSpriteText { TextSize = text_size }; - - protected override Menu CreateMenu() => new EditorMenu(); - - private class EditorMenu : OsuMenu - { - public EditorMenu() - { - Anchor = Anchor.BottomLeft; - BypassAutoSizeAxes = Axes.Both; - OriginPosition = new Vector2(8, 0); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - BackgroundColour = colours.Gray3; - } - - protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableEditorMenuItem(item); - - private class DrawableEditorMenuItem : DrawableOsuMenuItem - { - public override bool HandleInput => !isSpacer; - private readonly bool isSpacer; - - public DrawableEditorMenuItem(MenuItem item) - : base(item) - { - - isSpacer = item is EditorMenuSpacer; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - BackgroundColour = colours.Gray3; - BackgroundColourHover = colours.Gray2; - } - } - } - } - } - - private class EditorMenuBarItem : MenuItem - { - public EditorMenuBarItem(string text) - : base(text) - { - } - } - - private class EditorMenuItem : OsuMenuItem - { - private const int min_text_length = 40; - - public EditorMenuItem(string text, MenuItemType type = MenuItemType.Standard) - : base(text.PadRight(min_text_length), type) - { - } - - public EditorMenuItem(string text, MenuItemType type, Action action) - : base(text.PadRight(min_text_length), type, action) - { - } - } - - private class EditorMenuSpacer : EditorMenuItem - { - public EditorMenuSpacer() - : base(" ") - { - } - } } } diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index efc6998ca7..e0bb23df5d 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -105,9 +105,10 @@ namespace osu.Game.Graphics.UserInterface return base.OnClick(state); } - protected override Drawable CreateContent() => text = new TextContainer(); + protected sealed override Drawable CreateContent() => text = CreateTextContainer(); + protected virtual TextContainer CreateTextContainer() => new TextContainer(); - private class TextContainer : Container, IHasText + protected class TextContainer : Container, IHasText { public string Text { diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 9f33d624e2..0454609689 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -8,6 +8,11 @@ using osu.Framework.Screens; using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Select; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; +using osu.Game.Screens.Edit.Menus; namespace osu.Game.Screens.Edit { @@ -17,6 +22,175 @@ namespace osu.Game.Screens.Edit protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg4"); + internal override bool ShowOverlays => false; + + public Editor() + { + Add(new Container + { + RelativeSizeAxes = Axes.X, + Height = 40, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("111") + }, + new EditorMenuBar + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + X = 100, + Items = new[] + { + new EditorMenuBarItem("File") + { + Items = new[] + { + new EditorMenuItem("Clear all notes"), + new EditorMenuItem("Open difficulty..."), + new EditorMenuItem("Save"), + new EditorMenuItem("Create new difficulty..."), + new EditorMenuSpacer(), + new EditorMenuItem("Revert to saved"), + new EditorMenuItem("Revert to saved (full"), + new EditorMenuSpacer(), + new EditorMenuItem("Test beatmap"), + new EditorMenuItem("Open AiMod"), + new EditorMenuSpacer(), + new EditorMenuItem("Upload Beatmap..."), + new EditorMenuItem("Export package"), + new EditorMenuItem("Export map package"), + new EditorMenuItem("Import from..."), + new EditorMenuSpacer(), + new EditorMenuItem("Open song folder"), + new EditorMenuItem("Open .osu in Notepad"), + new EditorMenuItem("Open .osb in Notepad"), + new EditorMenuSpacer(), + new EditorMenuItem("Exit", MenuItemType.Standard, Exit) + } + }, + new EditorMenuBarItem("Edit") + { + Items = new[] + { + new EditorMenuItem("Undo"), + new EditorMenuItem("Redo"), + new EditorMenuSpacer(), + new EditorMenuItem("Cut"), + new EditorMenuItem("Copy"), + new EditorMenuItem("Paste"), + new EditorMenuItem("Delete"), + new EditorMenuSpacer(), + new EditorMenuItem("Select all"), + new EditorMenuItem("Clone"), + new EditorMenuSpacer(), + new EditorMenuItem("Reverse selection"), + new EditorMenuItem("Flip horizontally"), + new EditorMenuItem("Flip vertically"), + new EditorMenuItem("Rotate 90deg clockwise"), + new EditorMenuItem("Rotate 90deg anticlockwise"), + new EditorMenuItem("Rotate by..."), + new EditorMenuItem("Scale by..."), + new EditorMenuSpacer(), + new EditorMenuItem("Reset selected objects' samples"), + new EditorMenuItem("Reset all samples", MenuItemType.Destructive), + new EditorMenuItem("Reset combo colours", MenuItemType.Destructive), + new EditorMenuItem("Reset breaks", MenuItemType.Destructive), + new EditorMenuSpacer(), + new EditorMenuItem("Nudge backward"), + new EditorMenuItem("Nudge forward") + } + }, + new EditorMenuBarItem("View") + { + Items = new[] + { + new EditorMenuItem("Compose"), + new EditorMenuItem("Design"), + new EditorMenuItem("Timing"), + new EditorMenuSpacer(), + new EditorMenuItem("Song setup..."), + new EditorMenuItem("Timing setup..."), + new EditorMenuSpacer(), + new EditorMenuItem("Volume"), + new EditorMenuItem("Grid level"), + new EditorMenuItem("Show video"), + new EditorMenuItem("Show sample name"), + new EditorMenuItem("Snaking sliders"), + new EditorMenuItem("Hit animations"), + new EditorMenuItem("Follow points"), + new EditorMenuItem("Stacking") + } + }, + new EditorMenuBarItem("Compose") + { + Items = new[] + { + new EditorMenuItem("Snap divisor"), + new EditorMenuItem("Audio rate"), + new EditorMenuItem("Grid snapping"), + new EditorMenuSpacer(), + new EditorMenuItem("Create polygon cricles..."), + new EditorMenuItem("Convert slider to stream"), + new EditorMenuItem("Enable live mapping mode"), + new EditorMenuItem("Sample import") + } + }, + new EditorMenuBarItem("Design") + { + Items = new[] + { + new EditorMenuItem("Move all elements in time...") + } + }, + new EditorMenuBarItem("Timing") + { + Items = new[] + { + new EditorMenuItem("Time signature"), + new EditorMenuItem("Metronome clicks"), + new EditorMenuSpacer(), + new EditorMenuItem("Add timing section"), + new EditorMenuItem("Add inheriting section"), + new EditorMenuItem("Reset current section"), + new EditorMenuItem("Delete timing section"), + new EditorMenuItem("Resnap current section"), + new EditorMenuSpacer(), + new EditorMenuItem("Timing setup..."), + new EditorMenuSpacer(), + new EditorMenuItem("Resnap all notes", MenuItemType.Destructive), + new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive), + new EditorMenuItem("Recalculate slider lengths", MenuItemType.Destructive), + new EditorMenuItem("Delete all timing sections", MenuItemType.Destructive), + new EditorMenuSpacer(), + new EditorMenuItem("Set current position as preview point") + } + }, + new EditorMenuBarItem("Web") + { + Items = new[] + { + new EditorMenuItem("This Beatmap's information page"), + new EditorMenuItem("This Beatmap's thread"), + new EditorMenuItem("Quick reply") + } + }, + new EditorMenuBarItem("Help") + { + Items = new[] + { + new EditorMenuItem("Show in-game help"), + new EditorMenuItem("View FAQ") + } + } + } + } + } + }); + } + protected override void OnResuming(Screen last) { Beatmap.Value.Track?.Stop(); diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs new file mode 100644 index 0000000000..9fd8669922 --- /dev/null +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -0,0 +1,131 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// 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.UserInterface; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Screens.Edit.Menus +{ + public class EditorMenuBar : MenuBar + { + protected override DrawableMenuBarItem CreateDrawableMenuBarItem(MenuItem item) => new DrawableEditorMenuBarItem(item); + + private class DrawableEditorMenuBarItem : DrawableMenuBarItem + { + private const int fade_duration = 250; + private const float text_size = 14; + + private readonly Container background; + + private Color4 normalColour; + + public DrawableEditorMenuBarItem(MenuItem item) + : base(item) + { + Text.Padding = new MarginPadding(8); + + AddInternal(background = new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + Depth = float.MaxValue, + Alpha = 0, + Child = new Container + { + // The following is done so we can have top rounded corners but not bottom corners + RelativeSizeAxes = Axes.Both, + Height = 2, + Masking = true, + CornerRadius = 5, + Child = new Box { RelativeSizeAxes = Axes.Both } + } + }); + + Menu.OnOpen += menuOpen; + Menu.OnClose += menuClose; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Gray3; + Text.Colour = normalColour = colours.BlueLight; + } + + private void menuOpen() + { + background.FadeIn(fade_duration, Easing.OutQuint); + Text.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + } + + private void menuClose() + { + background.FadeOut(fade_duration, Easing.OutQuint); + Text.FadeColour(normalColour, fade_duration, Easing.OutQuint); + } + + protected override SpriteText CreateText() => new OsuSpriteText { TextSize = text_size }; + + protected override Framework.Graphics.UserInterface.Menu CreateMenu() => new EditorMenu(); + + private class EditorMenu : OsuMenu + { + public EditorMenu() + { + Anchor = Anchor.BottomLeft; + BypassAutoSizeAxes = Axes.Both; + OriginPosition = new Vector2(8, 0); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Gray3; + } + + protected override MarginPadding ItemFlowContainerPadding => new MarginPadding { Top = 5, Bottom = 5 }; + + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableEditorMenuItem(item); + + private class DrawableEditorMenuItem : DrawableOsuMenuItem + { + public override bool HandleInput => !isSpacer; + private readonly bool isSpacer; + + public DrawableEditorMenuItem(MenuItem item) + : base(item) + { + isSpacer = item is EditorMenuSpacer; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Gray3; + BackgroundColourHover = colours.Gray2; + } + + protected override TextContainer CreateTextContainer() => new EditorTextContainer(); + + private class EditorTextContainer : TextContainer + { + public EditorTextContainer() + { + BoldText.TextSize = text_size; + NormalText.TextSize = text_size; + } + } + } + } + } + } +} diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs new file mode 100644 index 0000000000..201bc6e5c3 --- /dev/null +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit.Menus +{ + public class EditorMenuBarItem : MenuItem + { + public EditorMenuBarItem(string text) + : base(text) + { + } + } +} diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuItem.cs b/osu.Game/Screens/Edit/Menus/EditorMenuItem.cs new file mode 100644 index 0000000000..c7e36522cf --- /dev/null +++ b/osu.Game/Screens/Edit/Menus/EditorMenuItem.cs @@ -0,0 +1,23 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit.Menus +{ + public class EditorMenuItem : OsuMenuItem + { + private const int min_text_length = 40; + + public EditorMenuItem(string text, MenuItemType type = MenuItemType.Standard) + : base(text.PadRight(min_text_length), type) + { + } + + public EditorMenuItem(string text, MenuItemType type, Action action) + : base(text.PadRight(min_text_length), type, action) + { + } + } +} diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs b/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs new file mode 100644 index 0000000000..0e01992846 --- /dev/null +++ b/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Screens.Edit.Menus +{ + public class EditorMenuSpacer : EditorMenuItem + { + public EditorMenuSpacer() + : base(" ") + { + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 325cfba986..05ba3e25ab 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -133,6 +133,10 @@ + + + + From 6304a685c3317b143d7d5d6d3e75769bf7d61dca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 29 Aug 2017 14:43:23 +0900 Subject: [PATCH 34/93] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index c7457f0ce9..167d5cda8f 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit c7457f0ce9ef3f663ee800f6b7fc574e9abff1da +Subproject commit 167d5cda8f3ddae702ffc8d8d22dac67e48b509c From 57678a13d9d3faf49fe0f422b8716893a73bf7f8 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 4 Sep 2017 09:10:04 +0900 Subject: [PATCH 35/93] Update in-line with framework changes. --- osu-framework | 2 +- osu.Game/Beatmaps/Drawables/BeatmapGroup.cs | 9 ++++++++- osu.Game/Beatmaps/Drawables/Panel.cs | 9 ++++++++- .../Containers/OsuFocusedOverlayContainer.cs | 6 +++--- .../Graphics/UserInterface/BreadcrumbControl.cs | 6 ++++++ .../Graphics/UserInterface/OsuContextMenu.cs | 9 +++++---- osu.Game/Graphics/UserInterface/OsuDropdown.cs | 14 +++++--------- osu.Game/Graphics/UserInterface/OsuMenu.cs | 16 +++++++--------- osu.Game/OsuGame.cs | 4 ++-- osu.Game/Overlays/ChatOverlay.cs | 2 +- osu.Game/Overlays/DialogOverlay.cs | 2 +- osu.Game/Overlays/MainSettings.cs | 2 +- osu.Game/Overlays/MedalSplash/DrawableMedal.cs | 5 +++++ osu.Game/Overlays/MusicController.cs | 2 +- .../Settings/Sections/General/LoginSettings.cs | 4 ++-- osu.Game/Overlays/Settings/Sidebar.cs | 6 ++++++ .../Toolbar/ToolbarOverlayToggleButton.cs | 2 +- osu.Game/Overlays/WaveOverlayContainer.cs | 5 +++++ osu.Game/Screens/Menu/Button.cs | 4 ++++ osu.Game/Screens/Menu/ButtonSystem.cs | 4 ++++ osu.Game/Screens/Play/SkipButton.cs | 8 +++++++- osu.Game/Screens/Play/SquareGraph.cs | 6 ++++++ .../Select/Leaderboards/LeaderboardScore.cs | 8 ++++++++ 23 files changed, 97 insertions(+), 38 deletions(-) diff --git a/osu-framework b/osu-framework index 2bd341b29d..5c0e50379e 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 2bd341b29d6a7ed864aa9c1c5fad4668dafe03a4 +Subproject commit 5c0e50379e47a3805097dbc36a713decc64f49ce diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index 4a389101e2..c66bf637e2 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -11,6 +11,8 @@ namespace osu.Game.Beatmaps.Drawables { public class BeatmapGroup : IStateful { + public event Action StateChanged; + public BeatmapPanel SelectedPanel; /// @@ -42,6 +44,10 @@ namespace osu.Game.Beatmaps.Drawables get { return state; } set { + if (state == value) + return; + state = value; + switch (value) { case BeatmapGroupState.Expanded: @@ -60,7 +66,8 @@ namespace osu.Game.Beatmaps.Drawables panel.State = PanelSelectedState.Hidden; break; } - state = value; + + StateChanged?.Invoke(state); } } diff --git a/osu.Game/Beatmaps/Drawables/Panel.cs b/osu.Game/Beatmaps/Drawables/Panel.cs index d07be88392..d6ed306b39 100644 --- a/osu.Game/Beatmaps/Drawables/Panel.cs +++ b/osu.Game/Beatmaps/Drawables/Panel.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -15,6 +16,8 @@ namespace osu.Game.Beatmaps.Drawables { public const float MAX_HEIGHT = 80; + public event Action StateChanged; + public override bool RemoveWhenNotAlive => false; private readonly Container nestedContainer; @@ -77,11 +80,15 @@ namespace osu.Game.Beatmaps.Drawables set { - if (state == value) return; + if (state == value) + return; var last = state; state = value; + ApplyState(last); + + StateChanged?.Invoke(State); } } diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 0713fa1a52..4ea4f4cdc3 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -19,12 +19,12 @@ namespace osu.Game.Graphics.Containers samplePopIn = audio.Sample.Get(@"UI/melodic-5"); samplePopOut = audio.Sample.Get(@"UI/melodic-4"); - StateChanged += OsuFocusedOverlayContainer_StateChanged; + StateChanged += onStateChanged; } - private void OsuFocusedOverlayContainer_StateChanged(VisibilityContainer arg1, Visibility arg2) + private void onStateChanged(Visibility visibility) { - switch (arg2) + switch (visibility) { case Visibility.Visible: samplePopIn?.Play(); diff --git a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs index b3e53280fb..65ece51a70 100644 --- a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using OpenTK; using osu.Framework; using osu.Framework.Graphics; @@ -35,6 +36,8 @@ namespace osu.Game.Graphics.UserInterface private class BreadcrumbTabItem : OsuTabItem, IStateful { + public event Action StateChanged; + public readonly SpriteIcon Chevron; //don't allow clicking between transitions and don't make the chevron clickable @@ -42,6 +45,7 @@ namespace osu.Game.Graphics.UserInterface public override bool HandleInput => State == Visibility.Visible; private Visibility state; + public Visibility State { get { return state; } @@ -62,6 +66,8 @@ namespace osu.Game.Graphics.UserInterface this.FadeOut(transition_duration, Easing.OutQuint); this.ScaleTo(new Vector2(0.8f, 1f), transition_duration, Easing.OutQuint); } + + StateChanged?.Invoke(State); } } diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs index 808c72ee5d..4ce6c98744 100644 --- a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs @@ -14,14 +14,17 @@ namespace osu.Game.Graphics.UserInterface private const int fade_duration = 250; public OsuContextMenu() + : base(Direction.Vertical) { - CornerRadius = 5; - EdgeEffect = new EdgeEffectParameters + MaskingContainer.CornerRadius = 5; + MaskingContainer.EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.1f), Radius = 4, }; + + ItemsContainer.Padding = new MarginPadding { Vertical = DrawableOsuMenuItem.MARGIN_VERTICAL }; } [BackgroundDependencyLoader] @@ -32,7 +35,5 @@ namespace osu.Game.Graphics.UserInterface protected override void AnimateOpen() => this.FadeIn(fade_duration, Easing.OutQuint); protected override void AnimateClose() => this.FadeOut(fade_duration, Easing.OutQuint); - - protected override MarginPadding ItemFlowContainerPadding => new MarginPadding { Vertical = DrawableOsuMenuItem.MARGIN_VERTICAL }; } } \ No newline at end of file diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index dde154bb61..275cc2ab64 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -57,6 +57,9 @@ namespace osu.Game.Graphics.UserInterface { CornerRadius = 4; BackgroundColour = Color4.Black.Opacity(0.5f); + + // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring + ItemsContainer.Padding = new MarginPadding(5); } // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring @@ -64,14 +67,7 @@ namespace osu.Game.Graphics.UserInterface protected override void AnimateClose() => this.FadeOut(300, Easing.OutQuint); // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring - protected override MarginPadding ItemFlowContainerPadding => new MarginPadding(5); - - // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring - protected override void UpdateMenuHeight() - { - var actualHeight = (RelativeSizeAxes & Axes.Y) > 0 ? 1 : ContentHeight; - this.ResizeHeightTo(State == MenuState.Opened ? actualHeight : 0, 300, Easing.OutQuint); - } + protected override void UpdateSize(Vector2 newSize) => this.ResizeTo(newSize, 300, Easing.OutQuint); private Color4 accentColour; public Color4 AccentColour @@ -141,7 +137,7 @@ namespace osu.Game.Graphics.UserInterface protected override Drawable CreateContent() => new Content(); - protected class Content : FillFlowContainer, IHasText + protected new class Content : FillFlowContainer, IHasText { public string Text { diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index ab37fd2c90..a8cb8cafbb 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -12,27 +12,25 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; using osu.Game.Graphics.Sprites; +using OpenTK; namespace osu.Game.Graphics.UserInterface { public class OsuMenu : Menu { - public OsuMenu() + public OsuMenu(Direction direction) + : base(direction) { - CornerRadius = 4; BackgroundColour = Color4.Black.Opacity(0.5f); + + MaskingContainer.CornerRadius = 4; + ItemsContainer.Padding = new MarginPadding(5); } protected override void AnimateOpen() => this.FadeIn(300, Easing.OutQuint); protected override void AnimateClose() => this.FadeOut(300, Easing.OutQuint); - protected override void UpdateMenuHeight() - { - var actualHeight = (RelativeSizeAxes & Axes.Y) > 0 ? 1 : ContentHeight; - this.ResizeHeightTo(State == MenuState.Opened ? actualHeight : 0, 300, Easing.OutQuint); - } - - protected override MarginPadding ItemFlowContainerPadding => new MarginPadding(5); + protected override void UpdateSize(Vector2 newSize) => this.ResizeTo(newSize, 300, Easing.OutQuint); protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuMenuItem(item); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 30bc09d50f..c020675881 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -230,13 +230,13 @@ namespace osu.Game var singleDisplayOverlays = new OverlayContainer[] { chat, social, direct }; foreach (var overlay in singleDisplayOverlays) { - overlay.StateChanged += (container, state) => + overlay.StateChanged += state => { if (state == Visibility.Hidden) return; foreach (var c in singleDisplayOverlays) { - if (c == container) continue; + if (c == overlay) continue; c.State = Visibility.Hidden; } }; diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 6dd5425fd1..b5bb1a2d9f 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -169,7 +169,7 @@ namespace osu.Game.Overlays channelTabs.Current.ValueChanged += newChannel => CurrentChannel = newChannel; channelTabs.ChannelSelectorActive.ValueChanged += value => channelSelection.State = value ? Visibility.Visible : Visibility.Hidden; - channelSelection.StateChanged += (overlay, state) => + channelSelection.StateChanged += state => { channelTabs.ChannelSelectorActive.Value = state == Visibility.Visible; diff --git a/osu.Game/Overlays/DialogOverlay.cs b/osu.Game/Overlays/DialogOverlay.cs index 012e93f10d..7853eefd2c 100644 --- a/osu.Game/Overlays/DialogOverlay.cs +++ b/osu.Game/Overlays/DialogOverlay.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays dialogContainer.Add(currentDialog); currentDialog.Show(); - currentDialog.StateChanged += onDialogOnStateChanged; + currentDialog.StateChanged += state => onDialogOnStateChanged(dialog, state); State = Visibility.Visible; } diff --git a/osu.Game/Overlays/MainSettings.cs b/osu.Game/Overlays/MainSettings.cs index b4d9cac045..4fe86d62fd 100644 --- a/osu.Game/Overlays/MainSettings.cs +++ b/osu.Game/Overlays/MainSettings.cs @@ -53,7 +53,7 @@ namespace osu.Game.Overlays private const float hidden_width = 120; - private void keyBindingOverlay_StateChanged(VisibilityContainer container, Visibility visibility) + private void keyBindingOverlay_StateChanged(Visibility visibility) { switch (visibility) { diff --git a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs index 56b26e7176..3ac8af7b2b 100644 --- a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs +++ b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Framework; using OpenTK; using osu.Framework.Allocation; @@ -19,6 +20,8 @@ namespace osu.Game.Overlays.MedalSplash private const float scale_when_unlocked = 0.76f; private const float scale_when_full = 0.6f; + public event Action StateChanged; + private readonly Medal medal; private readonly Container medalContainer; private readonly Sprite medalSprite, medalGlow; @@ -132,6 +135,8 @@ namespace osu.Game.Overlays.MedalSplash state = value; updateState(); + + StateChanged?.Invoke(State); } } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index cb4628825e..0a06439c3e 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -204,7 +204,7 @@ namespace osu.Game.Overlays beatmapBacking.BindTo(game.Beatmap); - playlist.StateChanged += (c, s) => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint); + playlist.StateChanged += s => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint); } protected override void LoadComplete() diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index a816fa56c1..e62050fae1 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -292,6 +292,8 @@ namespace osu.Game.Overlays.Settings.Sections.General Colour = Color4.Black.Opacity(0.25f), Radius = 4, }; + + ItemsContainer.Padding = new MarginPadding(); } [BackgroundDependencyLoader] @@ -300,8 +302,6 @@ namespace osu.Game.Overlays.Settings.Sections.General BackgroundColour = colours.Gray3; } - protected override MarginPadding ItemFlowContainerPadding => new MarginPadding(); - protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableUserDropdownMenuItem(item); private class DrawableUserDropdownMenuItem : DrawableOsuDropdownMenuItem diff --git a/osu.Game/Overlays/Settings/Sidebar.cs b/osu.Game/Overlays/Settings/Sidebar.cs index b22a5ab126..55167188a3 100644 --- a/osu.Game/Overlays/Settings/Sidebar.cs +++ b/osu.Game/Overlays/Settings/Sidebar.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Linq; using osu.Framework; using OpenTK; @@ -19,6 +20,9 @@ namespace osu.Game.Overlays.Settings private readonly FillFlowContainer content; internal const float DEFAULT_WIDTH = ToolbarButton.WIDTH; internal const int EXPANDED_WIDTH = 200; + + public event Action StateChanged; + protected override Container Content => content; public Sidebar() @@ -102,6 +106,8 @@ namespace osu.Game.Overlays.Settings this.ResizeTo(new Vector2(EXPANDED_WIDTH, Height), 500, Easing.OutQuint); break; } + + StateChanged?.Invoke(State); } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs index 6d61a096b2..c530e8d7ff 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs @@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Toolbar stateContainer.StateChanged -= stateChanged; } - private void stateChanged(VisibilityContainer c, Visibility state) + private void stateChanged(Visibility state) { switch (state) { diff --git a/osu.Game/Overlays/WaveOverlayContainer.cs b/osu.Game/Overlays/WaveOverlayContainer.cs index fd89dcfbc4..4f9783a762 100644 --- a/osu.Game/Overlays/WaveOverlayContainer.cs +++ b/osu.Game/Overlays/WaveOverlayContainer.cs @@ -167,6 +167,8 @@ namespace osu.Game.Overlays private class Wave : Container, IStateful { + public event Action StateChanged; + public float FinalPosition; public Wave() @@ -200,6 +202,7 @@ namespace osu.Game.Overlays } private Visibility state; + public Visibility State { get { return state; } @@ -216,6 +219,8 @@ namespace osu.Game.Overlays this.MoveToY(FinalPosition, APPEAR_DURATION, easing_show); break; } + + StateChanged?.Invoke(State); } } } diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index 0898c079ce..aca169c3dc 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -28,6 +28,8 @@ namespace osu.Game.Screens.Menu /// public class Button : BeatSyncedContainer, IStateful { + public event Action StateChanged; + private readonly Container iconText; private readonly Container box; private readonly Box boxHoverLayer; @@ -266,6 +268,8 @@ namespace osu.Game.Screens.Menu this.FadeOut(explode_duration / 4f * 3); break; } + + StateChanged?.Invoke(State); } } } diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 71f2a16c09..e4dbe00a80 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -22,6 +22,8 @@ namespace osu.Game.Screens.Menu { public class ButtonSystem : Container, IStateful { + public event Action StateChanged; + public Action OnEdit; public Action OnExit; public Action OnDirect; @@ -294,6 +296,8 @@ namespace osu.Game.Screens.Menu backButton.State = state == MenuState.Play ? ButtonState.Expanded : ButtonState.Contracted; settingsButton.State = state == MenuState.TopLevel ? ButtonState.Expanded : ButtonState.Contracted; } + + StateChanged?.Invoke(State); } } diff --git a/osu.Game/Screens/Play/SkipButton.cs b/osu.Game/Screens/Play/SkipButton.cs index 3cf371f1e1..6519a8db36 100644 --- a/osu.Game/Screens/Play/SkipButton.cs +++ b/osu.Game/Screens/Play/SkipButton.cs @@ -133,6 +133,8 @@ namespace osu.Game.Screens.Play private class FadeContainer : Container, IStateful { + public event Action StateChanged; + private Visibility state; private ScheduledDelegate scheduledHide; @@ -144,8 +146,10 @@ namespace osu.Game.Screens.Play } set { - var lastState = state; + if (state == value) + return; + var lastState = state; state = value; scheduledHide?.Cancel(); @@ -164,6 +168,8 @@ namespace osu.Game.Screens.Play this.FadeOut(1000, Easing.OutExpo); break; } + + StateChanged?.Invoke(State); } } diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index f3bb523611..81dbf3eca4 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // 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; @@ -170,6 +171,8 @@ namespace osu.Game.Screens.Play private const float padding = 2; public const float WIDTH = cube_size + padding; + public event Action StateChanged; + private readonly List drawableRows = new List(); private float filled; @@ -186,6 +189,7 @@ namespace osu.Game.Screens.Play } private ColumnState state; + public ColumnState State { get { return state; } @@ -196,6 +200,8 @@ namespace osu.Game.Screens.Play if (IsLoaded) fillActive(); + + StateChanged?.Invoke(State); } } diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs index d7c85fff90..2987f4476c 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics; @@ -21,6 +22,8 @@ namespace osu.Game.Screens.Select.Leaderboards { public static readonly float HEIGHT = 60; + public event Action StateChanged; + public readonly int RankPosition; public readonly Score Score; @@ -41,11 +44,14 @@ namespace osu.Game.Screens.Select.Leaderboards private readonly FillFlowContainer modsContainer; private Visibility state; + public Visibility State { get { return state; } set { + if (state == value) + return; state = value; switch (state) @@ -88,6 +94,8 @@ namespace osu.Game.Screens.Select.Leaderboards break; } + + StateChanged?.Invoke(State); } } From 2a64bcda85aaa686fbefee7e22fb0a0dca9bd928 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 4 Sep 2017 09:32:44 +0900 Subject: [PATCH 36/93] Fix resizing bug(?). --- osu.Game/Graphics/UserInterface/OsuDropdown.cs | 14 +++++++++++++- osu.Game/Graphics/UserInterface/OsuMenu.cs | 14 +++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index 275cc2ab64..b69186e8b0 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -67,7 +67,19 @@ namespace osu.Game.Graphics.UserInterface protected override void AnimateClose() => this.FadeOut(300, Easing.OutQuint); // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring - protected override void UpdateSize(Vector2 newSize) => this.ResizeTo(newSize, 300, Easing.OutQuint); + protected override void UpdateSize(Vector2 newSize) + { + if (Direction == Direction.Vertical) + { + Width = newSize.X; + this.ResizeHeightTo(newSize.Y, 300, Easing.OutQuint); + } + else + { + Height = newSize.Y; + this.ResizeWidthTo(newSize.X, 300, Easing.OutQuint); + } + } private Color4 accentColour; public Color4 AccentColour diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index a8cb8cafbb..103155dd1f 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -30,7 +30,19 @@ namespace osu.Game.Graphics.UserInterface protected override void AnimateOpen() => this.FadeIn(300, Easing.OutQuint); protected override void AnimateClose() => this.FadeOut(300, Easing.OutQuint); - protected override void UpdateSize(Vector2 newSize) => this.ResizeTo(newSize, 300, Easing.OutQuint); + protected override void UpdateSize(Vector2 newSize) + { + if (Direction == Direction.Vertical) + { + Width = newSize.X; + this.ResizeHeightTo(newSize.Y, 300, Easing.OutQuint); + } + else + { + Height = newSize.Y; + this.ResizeWidthTo(newSize.X, 300, Easing.OutQuint); + } + } protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuMenuItem(item); From 24f7fbe1e5d7ad1d0b4637a1b750c25bc787ccf0 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 5 Sep 2017 19:14:37 +0900 Subject: [PATCH 37/93] Update framework. --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 5c0e50379e..3edf658577 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 5c0e50379e47a3805097dbc36a713decc64f49ce +Subproject commit 3edf65857759f32d5a6d07ed523a2892b09c3c6a From b871323ed8091577a151cd3285152408db0e6643 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 5 Sep 2017 19:26:28 +0900 Subject: [PATCH 38/93] Fix BeatmapGroup initialization not correctly setting panels to Hidden. --- osu.Game/Beatmaps/Drawables/BeatmapGroup.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index c66bf637e2..9c62289bfa 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -33,19 +33,16 @@ namespace osu.Game.Beatmaps.Drawables public BeatmapSetHeader Header; - private BeatmapGroupState state; - public List BeatmapPanels; public BeatmapSetInfo BeatmapSet; + private BeatmapGroupState state; public BeatmapGroupState State { get { return state; } set { - if (state == value) - return; state = value; switch (value) @@ -97,6 +94,7 @@ namespace osu.Game.Beatmaps.Drawables Header.AddDifficultyIcons(BeatmapPanels); } + private void headerGainedSelection(BeatmapSetHeader panel) { State = BeatmapGroupState.Expanded; From 0fc2e49ce6b12f2003f043135189293653ea2247 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 5 Sep 2017 19:33:20 +0900 Subject: [PATCH 39/93] Remove second calculateScore call --- osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 8432c5b26a..41e0dbff41 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -110,8 +110,6 @@ namespace osu.Game.Rulesets.Osu.Scoring } calculateScore(); - - calculateScore(); } private void calculateScore() From 05f5dfba81c5dd0d2cdf52c8cf933d921f3515db Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 5 Sep 2017 13:57:30 +0200 Subject: [PATCH 40/93] Change difficulty colors and add ExpertPlus ExpertPlus is for beatmaps above 6.75* --- .../Drawables/DifficultyColouredContainer.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs b/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs index 2614baa116..41b77f6584 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs @@ -33,7 +33,8 @@ namespace osu.Game.Beatmaps.Drawables Normal, Hard, Insane, - Expert + Expert, + ExpertPlus } private DifficultyRating getDifficultyRating(BeatmapInfo beatmap) @@ -44,7 +45,8 @@ namespace osu.Game.Beatmaps.Drawables if (rating < 2.25) return DifficultyRating.Normal; if (rating < 3.75) return DifficultyRating.Hard; if (rating < 5.25) return DifficultyRating.Insane; - return DifficultyRating.Expert; + if (rating < 6.75) return DifficultyRating.Expert; + return DifficultyRating.ExpertPlus; } private Color4 getColour(BeatmapInfo beatmap) @@ -55,12 +57,14 @@ namespace osu.Game.Beatmaps.Drawables return palette.Green; default: case DifficultyRating.Normal: - return palette.Yellow; + return palette.Blue; case DifficultyRating.Hard: - return palette.Pink; + return palette.Yellow; case DifficultyRating.Insane: - return palette.Purple; + return palette.Pink; case DifficultyRating.Expert: + return palette.Purple; + case DifficultyRating.ExpertPlus: return palette.Gray0; } } From 081b98ef39c3678ce7c5960505e86fe41627a711 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 5 Sep 2017 21:30:14 +0900 Subject: [PATCH 41/93] "Use" the hitobject Obviously temporary. --- .../Scoring/OsuScoreProcessor.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 41e0dbff41..3ee8f56665 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -44,13 +44,16 @@ namespace osu.Game.Rulesets.Osu.Scoring foreach (var h in beatmap.HitObjects) { - // TODO: add support for other object types. - AddJudgement(new OsuJudgement + if (h != null) { - MaxScore = OsuScoreResult.Hit300, - Score = OsuScoreResult.Hit300, - Result = HitResult.Hit - }); + // TODO: add support for other object types. + AddJudgement(new OsuJudgement + { + MaxScore = OsuScoreResult.Hit300, + Score = OsuScoreResult.Hit300, + Result = HitResult.Hit + }); + } } } From 1e10d977f9c3e7e166a1a4cdecdd1c7837c61073 Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 5 Sep 2017 15:39:27 +0200 Subject: [PATCH 42/93] Accuracy starts at 100% instead of 0% --- osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index 647a1381c6..83203f5a7e 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -268,6 +268,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring base.Reset(); Health.Value = 0; + Accuracy.Value = 1; bonusScore = 0; comboPortion = 0; From 4f4b0a1f351bca177c094a190e274e5ed50cc72d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Sep 2017 20:26:01 +0900 Subject: [PATCH 43/93] Allow posting to chat in all channels --- osu.Game/Online/Chat/Channel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index bec4aadb18..77683ae857 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -30,7 +30,7 @@ namespace osu.Game.Online.Chat public Bindable Joined = new Bindable(); - public bool ReadOnly => Name != "#lazer"; + public bool ReadOnly => false; public const int MAX_HISTORY = 300; From e834e0e9580aa3762812be9ac29e6a6be1e959d2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Sep 2017 21:07:53 +0900 Subject: [PATCH 44/93] Fix incorrect initialisation order causing mania key bindings to not work --- osu.Game/Rulesets/UI/RulesetContainer.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index a7472f4dbc..e2701faca0 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -75,7 +75,11 @@ namespace osu.Game.Rulesets.UI internal RulesetContainer(Ruleset ruleset) { Ruleset = ruleset; + } + [BackgroundDependencyLoader] + private void load() + { KeyBindingInputManager = CreateInputManager(); KeyBindingInputManager.RelativeSizeAxes = Axes.Both; } From 06fac913bfe5c03e479fca450a5f45ac0ad006cf Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 6 Sep 2017 21:14:29 +0900 Subject: [PATCH 45/93] Re-implement EditorMenuBar. --- osu-framework | 2 +- osu.Game/Graphics/UserInterface/OsuMenu.cs | 6 +- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 160 +++++++++---------- 3 files changed, 83 insertions(+), 85 deletions(-) diff --git a/osu-framework b/osu-framework index 3edf658577..3e91706ad5 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 3edf65857759f32d5a6d07ed523a2892b09c3c6a +Subproject commit 3e91706ad54609c9477588730b5de7db9d1311f8 diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index 3c9b9797ba..4e23a8939d 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -46,6 +46,11 @@ namespace osu.Game.Graphics.UserInterface protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuMenuItem(item); + protected override Menu CreateSubMenu() => new OsuMenu(Direction.Vertical) + { + Anchor = Direction == Direction.Horizontal ? Anchor.BottomLeft : Anchor.TopRight + }; + protected class DrawableOsuMenuItem : DrawableMenuItem { private const int margin_horizontal = 17; @@ -61,7 +66,6 @@ namespace osu.Game.Graphics.UserInterface public DrawableOsuMenuItem(MenuItem item) : base(item) { - } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index 9fd8669922..15610fcebd 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -5,125 +5,119 @@ 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.UserInterface; +using osu.Framework.Input; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using OpenTK; using OpenTK.Graphics; namespace osu.Game.Screens.Edit.Menus { - public class EditorMenuBar : MenuBar + public class EditorMenuBar : OsuMenu { - protected override DrawableMenuBarItem CreateDrawableMenuBarItem(MenuItem item) => new DrawableEditorMenuBarItem(item); - - private class DrawableEditorMenuBarItem : DrawableMenuBarItem + public EditorMenuBar() + : base(Direction.Horizontal) { - private const int fade_duration = 250; - private const float text_size = 14; + AlwaysOpen = true; + RequireClickToOpen = true; - private readonly Container background; + ItemsContainer.Padding = new MarginPadding(0); + BackgroundColour = Color4.Transparent; + } - private Color4 normalColour; + protected override Framework.Graphics.UserInterface.Menu CreateSubMenu() => new SubMenu(); - public DrawableEditorMenuBarItem(MenuItem item) + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableEditorBarMenuItem(item); + + private class DrawableEditorBarMenuItem : DrawableOsuMenuItem + { + private Color4 openedForegroundColour; + private Color4 openedBackgroundColour; + + public DrawableEditorBarMenuItem(MenuItem item) : base(item) { - Text.Padding = new MarginPadding(8); - - AddInternal(background = new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Depth = float.MaxValue, - Alpha = 0, - Child = new Container - { - // The following is done so we can have top rounded corners but not bottom corners - RelativeSizeAxes = Axes.Both, - Height = 2, - Masking = true, - CornerRadius = 5, - Child = new Box { RelativeSizeAxes = Axes.Both } - } - }); - - Menu.OnOpen += menuOpen; - Menu.OnClose += menuClose; } [BackgroundDependencyLoader] private void load(OsuColour colours) { - background.Colour = colours.Gray3; - Text.Colour = normalColour = colours.BlueLight; + ForegroundColour = ForegroundColourHover = colours.BlueLight; + BackgroundColour = BackgroundColourHover = Color4.Transparent; + openedForegroundColour = Color4.White; + openedBackgroundColour = colours.Gray3; } - private void menuOpen() + protected override void UpdateBackgroundColour() { - background.FadeIn(fade_duration, Easing.OutQuint); - Text.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + if (State == MenuItemState.Selected) + Background.FadeColour(openedBackgroundColour); + else + base.UpdateBackgroundColour(); } - private void menuClose() + protected override void UpdateForegroundColour() { - background.FadeOut(fade_duration, Easing.OutQuint); - Text.FadeColour(normalColour, fade_duration, Easing.OutQuint); + if (State == MenuItemState.Selected) + Foreground.FadeColour(openedForegroundColour); + else + base.UpdateForegroundColour(); } - protected override SpriteText CreateText() => new OsuSpriteText { TextSize = text_size }; - - protected override Framework.Graphics.UserInterface.Menu CreateMenu() => new EditorMenu(); - - private class EditorMenu : OsuMenu + protected override Drawable CreateBackground() => new Container { - public EditorMenu() + RelativeSizeAxes = Axes.Both, + Masking = true, + Child = new Container + { + RelativeSizeAxes = Axes.Both, + Height = 2, + Masking = true, + CornerRadius = 4, + Child = new Box { RelativeSizeAxes = Axes.Both } + } + }; + } + + private class SubMenu : OsuMenu + { + public SubMenu() + : base(Direction.Vertical) + { + OriginPosition = new Vector2(5, 1); + ItemsContainer.Padding = new MarginPadding { Top = 5, Bottom = 5 }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Gray3; + } + + protected override Framework.Graphics.UserInterface.Menu CreateSubMenu() => new SubMenu(); + + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableSubMenuItem(item); + + private class DrawableSubMenuItem : DrawableOsuMenuItem + { + public DrawableSubMenuItem(MenuItem item) + : base(item) { - Anchor = Anchor.BottomLeft; - BypassAutoSizeAxes = Axes.Both; - OriginPosition = new Vector2(8, 0); } - [BackgroundDependencyLoader] - private void load(OsuColour colours) + protected override bool OnHover(InputState state) { - BackgroundColour = colours.Gray3; + if (Item is EditorMenuSpacer) + return true; + return base.OnHover(state); } - protected override MarginPadding ItemFlowContainerPadding => new MarginPadding { Top = 5, Bottom = 5 }; - - protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableEditorMenuItem(item); - - private class DrawableEditorMenuItem : DrawableOsuMenuItem + protected override bool OnClick(InputState state) { - public override bool HandleInput => !isSpacer; - private readonly bool isSpacer; - - public DrawableEditorMenuItem(MenuItem item) - : base(item) - { - isSpacer = item is EditorMenuSpacer; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - BackgroundColour = colours.Gray3; - BackgroundColourHover = colours.Gray2; - } - - protected override TextContainer CreateTextContainer() => new EditorTextContainer(); - - private class EditorTextContainer : TextContainer - { - public EditorTextContainer() - { - BoldText.TextSize = text_size; - NormalText.TextSize = text_size; - } - } + if (Item is EditorMenuSpacer) + return true; + return base.OnClick(state); } } } From f70b4839bd80834720e2d205f097d014ec30bfb8 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 6 Sep 2017 21:22:23 +0900 Subject: [PATCH 46/93] Remove a few unnecessary attributes in OsuTestCase. --- osu.Desktop.Tests/Visual/OsuTestCase.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Desktop.Tests/Visual/OsuTestCase.cs b/osu.Desktop.Tests/Visual/OsuTestCase.cs index e366aecb21..1b48ded4e2 100644 --- a/osu.Desktop.Tests/Visual/OsuTestCase.cs +++ b/osu.Desktop.Tests/Visual/OsuTestCase.cs @@ -1,17 +1,14 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using NUnit.Framework; using osu.Framework.Desktop.Platform; using osu.Framework.Testing; using osu.Game; namespace osu.Desktop.Tests.Visual { - [TestFixture] public abstract class OsuTestCase : TestCase { - [Test] public override void RunTest() { using (var host = new HeadlessGameHost(realtime: false)) From 940c45b6d199fafcec8f440a9c68ae93746eb361 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Sep 2017 21:43:20 +0900 Subject: [PATCH 47/93] Fix visual styling and code styling --- osu.Game/Overlays/Chat/ChatTabControl.cs | 72 ++++++++++++++++++------ 1 file changed, 55 insertions(+), 17 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index 5b65f7c036..6498761832 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -64,10 +64,10 @@ namespace osu.Game.Overlays.Chat protected override TabItem CreateTabItem(Channel value) { - ChannelTabItem tab = new ChannelTabItem(value); - tab.OnRequestClose = () => onTabClose(tab); + ChannelTabItem tab = new ChannelTabItem(value); + tab.OnRequestClose = () => onTabClose(tab); - return tab; + return tab; } protected override void SelectTab(TabItem tab) @@ -108,7 +108,7 @@ namespace osu.Game.Overlays.Chat private readonly SpriteText text; private readonly SpriteText textBold; - private readonly Button closeButton; + private readonly ClickableContainer closeButton; private readonly Box box; private readonly Box highlightBox; private readonly SpriteIcon icon; @@ -129,7 +129,6 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1.1f), transition_length, Easing.OutQuint); - closeButton.MoveToX(-5f, 0.5f, Easing.OutElastic); box.FadeColour(backgroundActive, transition_length, Easing.OutQuint); highlightBox.FadeIn(transition_length, Easing.OutQuint); @@ -141,7 +140,6 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1), transition_length, Easing.OutQuint); - closeButton.MoveToX(5f, 0.5f, Easing.InElastic); box.FadeColour(backgroundInactive, transition_length, Easing.OutQuint); highlightBox.FadeOut(transition_length, Easing.OutQuint); @@ -152,7 +150,7 @@ namespace osu.Game.Overlays.Chat protected override bool OnHover(InputState state) { if (IsRemovable) - closeButton.FadeIn(1f, Easing.InBounce); + closeButton.FadeIn(200, Easing.OutQuint); if (!Active) box.FadeColour(backgroundHover, transition_length, Easing.OutQuint); @@ -161,9 +159,7 @@ namespace osu.Game.Overlays.Chat protected override void OnHoverLost(InputState state) { - if (closeButton.IsPresent) - closeButton.FadeOut(1f, Easing.OutBounce); - + closeButton.FadeOut(200, Easing.OutQuint); updateState(); } @@ -253,23 +249,65 @@ namespace osu.Game.Overlays.Chat Font = @"Exo2.0-Bold", TextSize = 18, }, - closeButton = new Button + closeButton = new CloseButton { Alpha = 0, - Width = 20, - Height = 20, - Margin = new MarginPadding { Right = 10 }, + Margin = new MarginPadding { Right = 20 }, Origin = Anchor.CentreRight, Anchor = Anchor.CentreRight, - Text = @"x", - BackgroundColour = Color4.Transparent, - Action = delegate { if (IsRemovable) OnRequestClose?.Invoke(); }, + Action = delegate + { + if (IsRemovable) OnRequestClose?.Invoke(); + }, }, }, }, }; } + public class CloseButton : ClickableContainer + { + private SpriteIcon icon; + + public CloseButton() + { + Size = new Vector2(20); + + Child = icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(0.75f), + Icon = FontAwesome.fa_close, + RelativeSizeAxes = Axes.Both, + }; + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + icon.ScaleTo(0.5f, 1000, Easing.OutQuint); + return base.OnMouseDown(state, args); + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + icon.ScaleTo(0.75f, 1000, Easing.OutElastic); + return base.OnMouseUp(state, args); + } + + protected override bool OnHover(InputState state) + { + icon.FadeColour(Color4.Red, 200, Easing.OutQuint); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + icon.FadeColour(Color4.White, 200, Easing.OutQuint); + base.OnHoverLost(state); + } + } + public class ChannelSelectorTabItem : ChannelTabItem { public override bool IsRemovable => false; From a7fa66b9f91b710ba9969757b6c6d21159879bc2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Sep 2017 22:41:03 +0900 Subject: [PATCH 48/93] Fix CI issue --- osu.Game/Overlays/Chat/ChatTabControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index 6498761832..b68bdac3b3 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -267,7 +267,7 @@ namespace osu.Game.Overlays.Chat public class CloseButton : ClickableContainer { - private SpriteIcon icon; + private readonly SpriteIcon icon; public CloseButton() { From 4f49a0c18387f6c4d3d2f3ea124f9742c468d1bb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Sep 2017 22:58:21 +0900 Subject: [PATCH 49/93] Simplify action --- osu.Game/Overlays/Chat/ChatTabControl.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index b68bdac3b3..83c0c17bc2 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -62,13 +62,7 @@ namespace osu.Game.Overlays.Chat SelectTab(item); } - protected override TabItem CreateTabItem(Channel value) - { - ChannelTabItem tab = new ChannelTabItem(value); - tab.OnRequestClose = () => onTabClose(tab); - - return tab; - } + protected override TabItem CreateTabItem(Channel value) => new ChannelTabItem(value) { OnRequestClose = onTabClose }; protected override void SelectTab(TabItem tab) { @@ -113,7 +107,7 @@ namespace osu.Game.Overlays.Chat private readonly Box highlightBox; private readonly SpriteIcon icon; - public Action OnRequestClose; + public Action OnRequestClose; private void updateState() { @@ -257,7 +251,7 @@ namespace osu.Game.Overlays.Chat Anchor = Anchor.CentreRight, Action = delegate { - if (IsRemovable) OnRequestClose?.Invoke(); + if (IsRemovable) OnRequestClose?.Invoke(this); }, }, }, From da294c96051fa950a1634ac64daaa1adeeeda51e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Sep 2017 23:10:08 +0900 Subject: [PATCH 50/93] Don't use base call when we don't have to --- osu.Game/Overlays/Chat/ChatTabControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index 83c0c17bc2..ca195a7830 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Chat Margin = new MarginPadding(10), }); - base.AddTabItem(selectorTab = new ChannelTabItem.ChannelSelectorTabItem(new Channel { Name = "+" })); + AddTabItem(selectorTab = new ChannelTabItem.ChannelSelectorTabItem(new Channel { Name = "+" })); ChannelSelectorActive.BindTo(selectorTab.Active); } From e5308b624700cd77bb3f56e68cd844906cf15e6a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Sep 2017 23:12:32 +0900 Subject: [PATCH 51/93] Method rename --- osu.Game/Overlays/Chat/ChatTabControl.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index ca195a7830..9f1028c168 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Chat SelectTab(item); } - protected override TabItem CreateTabItem(Channel value) => new ChannelTabItem(value) { OnRequestClose = onTabClose }; + protected override TabItem CreateTabItem(Channel value) => new ChannelTabItem(value) { OnRequestClose = tabCloseRequested }; protected override void SelectTab(TabItem tab) { @@ -77,7 +77,7 @@ namespace osu.Game.Overlays.Chat base.SelectTab(tab); } - private void onTabClose(TabItem tab) + private void tabCloseRequested(TabItem tab) { int totalTabs = TabContainer.Count - 1; // account for selectorTab int currentIndex = MathHelper.Clamp(TabContainer.IndexOf(tab), 1, totalTabs); From 69ff4bfa46cc51aab72dd6e17260c376fb0704c6 Mon Sep 17 00:00:00 2001 From: naoey Date: Wed, 6 Sep 2017 20:04:21 +0530 Subject: [PATCH 52/93] Fix startup crash on mono. --- osu.Game/Graphics/UserInterface/OsuDropdown.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index b69186e8b0..f605804aaa 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -96,7 +96,7 @@ namespace osu.Game.Graphics.UserInterface protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuDropdownMenuItem(item) { AccentColour = accentColour }; #region DrawableOsuDropdownMenuItem - protected class DrawableOsuDropdownMenuItem : DrawableDropdownMenuItem, IHasAccentColour + public class DrawableOsuDropdownMenuItem : DrawableDropdownMenuItem, IHasAccentColour { private Color4? accentColour; public Color4 AccentColour From b98346c79feddd797cf6a6dc1718c27727a7bf5a Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 7 Sep 2017 15:32:28 +0900 Subject: [PATCH 53/93] Update framework. --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 3e91706ad5..23d1932eae 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 3e91706ad54609c9477588730b5de7db9d1311f8 +Subproject commit 23d1932eae87a871d65624eac3e6e8deb7e286c2 From ef9b87e8c7b32b0cdcedaf2b52280731a0efa5e4 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 7 Sep 2017 16:15:25 +0900 Subject: [PATCH 54/93] Make column lights not increase in brightness when successfully pressed --- osu.Game.Rulesets.Mania/UI/Column.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index a8f5b4919d..d5bc7cc659 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -198,7 +198,7 @@ namespace osu.Game.Rulesets.Mania.UI { if (action == Action) { - background.FadeTo(background.Alpha + 0.2f, 50, Easing.OutQuint); + background.FadeTo(0.6f, 50, Easing.OutQuint); keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint); } From b085208d247d9a78fb66d659321a3a6e46a5d1a7 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 7 Sep 2017 16:15:33 +0900 Subject: [PATCH 55/93] Remove unused code --- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index d3dc920fc6..ce91fda023 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Containers; using System; using osu.Game.Graphics; using osu.Framework.Allocation; -using OpenTK.Input; using System.Linq; using System.Collections.Generic; using osu.Framework.Configuration; @@ -25,12 +24,6 @@ namespace osu.Game.Rulesets.Mania.UI { public const float HIT_TARGET_POSITION = 50; - /// - /// Default column keys, expanding outwards from the middle as more column are added. - /// E.g. 2 columns use FJ, 4 columns use DFJK, 6 use SDFJKL, etc... - /// - private static readonly Key[] default_keys = { Key.A, Key.S, Key.D, Key.F, Key.J, Key.K, Key.L, Key.Semicolon }; - private SpecialColumnPosition specialColumnPosition; /// /// The style to use for the special column. From 41398f57d65cfb8462f8e646c1453ef4e46b44e4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Sep 2017 20:36:32 +0900 Subject: [PATCH 56/93] Changes in line with framework --- osu.Game/Graphics/UserInterface/OsuMenu.cs | 4 ++-- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index 4e23a8939d..3fd5481152 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -18,8 +18,8 @@ namespace osu.Game.Graphics.UserInterface { public class OsuMenu : Menu { - public OsuMenu(Direction direction) - : base(direction) + public OsuMenu(Direction direction, bool topLevelMenu = false) + : base(direction, topLevelMenu) { BackgroundColour = Color4.Black.Opacity(0.5f); diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index 15610fcebd..24625570a1 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -17,11 +17,8 @@ namespace osu.Game.Screens.Edit.Menus public class EditorMenuBar : OsuMenu { public EditorMenuBar() - : base(Direction.Horizontal) + : base(Direction.Horizontal, true) { - AlwaysOpen = true; - RequireClickToOpen = true; - ItemsContainer.Padding = new MarginPadding(0); BackgroundColour = Color4.Transparent; } From b9bec6a983a48f6e39ccb594effe1bf1dd6a3542 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Sep 2017 23:06:35 +0900 Subject: [PATCH 57/93] CI fixes --- .../Visual/TestCaseEditorMenuBar.cs | 18 +++++----- osu.Game/Screens/Edit/Editor.cs | 34 +++++++++---------- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 4 +-- .../Edit/Menus/EditorMenuItemSpacer.cs | 4 +-- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index 9ff4f4c591..d04a12501e 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -27,22 +27,22 @@ namespace osu.Desktop.Tests.Visual new EditorMenuItem("Open Difficulty..."), new EditorMenuItem("Save"), new EditorMenuItem("Create a new Difficulty..."), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Revert to Saved"), new EditorMenuItem("Revert to Saved (Full)"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Test Beatmap"), new EditorMenuItem("Open AiMod"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Upload Beatmap..."), new EditorMenuItem("Export Package"), new EditorMenuItem("Export Map Package"), new EditorMenuItem("Import from..."), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Open Song Folder"), new EditorMenuItem("Open .osu in Notepad"), new EditorMenuItem("Open .osb in Notepad"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Exit"), } }, @@ -52,20 +52,20 @@ namespace osu.Desktop.Tests.Visual { new EditorMenuItem("Time Signature"), new EditorMenuItem("Metronome Clicks"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Add Timing Section"), new EditorMenuItem("Add Inheriting Section"), new EditorMenuItem("Reset Current Section"), new EditorMenuItem("Delete Timing Section"), new EditorMenuItem("Resnap Current Section"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Timing Setup"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Resnap All Notes", MenuItemType.Destructive), new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive), new EditorMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive), new EditorMenuItem("Delete All Timing Sections", MenuItemType.Destructive), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Set Current Position as Preview Point"), } }, diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 0454609689..be9098e3be 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -52,22 +52,22 @@ namespace osu.Game.Screens.Edit new EditorMenuItem("Open difficulty..."), new EditorMenuItem("Save"), new EditorMenuItem("Create new difficulty..."), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Revert to saved"), new EditorMenuItem("Revert to saved (full"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Test beatmap"), new EditorMenuItem("Open AiMod"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Upload Beatmap..."), new EditorMenuItem("Export package"), new EditorMenuItem("Export map package"), new EditorMenuItem("Import from..."), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Open song folder"), new EditorMenuItem("Open .osu in Notepad"), new EditorMenuItem("Open .osb in Notepad"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Exit", MenuItemType.Standard, Exit) } }, @@ -77,15 +77,15 @@ namespace osu.Game.Screens.Edit { new EditorMenuItem("Undo"), new EditorMenuItem("Redo"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Cut"), new EditorMenuItem("Copy"), new EditorMenuItem("Paste"), new EditorMenuItem("Delete"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Select all"), new EditorMenuItem("Clone"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Reverse selection"), new EditorMenuItem("Flip horizontally"), new EditorMenuItem("Flip vertically"), @@ -93,12 +93,12 @@ namespace osu.Game.Screens.Edit new EditorMenuItem("Rotate 90deg anticlockwise"), new EditorMenuItem("Rotate by..."), new EditorMenuItem("Scale by..."), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Reset selected objects' samples"), new EditorMenuItem("Reset all samples", MenuItemType.Destructive), new EditorMenuItem("Reset combo colours", MenuItemType.Destructive), new EditorMenuItem("Reset breaks", MenuItemType.Destructive), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Nudge backward"), new EditorMenuItem("Nudge forward") } @@ -110,10 +110,10 @@ namespace osu.Game.Screens.Edit new EditorMenuItem("Compose"), new EditorMenuItem("Design"), new EditorMenuItem("Timing"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Song setup..."), new EditorMenuItem("Timing setup..."), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Volume"), new EditorMenuItem("Grid level"), new EditorMenuItem("Show video"), @@ -131,7 +131,7 @@ namespace osu.Game.Screens.Edit new EditorMenuItem("Snap divisor"), new EditorMenuItem("Audio rate"), new EditorMenuItem("Grid snapping"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Create polygon cricles..."), new EditorMenuItem("Convert slider to stream"), new EditorMenuItem("Enable live mapping mode"), @@ -151,20 +151,20 @@ namespace osu.Game.Screens.Edit { new EditorMenuItem("Time signature"), new EditorMenuItem("Metronome clicks"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Add timing section"), new EditorMenuItem("Add inheriting section"), new EditorMenuItem("Reset current section"), new EditorMenuItem("Delete timing section"), new EditorMenuItem("Resnap current section"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Timing setup..."), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Resnap all notes", MenuItemType.Destructive), new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive), new EditorMenuItem("Recalculate slider lengths", MenuItemType.Destructive), new EditorMenuItem("Delete all timing sections", MenuItemType.Destructive), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Set current position as preview point") } }, diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index 24625570a1..bb349b1531 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -105,14 +105,14 @@ namespace osu.Game.Screens.Edit.Menus protected override bool OnHover(InputState state) { - if (Item is EditorMenuSpacer) + if (Item is EditorMenuItemSpacer) return true; return base.OnHover(state); } protected override bool OnClick(InputState state) { - if (Item is EditorMenuSpacer) + if (Item is EditorMenuItemSpacer) return true; return base.OnClick(state); } diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs b/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs index 0e01992846..5060165ef7 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs @@ -3,9 +3,9 @@ namespace osu.Game.Screens.Edit.Menus { - public class EditorMenuSpacer : EditorMenuItem + public class EditorMenuItemSpacer : EditorMenuItem { - public EditorMenuSpacer() + public EditorMenuItemSpacer() : base(" ") { } From 439cbd09a0a9b84af357151232c9bcb525b81ca2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Sep 2017 23:23:51 +0900 Subject: [PATCH 58/93] Fix incorrect TestCase type --- osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index d04a12501e..9cb3053ff2 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -2,13 +2,12 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Graphics; -using osu.Framework.Testing; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Edit.Menus; namespace osu.Desktop.Tests.Visual { - public class TestCaseEditorMenuBar : TestCase + public class TestCaseEditorMenuBar : OsuTestCase { public TestCaseEditorMenuBar() { From 709aa1ed3dc315e6b751784e06e509e3a83bde77 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Thu, 7 Sep 2017 18:20:14 +0200 Subject: [PATCH 59/93] Moved all online score related parsing to its own class --- .../Online/API/Requests/GetScoresRequest.cs | 11 ++++------ osu.Game/Rulesets/Scoring/OnlineScore.cs | 19 +++++++++++++++++ osu.Game/Rulesets/Scoring/Score.cs | 21 +------------------ osu.Game/osu.Game.csproj | 1 + 4 files changed, 25 insertions(+), 27 deletions(-) create mode 100644 osu.Game/Rulesets/Scoring/OnlineScore.cs diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index a902c8c807..72b8649ae0 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -22,11 +22,8 @@ namespace osu.Game.Online.API.Requests private void onSuccess(GetScoresResponse r) { - foreach (Score score in r.Scores) - { - score.Beatmap = beatmap; - score.Ruleset = beatmap.Ruleset; - } + foreach (OnlineScore score in r.Scores) + score.GetModsFor(beatmap.Ruleset); } protected override WebRequest CreateWebRequest() @@ -43,6 +40,6 @@ namespace osu.Game.Online.API.Requests public class GetScoresResponse { [JsonProperty(@"scores")] - public IEnumerable Scores; + public IEnumerable Scores; } -} \ No newline at end of file +} diff --git a/osu.Game/Rulesets/Scoring/OnlineScore.cs b/osu.Game/Rulesets/Scoring/OnlineScore.cs new file mode 100644 index 0000000000..1f652e3d6c --- /dev/null +++ b/osu.Game/Rulesets/Scoring/OnlineScore.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Linq; +using Newtonsoft.Json; + +namespace osu.Game.Rulesets.Scoring +{ + public class OnlineScore : Score + { + [JsonProperty(@"mods")] + private string[] modStrings { get; set; } + + public void GetModsFor(RulesetInfo ruleset) + { + Mods = ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); + } + } +} diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index 154188a2fa..ecc7b60986 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Linq; using System.Collections.Generic; using Newtonsoft.Json; using osu.Game.Beatmaps; @@ -28,27 +27,9 @@ namespace osu.Game.Rulesets.Scoring public int Combo { get; set; } - [JsonProperty(@"mods")] - private string[] modStrings { get; set; } - public RulesetInfo Ruleset; - private Mod[] mods; - public Mod[] Mods - { - get - { - // Evaluate the mod strings if necessary - return mods ?? (mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray()); - } - set - { - mods = value; - - // Assign the mod strings - modStrings = mods.Select(mod => mod.ShortenedName).ToArray(); - } - } + public Mod[] Mods; [JsonProperty(@"user")] public User User; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 07ab58bffc..16812c3467 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -128,6 +128,7 @@ + From e71f907f899352f656d8a55236834e4c266385f1 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Thu, 7 Sep 2017 18:36:16 +0200 Subject: [PATCH 60/93] CI fix --- osu.Game/Rulesets/Ruleset.cs | 1 - osu.Game/Rulesets/Scoring/Score.cs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 3d89afb7ff..33621662af 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -12,7 +12,6 @@ using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; -using osu.Game.Screens.Play; namespace osu.Game.Rulesets { diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index ecc7b60986..c09df06633 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -27,9 +27,9 @@ namespace osu.Game.Rulesets.Scoring public int Combo { get; set; } - public RulesetInfo Ruleset; + public RulesetInfo Ruleset { get; set; } - public Mod[] Mods; + public Mod[] Mods { get; set; } [JsonProperty(@"user")] public User User; From 5e685ff5b12e33b4cb7932e67744a80f70b19cef Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 7 Sep 2017 14:53:53 -0300 Subject: [PATCH 61/93] Rewrite BeatmapDetails to be more modular for future code sharing. --- osu.Game/Screens/Select/BeatmapDetailArea.cs | 13 +- osu.Game/Screens/Select/BeatmapDetails.cs | 676 ++++++++---------- .../Screens/Select/Details/AdvancedStats.cs | 152 ++++ osu.Game/Screens/Select/Details/BasicStats.cs | 120 ++++ .../Screens/Select/Details/FailRetryGraph.cs | 62 ++ .../Screens/Select/Details/SuccessRate.cs | 114 +++ .../Screens/Select/Details/UserRatings.cs | 122 ++++ osu.Game/osu.Game.csproj | 5 + 8 files changed, 871 insertions(+), 393 deletions(-) create mode 100644 osu.Game/Screens/Select/Details/AdvancedStats.cs create mode 100644 osu.Game/Screens/Select/Details/BasicStats.cs create mode 100644 osu.Game/Screens/Select/Details/FailRetryGraph.cs create mode 100644 osu.Game/Screens/Select/Details/SuccessRate.cs create mode 100644 osu.Game/Screens/Select/Details/UserRatings.cs diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs index 47d25585ad..9e244e1268 100644 --- a/osu.Game/Screens/Select/BeatmapDetailArea.cs +++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // 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.Game.Beatmaps; @@ -10,6 +11,8 @@ namespace osu.Game.Screens.Select { public class BeatmapDetailArea : Container { + private const float details_padding = 10; + private readonly Container content; protected override Container Content => content; @@ -66,9 +69,8 @@ namespace osu.Game.Screens.Select Details = new BeatmapDetails { RelativeSizeAxes = Axes.X, - Masking = true, - Height = 352, Alpha = 0, + Margin = new MarginPadding { Top = details_padding }, }, Leaderboard = new Leaderboard { @@ -76,5 +78,12 @@ namespace osu.Game.Screens.Select } }); } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + Details.Height = Math.Min(DrawHeight - (details_padding * 3) - BeatmapDetailAreaTabControl.HEIGHT, 450); + } } } diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index a5486efa96..8f564bb794 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -9,71 +9,188 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; 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; using osu.Framework.Graphics.Shapes; +using osu.Framework.Extensions.Color4Extensions; +using osu.Game.Screens.Select.Details; using osu.Game.Beatmaps; namespace osu.Game.Screens.Select { public class BeatmapDetails : Container { - private readonly MetadataSegment description; - private readonly MetadataSegment source; - private readonly MetadataSegment tags; + private const float spacing = 10; + private const float transition_duration = 250; - private readonly DifficultyRow circleSize; - private readonly DifficultyRow drainRate; - private readonly DifficultyRow overallDifficulty; - private readonly DifficultyRow approachRate; - private readonly DifficultyRow stars; + private readonly FillFlowContainer top, statsFlow; + private readonly AdvancedStats advanced; + private readonly DetailBox ratingsContainer; + private readonly UserRatings ratings; + private readonly ScrollContainer metadataScroll; + private readonly MetadataSection description, source, tags; + private readonly Container failRetryContainer; + private readonly FailRetryGraph failRetryGraph; + private readonly DimmedLoadingAnimation loading; - private readonly Container ratingsContainer; - private readonly Bar ratingsBar; - private readonly OsuSpriteText negativeRatings; - private readonly OsuSpriteText positiveRatings; - private readonly BarGraph ratingsGraph; - - private readonly FillFlowContainer retryFailContainer; - private readonly BarGraph retryGraph; - private readonly BarGraph failGraph; + private APIAccess api; private ScheduledDelegate pendingBeatmapSwitch; private BeatmapInfo beatmap; - public BeatmapInfo Beatmap { get { return beatmap; } - set { - if (beatmap == value) return; - + if (value == beatmap) return; beatmap = value; pendingBeatmapSwitch?.Cancel(); - pendingBeatmapSwitch = Schedule(updateStats); + pendingBeatmapSwitch = Schedule(updateStatistics); } } - private void updateStats() + public BeatmapDetails() { - if (beatmap == null) return; + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.5f), + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = spacing }, + Children = new Drawable[] + { + top = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + statsFlow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Width = 0.5f, + Spacing = new Vector2(spacing), + Padding = new MarginPadding { Right = spacing / 2 }, + Children = new[] + { + new DetailBox + { + Child = advanced = new AdvancedStats + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = spacing, Top = spacing * 2, Bottom = spacing }, + }, + }, + ratingsContainer = new DetailBox + { + Child = ratings = new UserRatings + { + RelativeSizeAxes = Axes.X, + Height = 134, + Padding = new MarginPadding { Horizontal = spacing, Top = spacing }, + }, + }, + }, + }, + metadataScroll = new ScrollContainer + { + RelativeSizeAxes = Axes.X, + Width = 0.5f, + ScrollbarVisible = false, + Padding = new MarginPadding { Left = spacing / 2 }, + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + LayoutDuration = transition_duration, + Spacing = new Vector2(spacing * 2), + Margin = new MarginPadding { Top = spacing * 2 }, + Children = new[] + { + description = new MetadataSection("Description") + { + TextColour = Color4.White.Opacity(0.75f), + }, + source = new MetadataSection("Source") + { + TextColour = Color4.White.Opacity(0.75f), + }, + tags = new MetadataSection("Tags"), + }, + }, + }, + }, + }, + failRetryContainer = new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Children = new Drawable[] + { + new OsuSpriteText + { + Text = "Points of Failure", + Font = @"Exo2.0-Bold", + TextSize = 14, + }, + failRetryGraph = new FailRetryGraph + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 14 + spacing / 2 }, + }, + }, + }, + }, + }, + loading = new DimmedLoadingAnimation + { + RelativeSizeAxes = Axes.Both, + }, + }; + } - description.Text = beatmap.Version; - source.Text = beatmap.Metadata.Source; - tags.Text = beatmap.Metadata.Tags; + [BackgroundDependencyLoader] + private void load(OsuColour colours, APIAccess api) + { + this.api = api; + tags.TextColour = colours.Yellow; + } - 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; + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); - var requestedBeatmap = beatmap; + metadataScroll.Height = statsFlow.DrawHeight; + failRetryContainer.Height = DrawHeight - Padding.TotalVertical - (top.DrawHeight + spacing / 2); + } + + private void updateStatistics() + { + if (Beatmap == null) + { + clearStats(); + return; + } + + ratingsContainer.FadeIn(transition_duration); + advanced.Beatmap = Beatmap; + description.Text = Beatmap.Version; + source.Text = Beatmap.Metadata.Source; + tags.Text = Beatmap.Metadata.Tags; + + var requestedBeatmap = Beatmap; if (requestedBeatmap.Metrics == null) { var lookup = new GetBeatmapDetailsRequest(requestedBeatmap); @@ -84,413 +201,190 @@ namespace osu.Game.Screens.Select return; requestedBeatmap.Metrics = res; - Schedule(() => updateMetrics(res)); + Schedule(() => displayMetrics(res)); }; - lookup.Failure += e => Schedule(() => updateMetrics(null)); + lookup.Failure += e => Schedule(() => displayMetrics(null)); api.Queue(lookup); loading.Show(); } - updateMetrics(requestedBeatmap.Metrics, false); + displayMetrics(requestedBeatmap.Metrics, false); } - /// - /// Update displayed metrics. - /// - /// New metrics to overwrite the existing display. Can be null. - /// Whether to hide the display on null or empty metrics. If false, we will dim as if waiting for further updates. - private void updateMetrics(BeatmapMetrics metrics, bool failOnMissing = true) + private void displayMetrics(BeatmapMetrics metrics, bool failOnMissing = true) { var hasRatings = metrics?.Ratings.Any() ?? false; var hasRetriesFails = (metrics?.Retries.Any() ?? false) && metrics.Fails.Any(); - if (failOnMissing) - loading.Hide(); + if (failOnMissing) loading.Hide(); 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, Easing.Out); - } - else if (failOnMissing) - ratingsGraph.Values = new float[10]; - else - ratingsContainer.FadeColour(Color4.Gray, 500, Easing.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, Easing.Out); + ratings.Metrics = metrics; + ratings.FadeIn(transition_duration); } else if (failOnMissing) { - failGraph.Values = new float[100]; - retryGraph.Values = new float[100]; - } - else - retryFailContainer.FadeColour(Color4.Gray, 500, Easing.Out); - } - - public BeatmapDetails() - { - Children = new Drawable[] - { - new Box + ratings.FadeTo(0.25f, transition_duration); + ratings.Metrics = new BeatmapMetrics { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.5f, - }, - new FillFlowContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Width = 0.4f, - Direction = FillDirection.Vertical, - LayoutDuration = 200, - LayoutEasing = Easing.OutQuint, - Children = new[] - { - description = new MetadataSegment("Description"), - source = new MetadataSegment("Source"), - tags = new MetadataSegment("Tags") - }, - }, - new FillFlowContainer - { - 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[] - { - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.5f, - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 5), - Padding = new MarginPadding(10), - Children = new[] - { - circleSize = new DifficultyRow("Circle Size", 7), - drainRate = new DifficultyRow("HP Drain"), - overallDifficulty = new DifficultyRow("Accuracy"), - approachRate = new DifficultyRow("Approach Rate"), - stars = new DifficultyRow("Star Difficulty"), - }, - }, - }, - }, - ratingsContainer = new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Alpha = 0, - AlwaysPresent = true, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.5f, - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Padding = new MarginPadding - { - Top = 25, - Left = 15, - Right = 15, - }, - Children = new Drawable[] - { - new OsuSpriteText - { - Text = "User Rating", - Font = @"Exo2.0-Medium", - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - }, - ratingsBar = new Bar - { - RelativeSizeAxes = Axes.X, - Height = 5, - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new[] - { - negativeRatings = new OsuSpriteText - { - Font = @"Exo2.0-Regular", - Text = "0", - }, - positiveRatings = new OsuSpriteText - { - Font = @"Exo2.0-Regular", - Text = "0", - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - }, - }, - }, - new OsuSpriteText - { - Text = "Rating Spread", - TextSize = 14, - Font = @"Exo2.0-Regular", - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - }, - ratingsGraph = new BarGraph - { - RelativeSizeAxes = Axes.X, - Height = 50, - }, - }, - }, - }, - }, - retryFailContainer = 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 - { - RelativeSizeAxes = Axes.X, - Size = new Vector2(1 / 0.6f, 50), - Children = new[] - { - retryGraph = new BarGraph - { - RelativeSizeAxes = Axes.Both, - }, - failGraph = new BarGraph - { - RelativeSizeAxes = Axes.Both, - }, - }, - }, - } - }, - }, - }, - loading = new LoadingAnimation() - }; - } - - private APIAccess api; - private readonly LoadingAnimation loading; - - [BackgroundDependencyLoader] - private void load(OsuColour colour, APIAccess api) - { - this.api = api; - - description.AccentColour = colour.GrayB; - source.AccentColour = colour.GrayB; - tags.AccentColour = colour.YellowLight; - - stars.AccentColour = colour.Yellow; - - ratingsBar.BackgroundColour = colour.Green; - ratingsBar.AccentColour = colour.YellowDark; - ratingsGraph.Colour = colour.BlueDark; - - failGraph.Colour = colour.YellowDarker; - retryGraph.Colour = colour.Yellow; - } - - private class DifficultyRow : Container, IHasAccentColour - { - private readonly OsuSpriteText name; - private readonly Bar bar; - private readonly OsuSpriteText valueText; - - private readonly float maxValue; - - private float difficultyValue; - public float Value - { - get - { - return difficultyValue; - } - set - { - difficultyValue = value; - bar.Length = value / maxValue; - valueText.Text = value.ToString("N1", CultureInfo.CurrentCulture); - } - } - - public Color4 AccentColour - { - get - { - return bar.AccentColour; - } - set - { - bar.AccentColour = value; - } - } - - public DifficultyRow(string difficultyName, float maxValue = 10) - { - this.maxValue = maxValue; - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Children = new Drawable[] - { - name = new OsuSpriteText - { - Font = @"Exo2.0-Regular", - Text = difficultyName, - }, - bar = new Bar - { - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - RelativeSizeAxes = Axes.Both, - Size = new Vector2(1, 0.35f), - Padding = new MarginPadding { Left = 100, Right = 25 }, - }, - valueText = new OsuSpriteText - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Font = @"Exo2.0-Regular", - }, + Ratings = new int[10], }; } - [BackgroundDependencyLoader] - private void load(OsuColour colour) + if (hasRetriesFails) { - name.Colour = colour.GrayB; - bar.BackgroundColour = colour.Gray7; - valueText.Colour = colour.GrayB; + failRetryGraph.Metrics = metrics; + failRetryContainer.FadeIn(transition_duration); + } + else if (failOnMissing) + { + failRetryContainer.FadeTo(0.25f, transition_duration); + failRetryGraph.Metrics = new BeatmapMetrics + { + Fails = new int[100], + Retries = new int[100], + }; } } - private class MetadataSegment : Container, IHasAccentColour + private void clearStats() { - private readonly OsuSpriteText header; - private readonly FillFlowContainer content; + description.Text = null; + source.Text = null; + tags.Text = null; + advanced.Beatmap = new BeatmapInfo + { + StarDifficulty = 0, + Difficulty = new BeatmapDifficulty + { + CircleSize = 0, + DrainRate = 0, + OverallDifficulty = 0, + ApproachRate = 0, + }, + }; + + loading.Hide(); + ratingsContainer.FadeOut(transition_duration); + failRetryContainer.FadeOut(transition_duration); + } + + private class DetailBox : Container + { + private readonly Container content; + protected override Container 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, + }, + }; + } + } + + private class MetadataSection : Container + { + private readonly OsuSpriteText title; + private readonly TextFlowContainer textFlow; public string Text { set { if (string.IsNullOrEmpty(value)) - Hide(); - else { - Show(); - if (header.Text == "Tags") - content.ChildrenEnumerable = value.Split(' ').Select(text => new OsuSpriteText - { - Text = text, - Font = "Exo2.0-Regular", - }); - else - content.Children = new[] - { - new OsuSpriteText - { - Text = value, - Font = "Exo2.0-Regular", - } - }; + this.FadeOut(transition_duration); + return; } + + this.FadeIn(transition_duration); + textFlow.Clear(); + textFlow.AddText(value, s => s.TextSize = 14); } } - public Color4 AccentColour + public Color4 TextColour { - get - { - return content.Colour; - } - set - { - content.Colour = value; - } + get { return textFlow.Colour; } + set { textFlow.Colour = value; } } - public MetadataSegment(string headerText) + public MetadataSection(string title) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Margin = new MarginPadding { Top = 10 }; + + InternalChild = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(spacing / 2), + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = this.title = new OsuSpriteText + { + Text = title, + Font = @"Exo2.0-Bold", + TextSize = 14, + }, + }, + textFlow = new TextFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + }, + }, + }; + } + } + + private class DimmedLoadingAnimation : VisibilityContainer + { + private readonly LoadingAnimation loading; + + public DimmedLoadingAnimation() + { Children = new Drawable[] { - header = new OsuSpriteText + new Box { - Font = @"Exo2.0-Bold", - Text = headerText, + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.5f), }, - content = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Full, - Spacing = new Vector2(5, 0), - Margin = new MarginPadding { Top = header.TextSize } - } + loading = new LoadingAnimation(), }; } + + protected override void PopIn() + { + this.FadeIn(transition_duration, Easing.OutQuint); + loading.State = Visibility.Visible; + } + + protected override void PopOut() + { + this.FadeOut(transition_duration, Easing.OutQuint); + loading.State = Visibility.Hidden; + } } } } diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs new file mode 100644 index 0000000000..5f7377ec09 --- /dev/null +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -0,0 +1,152 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +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.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using System; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Select.Details +{ + public class AdvancedStats : Container + { + private readonly StatRow firstValue, hpDrain, accuracy, approachRate, starDifficulty; + + private BeatmapInfo beatmap; + public BeatmapInfo Beatmap + { + get { return beatmap; } + set + { + if (value == beatmap) return; + beatmap = value; + + //mania specific + if ((Beatmap?.Ruleset?.ID ?? 0) == 3) + { + firstValue.Title = "Key Amount"; + firstValue.Value = (int)Math.Round(Beatmap.Difficulty.CircleSize); + } + else + { + firstValue.Title = "Circle Size"; + firstValue.Value = Beatmap.Difficulty.CircleSize; + } + + hpDrain.Value = beatmap.Difficulty.DrainRate; + accuracy.Value = beatmap.Difficulty.OverallDifficulty; + approachRate.Value = beatmap.Difficulty.ApproachRate; + starDifficulty.Value = (float)beatmap.StarDifficulty; + } + } + + public AdvancedStats() + { + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(4f), + Children = new[] + { + firstValue = new StatRow(), //circle size/key amount + hpDrain = new StatRow { Title = "HP Drain" }, + accuracy = new StatRow { Title = "Accuracy" }, + approachRate = new StatRow { Title = "Approach Rate" }, + starDifficulty = new StatRow(10, true) { Title = "Star Difficulty" }, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + starDifficulty.AccentColour = colours.Yellow; + } + + private class StatRow : Container, IHasAccentColour + { + private const float value_width = 25; + private const float name_width = 70; + + private readonly float maxValue; + private readonly bool forceDecimalPlaces; + private readonly OsuSpriteText name, value; + private readonly Bar bar; + + public string Title + { + get { return name.Text; } + set { name.Text = value; } + } + + private float difficultyValue; + public float Value + { + get { return difficultyValue; } + set + { + difficultyValue = value; + bar.Length = value / maxValue; + this.value.Text = value.ToString(forceDecimalPlaces ? "#.00" : "0.##"); + } + } + + public Color4 AccentColour + { + get { return bar.AccentColour; } + set { bar.AccentColour = value; } + } + + public StatRow(float maxValue = 10, bool forceDecimalPlaces = false) + { + this.maxValue = maxValue; + this.forceDecimalPlaces = forceDecimalPlaces; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + Children = new Drawable[] + { + new Container + { + Width = name_width, + AutoSizeAxes = Axes.Y, + Child = this.name = new OsuSpriteText + { + TextSize = 13, + }, + }, + bar = new Bar + { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + RelativeSizeAxes = Axes.X, + Height = 5, + BackgroundColour = Color4.White.Opacity(0.5f), + Padding = new MarginPadding { Left = name_width + 10, Right = value_width + 10 }, + }, + new Container + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Width = value_width, + RelativeSizeAxes = Axes.Y, + Child = value = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + TextSize = 13, + }, + }, + }; + } + } + } +} diff --git a/osu.Game/Screens/Select/Details/BasicStats.cs b/osu.Game/Screens/Select/Details/BasicStats.cs new file mode 100644 index 0000000000..bfdecf28b5 --- /dev/null +++ b/osu.Game/Screens/Select/Details/BasicStats.cs @@ -0,0 +1,120 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +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; + +namespace osu.Game.Screens.Select.Details +{ + public class BasicStats : Container + { + private const float stat_count = 4; + + private readonly Statistic length, bpm, circleCount, sliderCount; + + 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"); + //bpm.Value = Beatmap.BeatmapSet.OnlineInfo.BPM.ToString(@"0.##"); + //circleCount.Value = string.Format(@"{0:n0}", beatmap.OnlineInfo.CircleCount); + //sliderCount.Value = string.Format(@"{0:n0}", beatmap.OnlineInfo.SliderCount); + } + } + + public BasicStats() + { + var statWidth = 1 / stat_count; + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Children = new[] + { + length = new Statistic(FontAwesome.fa_clock_o, "Length") { Width = statWidth }, + bpm = new Statistic(FontAwesome.fa_circle, "BPM") { Width = statWidth }, + circleCount = new Statistic(FontAwesome.fa_circle_o, "Circle Count") { Width = statWidth }, + sliderCount = new Statistic(FontAwesome.fa_circle, "Slider Count") { Width = statWidth }, + }, + }; + } + + 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; + } + } + } +} diff --git a/osu.Game/Screens/Select/Details/FailRetryGraph.cs b/osu.Game/Screens/Select/Details/FailRetryGraph.cs new file mode 100644 index 0000000000..4d75c49d17 --- /dev/null +++ b/osu.Game/Screens/Select/Details/FailRetryGraph.cs @@ -0,0 +1,62 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; +using System.Linq; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Select.Details +{ + public class FailRetryGraph : Container + { + private readonly BarGraph retryGraph, failGraph; + + private BeatmapMetrics metrics; + public BeatmapMetrics Metrics + { + get { return metrics; } + set + { + if (value == metrics) return; + metrics = value; + + var retries = Metrics.Retries; + var fails = Metrics.Fails; + + float maxValue = fails.Zip(retries, (fail, retry) => fail + retry).Max(); + failGraph.MaxValue = maxValue; + retryGraph.MaxValue = maxValue; + + failGraph.Values = fails.Select(f => (float)f); + retryGraph.Values = retries.Zip(fails, (retry, fail) => retry + MathHelper.Clamp(fail, 0, maxValue)); + } + } + + public FailRetryGraph() + { + Children = new[] + { + retryGraph = new BarGraph + { + RelativeSizeAxes = Axes.Both, + }, + failGraph = new BarGraph + { + RelativeSizeAxes = Axes.Both, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + retryGraph.Colour = colours.Yellow; + failGraph.Colour = colours.YellowDarker; + } + } +} diff --git a/osu.Game/Screens/Select/Details/SuccessRate.cs b/osu.Game/Screens/Select/Details/SuccessRate.cs new file mode 100644 index 0000000000..1d84fdbd48 --- /dev/null +++ b/osu.Game/Screens/Select/Details/SuccessRate.cs @@ -0,0 +1,114 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// 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.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Select.Details +{ + 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; + + //successPercent.Text = $"{beatmap.OnlineInfo.SuccessRate}%"; + //successRate.Length = (float)beatmap.OnlineInfo.SuccessRate / 100f; + + 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, + Child = successPercent = new OsuSpriteText + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopCentre, + 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 }; + } + + protected override void Update() + { + base.Update(); + + percentContainer.Width = successRate.Length; + } + } +} diff --git a/osu.Game/Screens/Select/Details/UserRatings.cs b/osu.Game/Screens/Select/Details/UserRatings.cs new file mode 100644 index 0000000000..db6d932464 --- /dev/null +++ b/osu.Game/Screens/Select/Details/UserRatings.cs @@ -0,0 +1,122 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// 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.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using System.Linq; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Select.Details +{ + public class UserRatings : Container + { + private readonly FillFlowContainer header; + private readonly Bar ratingsBar; + private readonly OsuSpriteText negativeRatings, positiveRatings; + private readonly Container graphContainer; + private readonly BarGraph graph; + + private BeatmapMetrics metrics; + public BeatmapMetrics Metrics + { + get { return metrics; } + set + { + if (value == metrics) return; + metrics = value; + + var ratings = Metrics.Ratings.ToList(); + 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(); + graph.Values = Metrics.Ratings.Select(r => (float)r); + } + } + + public UserRatings() + { + Children = new Drawable[] + { + header = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = "User Rating", + TextSize = 13, + }, + ratingsBar = new Bar + { + RelativeSizeAxes = Axes.X, + Height = 5, + Margin = new MarginPadding { Top = 5 }, + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new[] + { + negativeRatings = new OsuSpriteText + { + Text = "0", + TextSize = 13, + }, + positiveRatings = new OsuSpriteText + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Text = @"0", + TextSize = 13, + }, + }, + }, + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = "Rating Spread", + TextSize = 13, + Margin = new MarginPadding { Top = 10, Bottom = 5 }, + }, + }, + }, + graphContainer = new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Both, + Child = graph = new BarGraph + { + RelativeSizeAxes = Axes.Both, + }, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + ratingsBar.BackgroundColour = colours.Green; + ratingsBar.AccentColour = colours.Yellow; + graph.Colour = colours.BlueDark; + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + graphContainer.Padding = new MarginPadding { Top = header.DrawHeight }; + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 05ba3e25ab..4782464fbb 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -538,6 +538,11 @@ + + + + + From fd2700a5b4971a476d0fdd8ab79aa2cf5702a1d5 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 7 Sep 2017 15:01:31 -0300 Subject: [PATCH 62/93] Fix .00 being displayed for star difficulty when the value is 0. --- osu.Game/Screens/Select/Details/AdvancedStats.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 5f7377ec09..eb9e1d2c78 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -95,7 +95,7 @@ namespace osu.Game.Screens.Select.Details { difficultyValue = value; bar.Length = value / maxValue; - this.value.Text = value.ToString(forceDecimalPlaces ? "#.00" : "0.##"); + this.value.Text = value.ToString(forceDecimalPlaces ? "0.00" : "0.##"); } } From 2153865de5ecd13bbe253212ae9e8ac309dfddd5 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 7 Sep 2017 15:09:50 -0300 Subject: [PATCH 63/93] Adjust fail on missing logic to match original. --- osu.Game/Screens/Select/BeatmapDetails.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 8f564bb794..a11a662e41 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -38,6 +38,7 @@ namespace osu.Game.Screens.Select private APIAccess api; private ScheduledDelegate pendingBeatmapSwitch; + private BeatmapInfo beatmap; public BeatmapInfo Beatmap { @@ -226,12 +227,15 @@ namespace osu.Game.Screens.Select } else if (failOnMissing) { - ratings.FadeTo(0.25f, transition_duration); ratings.Metrics = new BeatmapMetrics { Ratings = new int[10], }; } + else + { + ratings.FadeTo(0.25f, transition_duration); + } if (hasRetriesFails) { @@ -240,13 +244,16 @@ namespace osu.Game.Screens.Select } else if (failOnMissing) { - failRetryContainer.FadeTo(0.25f, transition_duration); failRetryGraph.Metrics = new BeatmapMetrics { Fails = new int[100], Retries = new int[100], }; } + else + { + failRetryContainer.FadeTo(0.25f, transition_duration); + } } private void clearStats() From 109531b66c639eff988c4558b9a03f1ec8b2ff11 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 7 Sep 2017 15:21:18 -0300 Subject: [PATCH 64/93] Cleanup, remove unneeded files. --- .../Screens/Select/Details/AdvancedStats.cs | 16 +-- osu.Game/Screens/Select/Details/BasicStats.cs | 120 ------------------ .../Screens/Select/Details/SuccessRate.cs | 114 ----------------- osu.Game/osu.Game.csproj | 2 - 4 files changed, 8 insertions(+), 244 deletions(-) delete mode 100644 osu.Game/Screens/Select/Details/BasicStats.cs delete mode 100644 osu.Game/Screens/Select/Details/SuccessRate.cs diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index eb9e1d2c78..6969ba1319 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.Select.Details { public class AdvancedStats : Container { - private readonly StatRow firstValue, hpDrain, accuracy, approachRate, starDifficulty; + private readonly StatisticRow firstValue, hpDrain, accuracy, approachRate, starDifficulty; private BeatmapInfo beatmap; public BeatmapInfo Beatmap @@ -56,11 +56,11 @@ namespace osu.Game.Screens.Select.Details Spacing = new Vector2(4f), Children = new[] { - firstValue = new StatRow(), //circle size/key amount - hpDrain = new StatRow { Title = "HP Drain" }, - accuracy = new StatRow { Title = "Accuracy" }, - approachRate = new StatRow { Title = "Approach Rate" }, - starDifficulty = new StatRow(10, true) { Title = "Star Difficulty" }, + firstValue = new StatisticRow(), //circle size/key amount + hpDrain = new StatisticRow { Title = "HP Drain" }, + accuracy = new StatisticRow { Title = "Accuracy" }, + approachRate = new StatisticRow { Title = "Approach Rate" }, + starDifficulty = new StatisticRow(10, true) { Title = "Star Difficulty" }, }, }; } @@ -71,7 +71,7 @@ namespace osu.Game.Screens.Select.Details starDifficulty.AccentColour = colours.Yellow; } - private class StatRow : Container, IHasAccentColour + private class StatisticRow : Container, IHasAccentColour { private const float value_width = 25; private const float name_width = 70; @@ -105,7 +105,7 @@ namespace osu.Game.Screens.Select.Details set { bar.AccentColour = value; } } - public StatRow(float maxValue = 10, bool forceDecimalPlaces = false) + public StatisticRow(float maxValue = 10, bool forceDecimalPlaces = false) { this.maxValue = maxValue; this.forceDecimalPlaces = forceDecimalPlaces; diff --git a/osu.Game/Screens/Select/Details/BasicStats.cs b/osu.Game/Screens/Select/Details/BasicStats.cs deleted file mode 100644 index bfdecf28b5..0000000000 --- a/osu.Game/Screens/Select/Details/BasicStats.cs +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using OpenTK; -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; - -namespace osu.Game.Screens.Select.Details -{ - public class BasicStats : Container - { - private const float stat_count = 4; - - private readonly Statistic length, bpm, circleCount, sliderCount; - - 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"); - //bpm.Value = Beatmap.BeatmapSet.OnlineInfo.BPM.ToString(@"0.##"); - //circleCount.Value = string.Format(@"{0:n0}", beatmap.OnlineInfo.CircleCount); - //sliderCount.Value = string.Format(@"{0:n0}", beatmap.OnlineInfo.SliderCount); - } - } - - public BasicStats() - { - var statWidth = 1 / stat_count; - Child = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Horizontal, - Children = new[] - { - length = new Statistic(FontAwesome.fa_clock_o, "Length") { Width = statWidth }, - bpm = new Statistic(FontAwesome.fa_circle, "BPM") { Width = statWidth }, - circleCount = new Statistic(FontAwesome.fa_circle_o, "Circle Count") { Width = statWidth }, - sliderCount = new Statistic(FontAwesome.fa_circle, "Slider Count") { Width = statWidth }, - }, - }; - } - - 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; - } - } - } -} diff --git a/osu.Game/Screens/Select/Details/SuccessRate.cs b/osu.Game/Screens/Select/Details/SuccessRate.cs deleted file mode 100644 index 1d84fdbd48..0000000000 --- a/osu.Game/Screens/Select/Details/SuccessRate.cs +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// 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.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osu.Game.Beatmaps; - -namespace osu.Game.Screens.Select.Details -{ - 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; - - //successPercent.Text = $"{beatmap.OnlineInfo.SuccessRate}%"; - //successRate.Length = (float)beatmap.OnlineInfo.SuccessRate / 100f; - - 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, - Child = successPercent = new OsuSpriteText - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopCentre, - 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 }; - } - - protected override void Update() - { - base.Update(); - - percentContainer.Width = successRate.Length; - } - } -} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 4782464fbb..cf5d1f7026 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -539,9 +539,7 @@ - - From 55e8bdfb0580575ec6909721cae28bf174f15ab1 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 7 Sep 2017 15:38:23 -0300 Subject: [PATCH 65/93] CI fixes. --- osu.Game/Screens/Select/BeatmapDetailArea.cs | 2 +- osu.Game/Screens/Select/BeatmapDetails.cs | 3 +-- osu.Game/Screens/Select/Details/AdvancedStats.cs | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs index 9e244e1268..a676516300 100644 --- a/osu.Game/Screens/Select/BeatmapDetailArea.cs +++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs @@ -83,7 +83,7 @@ namespace osu.Game.Screens.Select { base.UpdateAfterChildren(); - Details.Height = Math.Min(DrawHeight - (details_padding * 3) - BeatmapDetailAreaTabControl.HEIGHT, 450); + Details.Height = Math.Min(DrawHeight - details_padding * 3 - BeatmapDetailAreaTabControl.HEIGHT, 450); } } } diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index a11a662e41..7c3b8ba905 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -306,7 +306,6 @@ namespace osu.Game.Screens.Select private class MetadataSection : Container { - private readonly OsuSpriteText title; private readonly TextFlowContainer textFlow; public string Text @@ -347,7 +346,7 @@ namespace osu.Game.Screens.Select { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Child = this.title = new OsuSpriteText + Child = new OsuSpriteText { Text = title, Font = @"Exo2.0-Bold", diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 6969ba1319..d92c8ed509 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -32,12 +32,12 @@ namespace osu.Game.Screens.Select.Details if ((Beatmap?.Ruleset?.ID ?? 0) == 3) { firstValue.Title = "Key Amount"; - firstValue.Value = (int)Math.Round(Beatmap.Difficulty.CircleSize); + firstValue.Value = (int)Math.Round(Beatmap?.Difficulty?.CircleSize ?? 0); } else { firstValue.Title = "Circle Size"; - firstValue.Value = Beatmap.Difficulty.CircleSize; + firstValue.Value = Beatmap?.Difficulty?.CircleSize ?? 0; } hpDrain.Value = beatmap.Difficulty.DrainRate; @@ -118,7 +118,7 @@ namespace osu.Game.Screens.Select.Details { Width = name_width, AutoSizeAxes = Axes.Y, - Child = this.name = new OsuSpriteText + Child = name = new OsuSpriteText { TextSize = 13, }, From 01553fc9ef9d6bdddfac28f68986f5db169fbd69 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 8 Sep 2017 02:46:54 +0200 Subject: [PATCH 66/93] Moved all online related score parsing to its class --- .../Online/API/Requests/GetScoresRequest.cs | 7 +- osu.Game/Rulesets/Scoring/OnlineScore.cs | 75 ++++++++++++++++++- osu.Game/Rulesets/Scoring/Score.cs | 38 ---------- 3 files changed, 79 insertions(+), 41 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index 72b8649ae0..6e22bd6989 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -23,7 +23,12 @@ namespace osu.Game.Online.API.Requests private void onSuccess(GetScoresResponse r) { foreach (OnlineScore score in r.Scores) - score.GetModsFor(beatmap.Ruleset); + { + score.Beatmap = beatmap; + score.Ruleset = beatmap.Ruleset; + + score.ResolveModString(); + } } protected override WebRequest CreateWebRequest() diff --git a/osu.Game/Rulesets/Scoring/OnlineScore.cs b/osu.Game/Rulesets/Scoring/OnlineScore.cs index 1f652e3d6c..694ce023d1 100644 --- a/osu.Game/Rulesets/Scoring/OnlineScore.cs +++ b/osu.Game/Rulesets/Scoring/OnlineScore.cs @@ -1,19 +1,90 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; +using osu.Game.Users; +using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Scoring { public class OnlineScore : Score { + [JsonProperty(@"score")] + private double totalScore + { + set { TotalScore = value; } + } + + [JsonProperty(@"max_combo")] + private int maxCombo + { + set { MaxCombo = value; } + } + + [JsonProperty(@"user")] + private User user + { + set { User = value; } + } + + [JsonProperty(@"replay_data")] + private Replay replay + { + set { Replay = value; } + } + + [JsonProperty(@"score_id")] + private long onlineScoreID + { + set { OnlineScoreID = value; } + } + + [JsonProperty(@"created_at")] + private DateTimeOffset date + { + set { Date = value; } + } + + [JsonProperty(@"statistics")] + private Dictionary jsonStats + { + set + { + foreach (var kvp in value) + { + string key = kvp.Key; + switch (key) + { + case @"count_300": + key = @"300"; + break; + case @"count_100": + key = @"100"; + break; + case @"count_50": + key = @"50"; + break; + case @"count_miss": + key = @"x"; + break; + default: + continue; + } + + Statistics.Add(key, kvp.Value); + } + } + } + [JsonProperty(@"mods")] private string[] modStrings { get; set; } - public void GetModsFor(RulesetInfo ruleset) + public void ResolveModString() { - Mods = ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); + Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); } } } diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index c09df06633..ff4632a9c2 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; using osu.Game.Users; @@ -15,14 +14,12 @@ namespace osu.Game.Rulesets.Scoring { public ScoreRank Rank { get; set; } - [JsonProperty(@"score")] public double TotalScore { get; set; } public double Accuracy { get; set; } public double Health { get; set; } = 1; - [JsonProperty(@"max_combo")] public int MaxCombo { get; set; } public int Combo { get; set; } @@ -31,51 +28,16 @@ namespace osu.Game.Rulesets.Scoring public Mod[] Mods { get; set; } - [JsonProperty(@"user")] public User User; - [JsonProperty(@"replay_data")] public Replay Replay; public BeatmapInfo Beatmap; - [JsonProperty(@"score_id")] public long OnlineScoreID; - [JsonProperty(@"created_at")] public DateTimeOffset Date; - [JsonProperty(@"statistics")] - private Dictionary jsonStats - { - set - { - foreach (var kvp in value) - { - string key = kvp.Key; - switch (key) - { - case @"count_300": - key = @"300"; - break; - case @"count_100": - key = @"100"; - break; - case @"count_50": - key = @"50"; - break; - case @"count_miss": - key = @"x"; - break; - default: - continue; - } - - Statistics.Add(key, kvp.Value); - } - } - } - public Dictionary Statistics = new Dictionary(); } } From 80c35801a62a21289aff1053759c4f51dc0c05bc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Sep 2017 16:15:41 +0900 Subject: [PATCH 67/93] Hide all overlays when home button is pressed --- osu.Game/OsuGame.cs | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index c020675881..b4fbdfb252 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -245,7 +245,11 @@ namespace osu.Game LoadComponentAsync(Toolbar = new Toolbar { Depth = -4, - OnHome = delegate { intro?.ChildScreen?.MakeCurrent(); }, + OnHome = delegate + { + hideAllOverlays(); + intro?.ChildScreen?.MakeCurrent(); + }, }, overlayContent.Add); settings.StateChanged += delegate @@ -310,6 +314,16 @@ namespace osu.Game private OsuScreen currentScreen; private FrameworkConfigManager frameworkConfig; + private void hideAllOverlays() + { + settings.State = Visibility.Hidden; + chat.State = Visibility.Hidden; + direct.State = Visibility.Hidden; + social.State = Visibility.Hidden; + userProfile.State = Visibility.Hidden; + notificationOverlay.State = Visibility.Hidden; + } + private void screenChanged(Screen newScreen) { currentScreen = newScreen as OsuScreen; @@ -323,19 +337,12 @@ namespace osu.Game //central game screen change logic. if (!currentScreen.ShowOverlays) { - settings.State = Visibility.Hidden; - Toolbar.State = Visibility.Hidden; + hideAllOverlays(); musicController.State = Visibility.Hidden; - chat.State = Visibility.Hidden; - direct.State = Visibility.Hidden; - social.State = Visibility.Hidden; - userProfile.State = Visibility.Hidden; - notificationOverlay.State = Visibility.Hidden; + Toolbar.State = Visibility.Hidden; } else - { Toolbar.State = Visibility.Visible; - } ScreenChanged?.Invoke(newScreen); } From a5281739438f0c4bc38f52ce3a7f57cb980e0f98 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Sep 2017 19:04:24 +0900 Subject: [PATCH 68/93] Ensure that WorkingBeatmap's Beatmap is never null Also ensures some extra fields inside Beatmap have non-null defaults. --- osu.Game/Beatmaps/Beatmap.cs | 8 ++++---- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 6 +----- osu.Game/Beatmaps/Formats/BeatmapDecoder.cs | 4 +--- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 +- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 82777734bb..15953fcd82 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -17,7 +17,7 @@ namespace osu.Game.Beatmaps public class Beatmap where T : HitObject { - public BeatmapInfo BeatmapInfo; + public BeatmapInfo BeatmapInfo = new BeatmapInfo(); public ControlPointInfo ControlPointInfo = new ControlPointInfo(); public List Breaks = new List(); public readonly List ComboColors = new List @@ -33,7 +33,7 @@ namespace osu.Game.Beatmaps /// /// The HitObjects this Beatmap contains. /// - public List HitObjects; + public List HitObjects = new List(); /// /// Total amount of break time in the beatmap. @@ -44,12 +44,13 @@ namespace osu.Game.Beatmaps /// Constructs a new beatmap. /// /// The original beatmap to use the parameters of. - public Beatmap(Beatmap original = null) + public Beatmap(Beatmap original = null) { BeatmapInfo = original?.BeatmapInfo.DeepClone() ?? BeatmapInfo; ControlPointInfo = original?.ControlPointInfo ?? ControlPointInfo; Breaks = original?.Breaks ?? Breaks; ComboColors = original?.ComboColors ?? ComboColors; + HitObjects = original?.HitObjects ?? HitObjects; } } @@ -65,7 +66,6 @@ namespace osu.Game.Beatmaps public Beatmap(Beatmap original = null) : base(original) { - HitObjects = original?.HitObjects; } } } diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 479f274efb..cc982c7a70 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -7,7 +7,6 @@ using osu.Framework.Audio.Track; using osu.Framework.Graphics.Textures; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; @@ -42,10 +41,7 @@ namespace osu.Game.Beatmaps this.game = game; } - protected override Beatmap GetBeatmap() => new Beatmap - { - HitObjects = new List(), - }; + protected override Beatmap GetBeatmap() => new Beatmap(); protected override Texture GetBackground() => game.Textures.Get(@"Backgrounds/bg4"); diff --git a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs index 234d65eee4..81695c3b5a 100644 --- a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.IO; -using osu.Game.Rulesets.Objects; namespace osu.Game.Beatmaps.Formats { @@ -21,7 +20,7 @@ namespace osu.Game.Beatmaps.Formats { string line; do { line = stream.ReadLine()?.Trim(); } - while (line != null && line.Length == 0); + while (line != null && line.Length == 0); if (line == null || !decoders.ContainsKey(line)) throw new IOException(@"Unknown file format"); @@ -47,7 +46,6 @@ namespace osu.Game.Beatmaps.Formats { var beatmap = new Beatmap { - HitObjects = new List(), BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata(), diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 462f94ed7c..4797f438d0 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -54,7 +54,7 @@ namespace osu.Game.Beatmaps { if (beatmap != null) return beatmap; - beatmap = GetBeatmap(); + beatmap = GetBeatmap() ?? new Beatmap(); // use the database-backed info. beatmap.BeatmapInfo = BeatmapInfo; From 526ee107b8102ad0dd815e59e8d543f00cc52436 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 8 Sep 2017 12:17:16 +0200 Subject: [PATCH 69/93] Use a method to apply a beatmap, its ruleset and the mods. --- osu.Game/Online/API/Requests/GetScoresRequest.cs | 7 +------ osu.Game/Rulesets/Scoring/OnlineScore.cs | 7 ++++++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index 6e22bd6989..d5ba22b9ac 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -23,12 +23,7 @@ namespace osu.Game.Online.API.Requests private void onSuccess(GetScoresResponse r) { foreach (OnlineScore score in r.Scores) - { - score.Beatmap = beatmap; - score.Ruleset = beatmap.Ruleset; - - score.ResolveModString(); - } + score.ApplyBeatmap(beatmap); } protected override WebRequest CreateWebRequest() diff --git a/osu.Game/Rulesets/Scoring/OnlineScore.cs b/osu.Game/Rulesets/Scoring/OnlineScore.cs index 694ce023d1..a58d682d05 100644 --- a/osu.Game/Rulesets/Scoring/OnlineScore.cs +++ b/osu.Game/Rulesets/Scoring/OnlineScore.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; +using osu.Game.Beatmaps; using osu.Game.Users; using osu.Game.Rulesets.Replays; @@ -82,8 +83,12 @@ namespace osu.Game.Rulesets.Scoring [JsonProperty(@"mods")] private string[] modStrings { get; set; } - public void ResolveModString() + public void ApplyBeatmap(BeatmapInfo beatmap) { + Beatmap = beatmap; + Ruleset = beatmap.Ruleset; + + // Evaluate the mod string Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); } } From 0b1403683bc9a806a152067707eaba56052e273e Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 8 Sep 2017 12:21:35 +0200 Subject: [PATCH 70/93] Moved OnlineScore inside GetScoresRequest.cs --- .../Online/API/Requests/GetScoresRequest.cs | 86 +++++++++++++++++ osu.Game/Rulesets/Scoring/OnlineScore.cs | 95 ------------------- osu.Game/osu.Game.csproj | 1 - 3 files changed, 86 insertions(+), 96 deletions(-) delete mode 100644 osu.Game/Rulesets/Scoring/OnlineScore.cs diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index d5ba22b9ac..ef9ee85d25 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -1,10 +1,14 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Collections.Generic; +using System.Linq; using Newtonsoft.Json; using osu.Framework.IO.Network; using osu.Game.Beatmaps; +using osu.Game.Users; +using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Scoring; namespace osu.Game.Online.API.Requests @@ -42,4 +46,86 @@ namespace osu.Game.Online.API.Requests [JsonProperty(@"scores")] public IEnumerable Scores; } + + public class OnlineScore : Score + { + [JsonProperty(@"score")] + private double totalScore + { + set { TotalScore = value; } + } + + [JsonProperty(@"max_combo")] + private int maxCombo + { + set { MaxCombo = value; } + } + + [JsonProperty(@"user")] + private User user + { + set { User = value; } + } + + [JsonProperty(@"replay_data")] + private Replay replay + { + set { Replay = value; } + } + + [JsonProperty(@"score_id")] + private long onlineScoreID + { + set { OnlineScoreID = value; } + } + + [JsonProperty(@"created_at")] + private DateTimeOffset date + { + set { Date = value; } + } + + [JsonProperty(@"statistics")] + private Dictionary jsonStats + { + set + { + foreach (var kvp in value) + { + string key = kvp.Key; + switch (key) + { + case @"count_300": + key = @"300"; + break; + case @"count_100": + key = @"100"; + break; + case @"count_50": + key = @"50"; + break; + case @"count_miss": + key = @"x"; + break; + default: + continue; + } + + Statistics.Add(key, kvp.Value); + } + } + } + + [JsonProperty(@"mods")] + private string[] modStrings { get; set; } + + public void ApplyBeatmap(BeatmapInfo beatmap) + { + Beatmap = beatmap; + Ruleset = beatmap.Ruleset; + + // Evaluate the mod string + Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); + } + } } diff --git a/osu.Game/Rulesets/Scoring/OnlineScore.cs b/osu.Game/Rulesets/Scoring/OnlineScore.cs deleted file mode 100644 index a58d682d05..0000000000 --- a/osu.Game/Rulesets/Scoring/OnlineScore.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; -using osu.Game.Beatmaps; -using osu.Game.Users; -using osu.Game.Rulesets.Replays; - -namespace osu.Game.Rulesets.Scoring -{ - public class OnlineScore : Score - { - [JsonProperty(@"score")] - private double totalScore - { - set { TotalScore = value; } - } - - [JsonProperty(@"max_combo")] - private int maxCombo - { - set { MaxCombo = value; } - } - - [JsonProperty(@"user")] - private User user - { - set { User = value; } - } - - [JsonProperty(@"replay_data")] - private Replay replay - { - set { Replay = value; } - } - - [JsonProperty(@"score_id")] - private long onlineScoreID - { - set { OnlineScoreID = value; } - } - - [JsonProperty(@"created_at")] - private DateTimeOffset date - { - set { Date = value; } - } - - [JsonProperty(@"statistics")] - private Dictionary jsonStats - { - set - { - foreach (var kvp in value) - { - string key = kvp.Key; - switch (key) - { - case @"count_300": - key = @"300"; - break; - case @"count_100": - key = @"100"; - break; - case @"count_50": - key = @"50"; - break; - case @"count_miss": - key = @"x"; - break; - default: - continue; - } - - Statistics.Add(key, kvp.Value); - } - } - } - - [JsonProperty(@"mods")] - private string[] modStrings { get; set; } - - public void ApplyBeatmap(BeatmapInfo beatmap) - { - Beatmap = beatmap; - Ruleset = beatmap.Ruleset; - - // Evaluate the mod string - Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); - } - } -} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 66a892406f..05ba3e25ab 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -244,7 +244,6 @@ - From 7b497c0ecbc40b9979e6a340c8a9726738f89357 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Sep 2017 23:24:47 +0900 Subject: [PATCH 71/93] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 5f2d5a57e5..4e7ea6af4f 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 5f2d5a57e5d506d7e5d87eeeb442adf10be061f6 +Subproject commit 4e7ea6af4f59f21f6afc522fb063c05417e1a5fe From 5c125737cb6a52b8a9c025fcdc1c7274d94120a0 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 8 Sep 2017 17:47:23 +0200 Subject: [PATCH 72/93] Fix wrong initial topic color of not joined channels in the channel selection --- osu.Game/Overlays/Chat/ChannelListItem.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChannelListItem.cs b/osu.Game/Overlays/Chat/ChannelListItem.cs index f43154ea20..8360e793d8 100644 --- a/osu.Game/Overlays/Chat/ChannelListItem.cs +++ b/osu.Game/Overlays/Chat/ChannelListItem.cs @@ -76,7 +76,6 @@ namespace osu.Game.Overlays.Chat Size = new Vector2(text_size), Shadow = false, Margin = new MarginPadding { Right = 10f }, - Alpha = 0f, }, }, }, @@ -109,7 +108,6 @@ namespace osu.Game.Overlays.Chat TextSize = text_size, Font = @"Exo2.0-SemiBold", Shadow = false, - Alpha = 0.8f, }, }, }, @@ -151,6 +149,9 @@ namespace osu.Game.Overlays.Chat joinedBind.ValueChanged += updateColour; joinedBind.BindTo(channel.Joined); + + joinedBind.TriggerChange(); + FinishTransforms(true); } protected override bool OnHover(InputState state) From ce68b6661e3e957d28a5af0eee817be92b3e9d14 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 8 Sep 2017 14:15:28 -0300 Subject: [PATCH 73/93] Update visual test. --- .../Visual/TestCaseBeatmapDetails.cs | 117 +++++++++++++----- osu.Game/Screens/Select/BeatmapDetails.cs | 4 +- 2 files changed, 88 insertions(+), 33 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs b/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs index 11a15cf56f..7f447337bd 100644 --- a/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs +++ b/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs @@ -20,42 +20,97 @@ namespace osu.Desktop.Tests.Visual { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding(150), - Beatmap = new BeatmapInfo + }); + + AddStep("beatmap all metrics", () => details.Beatmap = new BeatmapInfo + { + Version = "All Metrics", + Metadata = new BeatmapMetadata { - Version = "VisualTest", - Metadata = new BeatmapMetadata - { - Source = "Some guy", - Tags = "beatmap metadata example with a very very long list of tags and not much creativity", - }, - Difficulty = new BeatmapDifficulty - { - CircleSize = 7, - ApproachRate = 3.5f, - OverallDifficulty = 5.7f, - DrainRate = 1, - }, - StarDifficulty = 5.3f, - Metrics = new BeatmapMetrics - { - Ratings = Enumerable.Range(0, 10), - Fails = Enumerable.Range(lastRange, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(lastRange - 3, 100).Select(i => i % 12 - 6), - }, + Source = "osu!lazer", + Tags = "this beatmap has all the metrics", + }, + Difficulty = new BeatmapDifficulty + { + CircleSize = 7, + DrainRate = 1, + OverallDifficulty = 5.7f, + ApproachRate = 3.5f, + }, + StarDifficulty = 5.3f, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), }, }); - AddRepeatStep("fail values", newRetryAndFailValues, 10); - } + AddStep("beatmap ratings", () => details.Beatmap = new BeatmapInfo + { + Version = "Only Ratings", + Metadata = new BeatmapMetadata + { + Source = "osu!lazer", + Tags = "this beatmap has ratings metrics but not retries or fails", + }, + Difficulty = new BeatmapDifficulty + { + CircleSize = 6, + DrainRate = 9, + OverallDifficulty = 6, + ApproachRate = 6, + }, + StarDifficulty = 4.8f, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + }, + }); - private int lastRange = 1; + AddStep("beatmap fails retries", () => details.Beatmap = new BeatmapInfo + { + Version = "Only Retries and Fails", + Metadata = new BeatmapMetadata + { + Source = "osu!lazer", + Tags = "this beatmap has retries and fails but no ratings", + }, + Difficulty = new BeatmapDifficulty + { + CircleSize = 3.7f, + DrainRate = 6, + OverallDifficulty = 6, + ApproachRate = 7, + }, + StarDifficulty = 2.91f, + Metrics = new BeatmapMetrics + { + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }); - private void newRetryAndFailValues() - { - details.Beatmap.Metrics.Fails = Enumerable.Range(lastRange, 100).Select(i => i % 12 - 6); - details.Beatmap.Metrics.Retries = Enumerable.Range(lastRange - 3, 100).Select(i => i % 12 - 6); - details.Beatmap = details.Beatmap; - lastRange += 100; + AddStep("beatmap no metrics", () => details.Beatmap = new BeatmapInfo + { + Version = "No Metrics", + Metadata = new BeatmapMetadata + { + Source = "osu!lazer", + Tags = "this beatmap has no metrics", + }, + Difficulty = new BeatmapDifficulty + { + CircleSize = 5, + DrainRate = 5, + OverallDifficulty = 5.5f, + ApproachRate = 6.5f, + }, + StarDifficulty = 1.97f, + Metrics = new BeatmapMetrics(), + }); + + AddStep("null beatmap", () => details.Beatmap = null); } } -} \ No newline at end of file +} diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 7c3b8ba905..b389489e0f 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -215,8 +215,8 @@ namespace osu.Game.Screens.Select private void displayMetrics(BeatmapMetrics metrics, bool failOnMissing = true) { - var hasRatings = metrics?.Ratings.Any() ?? false; - var hasRetriesFails = (metrics?.Retries.Any() ?? false) && metrics.Fails.Any(); + var hasRatings = metrics?.Ratings?.Any() ?? false; + var hasRetriesFails = (metrics?.Retries?.Any() ?? false) && (metrics?.Fails?.Any() ?? false); if (failOnMissing) loading.Hide(); From d95940ed5e2eec4a1b67cd50d28945891174bd2a Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 8 Sep 2017 14:25:41 -0300 Subject: [PATCH 74/93] CI fixes. --- osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs | 3 +-- osu.Game/Screens/Select/BeatmapDetails.cs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs b/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs index 7f447337bd..d0f631201a 100644 --- a/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs +++ b/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs @@ -12,10 +12,9 @@ namespace osu.Desktop.Tests.Visual { public override string Description => "BeatmapDetails tab of BeatmapDetailArea"; - private readonly BeatmapDetails details; - public TestCaseBeatmapDetails() { + BeatmapDetails details; Add(details = new BeatmapDetails { RelativeSizeAxes = Axes.Both, diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index b389489e0f..a98362e89c 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -216,7 +216,7 @@ namespace osu.Game.Screens.Select private void displayMetrics(BeatmapMetrics metrics, bool failOnMissing = true) { var hasRatings = metrics?.Ratings?.Any() ?? false; - var hasRetriesFails = (metrics?.Retries?.Any() ?? false) && (metrics?.Fails?.Any() ?? false); + var hasRetriesFails = (metrics?.Retries?.Any() ?? false) && (metrics.Fails?.Any() ?? false); if (failOnMissing) loading.Hide(); From 20f93c83d694b17f86c0343e86bdf96811796d2e Mon Sep 17 00:00:00 2001 From: naoey Date: Fri, 8 Sep 2017 22:37:28 +0530 Subject: [PATCH 75/93] Make downloads happen in BeatmapManager. --- .../Visual/TestCasePlaySongSelect.cs | 2 +- osu.Game/Beatmaps/BeatmapManager.cs | 74 ++++++++++++++++++- .../API/Requests/DownloadBeatmapSetRequest.cs | 21 ++++++ osu.Game/OsuGameBase.cs | 14 ++-- osu.Game/Overlays/Direct/DirectPanel.cs | 68 +++-------------- osu.Game/osu.Game.csproj | 1 + 6 files changed, 115 insertions(+), 65 deletions(-) create mode 100644 osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs diff --git a/osu.Desktop.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Desktop.Tests/Visual/TestCasePlaySongSelect.cs index 379100b543..8d1ae7d913 100644 --- a/osu.Desktop.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Desktop.Tests/Visual/TestCasePlaySongSelect.cs @@ -32,7 +32,7 @@ namespace osu.Desktop.Tests.Visual backingDatabase.CreateTable(); rulesets = new RulesetStore(backingDatabase); - manager = new BeatmapManager(storage, null, backingDatabase, rulesets); + manager = new BeatmapManager(storage, null, backingDatabase, rulesets, null); for (int i = 0; i < 100; i += 10) manager.Import(createTestBeatmapSet(i)); diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 551612330b..fbbc94a8f5 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -20,6 +20,9 @@ using osu.Game.IPC; using osu.Game.Overlays.Notifications; using osu.Game.Rulesets; using SQLite.Net; +using osu.Game.Online.API.Requests; +using System.Threading.Tasks; +using osu.Game.Online.API; namespace osu.Game.Beatmaps { @@ -63,6 +66,10 @@ namespace osu.Game.Beatmaps private readonly BeatmapStore beatmaps; + private readonly APIAccess api; + + private readonly Dictionary downloadsMap; + // ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised) private BeatmapIPCChannel ipc; @@ -76,7 +83,7 @@ namespace osu.Game.Beatmaps /// public Func GetStableStorage { private get; set; } - public BeatmapManager(Storage storage, FileStore files, SQLiteConnection connection, RulesetStore rulesets, IIpcHost importHost = null) + public BeatmapManager(Storage storage, FileStore files, SQLiteConnection connection, RulesetStore rulesets, APIAccess api, IIpcHost importHost = null) { beatmaps = new BeatmapStore(connection); beatmaps.BeatmapSetAdded += s => BeatmapSetAdded?.Invoke(s); @@ -88,9 +95,12 @@ namespace osu.Game.Beatmaps this.files = files; this.connection = connection; this.rulesets = rulesets; + this.api = api; if (importHost != null) ipc = new BeatmapIPCChannel(importHost, this); + + downloadsMap = new Dictionary(); } /// @@ -177,6 +187,68 @@ namespace osu.Game.Beatmaps beatmaps.Add(beatmapSetInfo); } + /// + /// Download a beatmap + /// + /// The beatmap to be downloaded + public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo) + { + if (api == null || downloadsMap.ContainsKey(beatmapSetInfo)) return null; + + ProgressNotification downloadNotification = new ProgressNotification + { + Text = $"Downloading {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}", + }; + + var request = new DownloadBeatmapSetRequest(beatmapSetInfo); + + request.DownloadProgressed += progress => + { + downloadNotification.State = ProgressNotificationState.Active; + downloadNotification.Progress = progress; + }; + + request.Success += data => + { + downloadNotification.State = ProgressNotificationState.Completed; + + using (var stream = new MemoryStream(data)) + using (var archive = new OszArchiveReader(stream)) + Import(archive); + + downloadsMap.Remove(beatmapSetInfo); + }; + + request.Failure += data => + { + downloadNotification.State = ProgressNotificationState.Completed; + Logger.Error(data, "Failed to get beatmap download information"); + downloadsMap.Remove(beatmapSetInfo); + }; + + downloadNotification.CancelRequested += () => + { + Logger.Log("Cancel requested"); + downloadsMap.Remove(beatmapSetInfo); + return true; + }; + + downloadsMap[beatmapSetInfo] = request; + PostNotification?.Invoke(downloadNotification); + + // don't run in the main api queue as this is a long-running task. + Task.Run(() => request.Perform(api)); + + return request; + } + + /// + /// Check if a beatmap is already downloading. + /// + /// The to check against. + /// true if a download request already exists, false if it doesn't. + public bool IsDownloading(BeatmapSetInfo beatmap) => downloadsMap.ContainsKey(beatmap); + /// /// Delete a beatmap from the manager. /// Is a no-op for already deleted beatmaps. diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs new file mode 100644 index 0000000000..28473d9f66 --- /dev/null +++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs @@ -0,0 +1,21 @@ +using osu.Game.Beatmaps; +using System; + +namespace osu.Game.Online.API.Requests +{ + public class DownloadBeatmapSetRequest : APIDownloadRequest + { + private readonly BeatmapSetInfo beatmapSet; + + public Action DownloadProgressed; + + public DownloadBeatmapSetRequest(BeatmapSetInfo beatmapSet) + { + this.beatmapSet = beatmapSet; + + Progress += (current, total) => DownloadProgressed?.Invoke((float) current / total); + } + + protected override string Target => $@"beatmapsets/{beatmapSet.OnlineBeatmapSetID}/download"; + } +} diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index a7136ce803..76eb7d5101 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -106,9 +106,15 @@ namespace osu.Game connection.CreateTable(); + dependencies.Cache(API = new APIAccess + { + Username = LocalConfig.Get(OsuSetting.Username), + Token = LocalConfig.Get(OsuSetting.Token) + }); + dependencies.Cache(RulesetStore = new RulesetStore(connection)); dependencies.Cache(FileStore = new FileStore(connection, Host.Storage)); - dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, Host)); + dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, API, Host)); dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, connection, Host, BeatmapManager, RulesetStore)); dependencies.Cache(KeyBindingStore = new KeyBindingStore(connection, RulesetStore)); dependencies.Cache(new OsuColour()); @@ -144,12 +150,6 @@ namespace osu.Game Beatmap = new NonNullableBindable(defaultBeatmap); BeatmapManager.DefaultBeatmap = defaultBeatmap; - dependencies.Cache(API = new APIAccess - { - Username = LocalConfig.Get(OsuSetting.Username), - Token = LocalConfig.Get(OsuSetting.Token) - }); - Beatmap.ValueChanged += b => { // compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index a642f72821..746cd39085 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -115,23 +115,8 @@ namespace osu.Game.Overlays.Direct base.OnHoverLost(state); } - // this should eventually be moved to a more central place, like BeatmapManager. - private DownloadBeatmapSetRequest downloadRequest; - protected void StartDownload() { - if (api == null) return; - - // we already have an active download running. - if (downloadRequest != null) - { - content.MoveToX(-5, 50, Easing.OutSine).Then() - .MoveToX(5, 100, Easing.InOutSine).Then() - .MoveToX(-5, 100, Easing.InOutSine).Then() - .MoveToX(0, 50, Easing.InSine).Then(); - return; - } - if (!api.LocalUser.Value.IsSupporter) { notifications.Post(new SimpleNotification @@ -142,25 +127,28 @@ namespace osu.Game.Overlays.Direct return; } + // we already have an active download running. + if (beatmaps.IsDownloading(SetInfo)) + { + content.MoveToX(-5, 50, Easing.OutSine).Then() + .MoveToX(5, 100, Easing.InOutSine).Then() + .MoveToX(-5, 100, Easing.InOutSine).Then() + .MoveToX(0, 50, Easing.InSine).Then(); + return; + } + + var downloadRequest = beatmaps.Download(SetInfo); + progressBar.FadeIn(400, Easing.OutQuint); progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); progressBar.Current.Value = 0; - ProgressNotification downloadNotification = new ProgressNotification - { - Text = $"Downloading {SetInfo.Metadata.Artist} - {SetInfo.Metadata.Title}", - }; - - downloadRequest = new DownloadBeatmapSetRequest(SetInfo); downloadRequest.Failure += e => { progressBar.Current.Value = 0; progressBar.FadeOut(500); - downloadNotification.State = ProgressNotificationState.Completed; Logger.Error(e, "Failed to get beatmap download information"); - - downloadRequest = null; }; downloadRequest.Progress += (current, total) => @@ -169,45 +157,13 @@ namespace osu.Game.Overlays.Direct progressBar.Current.Value = progress; - downloadNotification.State = ProgressNotificationState.Active; - downloadNotification.Progress = progress; }; downloadRequest.Success += data => { progressBar.Current.Value = 1; progressBar.FadeOut(500); - - downloadNotification.State = ProgressNotificationState.Completed; - - using (var stream = new MemoryStream(data)) - using (var archive = new OszArchiveReader(stream)) - beatmaps.Import(archive); }; - - downloadNotification.CancelRequested += () => - { - downloadRequest.Cancel(); - downloadRequest = null; - return true; - }; - - notifications.Post(downloadNotification); - - // don't run in the main api queue as this is a long-running task. - Task.Run(() => downloadRequest.Perform(api)); - } - - public class DownloadBeatmapSetRequest : APIDownloadRequest - { - private readonly BeatmapSetInfo beatmapSet; - - public DownloadBeatmapSetRequest(BeatmapSetInfo beatmapSet) - { - this.beatmapSet = beatmapSet; - } - - protected override string Target => $@"beatmapsets/{beatmapSet.OnlineBeatmapSetID}/download"; } protected override void LoadComplete() diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 05ba3e25ab..5e1c5426ec 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -98,6 +98,7 @@ + From 31a507372a0795f850c76a9e717978d6ab75d3fa Mon Sep 17 00:00:00 2001 From: naoey Date: Fri, 8 Sep 2017 23:16:48 +0530 Subject: [PATCH 76/93] Don't show beatmaps that are already added. --- osu.Game/Overlays/DirectOverlay.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index f734e43826..8bbb937641 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -27,6 +27,7 @@ namespace osu.Game.Overlays private APIAccess api; private RulesetStore rulesets; + private BeatmapManager beatmaps; private readonly FillFlowContainer resultCountsContainer; private readonly OsuSpriteText resultCountsText; @@ -147,6 +148,8 @@ namespace osu.Game.Overlays { this.api = api; this.rulesets = rulesets; + this.beatmaps = beatmaps; + resultCountsContainer.Colour = colours.Yellow; beatmaps.BeatmapSetAdded += setAdded; @@ -237,7 +240,10 @@ namespace osu.Game.Overlays getSetsRequest.Success += r => { - BeatmapSets = r?.Select(response => response.ToBeatmapSet(rulesets)); + BeatmapSets = r?. + Select(response => response.ToBeatmapSet(rulesets)). + Where(b => (beatmaps.QueryBeatmapSet(q => q.OnlineBeatmapSetID == b.OnlineBeatmapSetID) == null)); + if (BeatmapSets == null) return; var artists = new List(); From 00306b6e3807d08867a2f09aef9623308b565fbf Mon Sep 17 00:00:00 2001 From: naoey Date: Fri, 8 Sep 2017 23:55:20 +0530 Subject: [PATCH 77/93] Maintain download progress between switching result views. - Check for existing download requests on creating DirectPanel - Actually remove downloaded beatmap from results --- osu.Game/Beatmaps/BeatmapManager.cs | 25 +++++---- osu.Game/Overlays/Direct/DirectPanel.cs | 71 +++++++++++++++---------- osu.Game/Overlays/DirectOverlay.cs | 30 ++++++----- 3 files changed, 72 insertions(+), 54 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index fbbc94a8f5..22402ba76a 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -68,7 +68,7 @@ namespace osu.Game.Beatmaps private readonly APIAccess api; - private readonly Dictionary downloadsMap; + private readonly Dictionary downloadsMap; // ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised) private BeatmapIPCChannel ipc; @@ -100,7 +100,7 @@ namespace osu.Game.Beatmaps if (importHost != null) ipc = new BeatmapIPCChannel(importHost, this); - downloadsMap = new Dictionary(); + downloadsMap = new Dictionary(); } /// @@ -191,9 +191,10 @@ namespace osu.Game.Beatmaps /// Download a beatmap /// /// The beatmap to be downloaded + /// The new , or null if a download already exists for the same beatmap. public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo) { - if (api == null || downloadsMap.ContainsKey(beatmapSetInfo)) return null; + if (api == null || downloadsMap.ContainsKey(beatmapSetInfo.OnlineBeatmapSetID)) return null; ProgressNotification downloadNotification = new ProgressNotification { @@ -216,24 +217,26 @@ namespace osu.Game.Beatmaps using (var archive = new OszArchiveReader(stream)) Import(archive); - downloadsMap.Remove(beatmapSetInfo); + downloadsMap.Remove(beatmapSetInfo.OnlineBeatmapSetID); }; request.Failure += data => { downloadNotification.State = ProgressNotificationState.Completed; Logger.Error(data, "Failed to get beatmap download information"); - downloadsMap.Remove(beatmapSetInfo); + downloadsMap.Remove(beatmapSetInfo.OnlineBeatmapSetID); }; downloadNotification.CancelRequested += () => { Logger.Log("Cancel requested"); - downloadsMap.Remove(beatmapSetInfo); + downloadsMap[beatmapSetInfo.OnlineBeatmapSetID].Cancel(); + downloadsMap.Remove(beatmapSetInfo.OnlineBeatmapSetID); + downloadNotification.State = ProgressNotificationState.Cancelled; return true; }; - downloadsMap[beatmapSetInfo] = request; + downloadsMap[beatmapSetInfo.OnlineBeatmapSetID] = request; PostNotification?.Invoke(downloadNotification); // don't run in the main api queue as this is a long-running task. @@ -243,11 +246,11 @@ namespace osu.Game.Beatmaps } /// - /// Check if a beatmap is already downloading. + /// Get an existing download request if it exists. /// - /// The to check against. - /// true if a download request already exists, false if it doesn't. - public bool IsDownloading(BeatmapSetInfo beatmap) => downloadsMap.ContainsKey(beatmap); + /// The whose download request is wanted. + /// The object if it exists, or null. + public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => downloadsMap.GetOrDefault(beatmap.OnlineBeatmapSetID); /// /// Delete a beatmap from the manager. diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 746cd39085..0f87d22123 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -22,6 +22,7 @@ using osu.Game.Online.API; using osu.Framework.Logging; using osu.Game.Beatmaps.IO; using osu.Game.Overlays.Notifications; +using osu.Game.Online.API.Requests; namespace osu.Game.Overlays.Direct { @@ -40,6 +41,44 @@ namespace osu.Game.Overlays.Direct private BeatmapManager beatmaps; private NotificationOverlay notifications; + private DownloadBeatmapSetRequest downloadRequest; + protected DownloadBeatmapSetRequest DownloadRequest + { + get { return downloadRequest; } + set + { + if (value == null) return; + + downloadRequest = value; + + progressBar.FadeIn(400, Easing.OutQuint); + progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); + + progressBar.Current.Value = 0; + + downloadRequest.Failure += e => + { + progressBar.Current.Value = 0; + progressBar.FadeOut(500); + Logger.Error(e, "Failed to get beatmap download information"); + }; + + downloadRequest.Progress += (current, total) => + { + float progress = (float)current / total; + + progressBar.Current.Value = progress; + + }; + + downloadRequest.Success += data => + { + progressBar.Current.Value = 1; + progressBar.FadeOut(500); + }; + } + } + protected override Container Content => content; protected DirectPanel(BeatmapSetInfo setInfo) @@ -97,6 +136,8 @@ namespace osu.Game.Overlays.Direct }, } }); + + DownloadRequest = beatmaps.GetExistingDownload(SetInfo); } protected override bool OnHover(InputState state) @@ -128,7 +169,7 @@ namespace osu.Game.Overlays.Direct } // we already have an active download running. - if (beatmaps.IsDownloading(SetInfo)) + if ((DownloadRequest = beatmaps.Download(SetInfo)) == null) { content.MoveToX(-5, 50, Easing.OutSine).Then() .MoveToX(5, 100, Easing.InOutSine).Then() @@ -136,34 +177,6 @@ namespace osu.Game.Overlays.Direct .MoveToX(0, 50, Easing.InSine).Then(); return; } - - var downloadRequest = beatmaps.Download(SetInfo); - - progressBar.FadeIn(400, Easing.OutQuint); - progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); - - progressBar.Current.Value = 0; - - downloadRequest.Failure += e => - { - progressBar.Current.Value = 0; - progressBar.FadeOut(500); - Logger.Error(e, "Failed to get beatmap download information"); - }; - - downloadRequest.Progress += (current, total) => - { - float progress = (float)current / total; - - progressBar.Current.Value = progress; - - }; - - downloadRequest.Success += data => - { - progressBar.Current.Value = 1; - progressBar.FadeOut(500); - }; } protected override void LoadComplete() diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 8bbb937641..2aa64e2b99 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -47,9 +47,22 @@ namespace osu.Game.Overlays set { if (beatmapSets?.Equals(value) ?? false) return; + beatmapSets = value; - recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); + if (beatmapSets == null) return; + + var artists = new List(); + var songs = new List(); + var tags = new List(); + 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)); } } @@ -159,6 +172,7 @@ namespace osu.Game.Overlays { // if a new map was imported, we should remove it from search results (download completed etc.) panels?.FirstOrDefault(p => p.SetInfo.OnlineBeatmapSetID == set.OnlineBeatmapSetID)?.FadeOut(400).Expire(); + BeatmapSets = BeatmapSets.Where(b => b.OnlineBeatmapSetID != set.OnlineBeatmapSetID); } private void updateResultCounts() @@ -244,19 +258,7 @@ namespace osu.Game.Overlays Select(response => response.ToBeatmapSet(rulesets)). Where(b => (beatmaps.QueryBeatmapSet(q => q.OnlineBeatmapSetID == b.OnlineBeatmapSetID) == null)); - if (BeatmapSets == null) return; - - var artists = new List(); - var songs = new List(); - var tags = new List(); - 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)); + recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); }; api.Queue(getSetsRequest); From 0e4973020aaf65f8c3c7f1075af932cbfd63c2d9 Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 9 Sep 2017 00:17:38 +0530 Subject: [PATCH 78/93] Resharper and test case fixes. --- osu.Desktop.Tests/Visual/TestCaseDirect.cs | 8 ++++++++ osu.Game/Overlays/Direct/DirectPanel.cs | 4 ---- osu.Game/Overlays/DirectOverlay.cs | 6 +++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseDirect.cs b/osu.Desktop.Tests/Visual/TestCaseDirect.cs index b78ea02767..9fd93c3f1e 100644 --- a/osu.Desktop.Tests/Visual/TestCaseDirect.cs +++ b/osu.Desktop.Tests/Visual/TestCaseDirect.cs @@ -41,12 +41,14 @@ namespace osu.Desktop.Tests.Visual { new BeatmapSetInfo { + OnlineBeatmapSetID = 578332, Metadata = new BeatmapMetadata { Title = @"OrVid", Artist = @"An", Author = @"RLC", Source = @"", + Tags = @"acuticnotes an-fillnote revid tear tearvid encrpted encryption axi axivid quad her hervid recoll", }, OnlineInfo = new BeatmapSetOnlineInfo { @@ -71,12 +73,14 @@ namespace osu.Desktop.Tests.Visual }, new BeatmapSetInfo { + OnlineBeatmapSetID = 599627, Metadata = new BeatmapMetadata { Title = @"tiny lamp", Artist = @"fhana", Author = @"Sotarks", Source = @"ぎんぎつね", + Tags = @"lantis junichi sato yuxuki waga kevin mitsunaga towana gingitsune opening op full ver version kalibe collab collaboration", }, OnlineInfo = new BeatmapSetOnlineInfo { @@ -101,12 +105,14 @@ namespace osu.Desktop.Tests.Visual }, new BeatmapSetInfo { + OnlineBeatmapSetID = 513268, Metadata = new BeatmapMetadata { Title = @"At Gwanghwamun", Artist = @"KYUHYUN", Author = @"Cerulean Veyron", Source = @"", + Tags = @"soul ballad kh super junior sj suju 슈퍼주니어 kt뮤직 sm엔터테인먼트 s.m.entertainment kt music 1st mini album ep", }, OnlineInfo = new BeatmapSetOnlineInfo { @@ -146,12 +152,14 @@ namespace osu.Desktop.Tests.Visual }, new BeatmapSetInfo { + OnlineBeatmapSetID = 586841, Metadata = new BeatmapMetadata { Title = @"RHAPSODY OF BLUE SKY", Artist = @"fhana", Author = @"[Kamiya]", Source = @"小林さんちのメイドラゴン", + Tags = @"kobayashi san chi no maidragon aozora no opening anime maid dragon oblivion karen dynamix imoutosan pata-mon gxytcgxytc", }, OnlineInfo = new BeatmapSetOnlineInfo { diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 0f87d22123..4bbba27d99 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -4,8 +4,6 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; -using System.IO; -using System.Threading.Tasks; using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -20,7 +18,6 @@ using osu.Framework.Input; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Framework.Logging; -using osu.Game.Beatmaps.IO; using osu.Game.Overlays.Notifications; using osu.Game.Online.API.Requests; @@ -175,7 +172,6 @@ namespace osu.Game.Overlays.Direct .MoveToX(5, 100, Easing.InOutSine).Then() .MoveToX(-5, 100, Easing.InOutSine).Then() .MoveToX(0, 50, Easing.InSine).Then(); - return; } } diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 2aa64e2b99..54fda5a38d 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -63,6 +63,10 @@ namespace osu.Game.Overlays } ResultAmounts = new ResultCounts(distinctCount(artists), distinctCount(songs), distinctCount(tags)); + + if (beatmapSets.Any() && panels == null) + // real use case? currently only seems to be for test case + recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); } } @@ -256,7 +260,7 @@ namespace osu.Game.Overlays { BeatmapSets = r?. Select(response => response.ToBeatmapSet(rulesets)). - Where(b => (beatmaps.QueryBeatmapSet(q => q.OnlineBeatmapSetID == b.OnlineBeatmapSetID) == null)); + Where(b => beatmaps.QueryBeatmapSet(q => q.OnlineBeatmapSetID == b.OnlineBeatmapSetID) == null); recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); }; From 5a3814b02e765e8b34491fed43b8d91ad2eb4032 Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 9 Sep 2017 01:04:55 +0530 Subject: [PATCH 79/93] XMLdoc fixes and a cautionary check. --- osu.Game/Beatmaps/BeatmapManager.cs | 4 ++-- osu.Game/Overlays/Direct/DirectPanel.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 22402ba76a..4de5d49b1e 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -188,9 +188,9 @@ namespace osu.Game.Beatmaps } /// - /// Download a beatmap + /// Downloads a beatmap. /// - /// The beatmap to be downloaded + /// The to be downloaded. /// The new , or null if a download already exists for the same beatmap. public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo) { diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 4bbba27d99..7f0c8ac350 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -44,7 +44,7 @@ namespace osu.Game.Overlays.Direct get { return downloadRequest; } set { - if (value == null) return; + if (value == null || downloadRequest == value) return; downloadRequest = value; From 20becbe5760fa2c5d9f07c00558513aa4c59f00a Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 9 Sep 2017 01:53:42 +0530 Subject: [PATCH 80/93] Use the specifically created progress action, add license header. --- osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs | 5 ++++- osu.Game/Overlays/Direct/DirectPanel.cs | 8 +------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs index 28473d9f66..0ba4adf9c9 100644 --- a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs +++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs @@ -1,4 +1,7 @@ -using osu.Game.Beatmaps; +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Beatmaps; using System; namespace osu.Game.Online.API.Requests diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 7f0c8ac350..4bf3442453 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -60,13 +60,7 @@ namespace osu.Game.Overlays.Direct Logger.Error(e, "Failed to get beatmap download information"); }; - downloadRequest.Progress += (current, total) => - { - float progress = (float)current / total; - - progressBar.Current.Value = progress; - - }; + downloadRequest.DownloadProgressed += progress => progressBar.Current.Value = progress; downloadRequest.Success += data => { From 5f5dd54f9d1e99971218ad4910ab13c0df421dc5 Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 9 Sep 2017 09:51:37 +0530 Subject: [PATCH 81/93] Use a List instead of a Dictionary. --- osu.Game/Beatmaps/BeatmapManager.cs | 21 ++++++++++--------- .../API/Requests/DownloadBeatmapSetRequest.cs | 8 +++---- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 4de5d49b1e..8e7b38a50c 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -68,7 +68,7 @@ namespace osu.Game.Beatmaps private readonly APIAccess api; - private readonly Dictionary downloadsMap; + private readonly List downloadsList; // ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised) private BeatmapIPCChannel ipc; @@ -100,7 +100,7 @@ namespace osu.Game.Beatmaps if (importHost != null) ipc = new BeatmapIPCChannel(importHost, this); - downloadsMap = new Dictionary(); + downloadsList = new List(); } /// @@ -194,7 +194,8 @@ namespace osu.Game.Beatmaps /// The new , or null if a download already exists for the same beatmap. public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo) { - if (api == null || downloadsMap.ContainsKey(beatmapSetInfo.OnlineBeatmapSetID)) return null; + if (api == null || downloadsList.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmapSetInfo.OnlineBeatmapSetID) != null) + return null; ProgressNotification downloadNotification = new ProgressNotification { @@ -217,29 +218,29 @@ namespace osu.Game.Beatmaps using (var archive = new OszArchiveReader(stream)) Import(archive); - downloadsMap.Remove(beatmapSetInfo.OnlineBeatmapSetID); + downloadsList.Remove(request); }; request.Failure += data => { downloadNotification.State = ProgressNotificationState.Completed; Logger.Error(data, "Failed to get beatmap download information"); - downloadsMap.Remove(beatmapSetInfo.OnlineBeatmapSetID); + downloadsList.Remove(request); }; downloadNotification.CancelRequested += () => { - Logger.Log("Cancel requested"); - downloadsMap[beatmapSetInfo.OnlineBeatmapSetID].Cancel(); - downloadsMap.Remove(beatmapSetInfo.OnlineBeatmapSetID); + request.Cancel(); + downloadsList.Remove(request); downloadNotification.State = ProgressNotificationState.Cancelled; return true; }; - downloadsMap[beatmapSetInfo.OnlineBeatmapSetID] = request; + downloadsList.Add(request); PostNotification?.Invoke(downloadNotification); // don't run in the main api queue as this is a long-running task. + // TODO: ensure the Success/Failure callbacks are being scheduled to the main thread for thread safety. Task.Run(() => request.Perform(api)); return request; @@ -250,7 +251,7 @@ namespace osu.Game.Beatmaps /// /// The whose download request is wanted. /// The object if it exists, or null. - public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => downloadsMap.GetOrDefault(beatmap.OnlineBeatmapSetID); + public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => downloadsList.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID); /// /// Delete a beatmap from the manager. diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs index 0ba4adf9c9..5a9f609bca 100644 --- a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs +++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs @@ -8,17 +8,17 @@ namespace osu.Game.Online.API.Requests { public class DownloadBeatmapSetRequest : APIDownloadRequest { - private readonly BeatmapSetInfo beatmapSet; + public readonly BeatmapSetInfo BeatmapSet; public Action DownloadProgressed; - public DownloadBeatmapSetRequest(BeatmapSetInfo beatmapSet) + public DownloadBeatmapSetRequest(BeatmapSetInfo set) { - this.beatmapSet = beatmapSet; + BeatmapSet = set; Progress += (current, total) => DownloadProgressed?.Invoke((float) current / total); } - protected override string Target => $@"beatmapsets/{beatmapSet.OnlineBeatmapSetID}/download"; + protected override string Target => $@"beatmapsets/{BeatmapSet.OnlineBeatmapSetID}/download"; } } From e67606e2031722830b89c63ef0bd5d24d24aca94 Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 9 Sep 2017 10:25:28 +0530 Subject: [PATCH 82/93] Return existing download if it exists. --- osu.Game/Beatmaps/BeatmapManager.cs | 9 ++++++--- osu.Game/Overlays/Direct/DirectPanel.cs | 6 +++++- osu.Game/Overlays/DirectOverlay.cs | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 8e7b38a50c..472e44f36b 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -191,11 +191,14 @@ namespace osu.Game.Beatmaps /// Downloads a beatmap. /// /// The to be downloaded. - /// The new , or null if a download already exists for the same beatmap. + /// A new , or an existing one if a download is already in progress. public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo) { - if (api == null || downloadsList.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmapSetInfo.OnlineBeatmapSetID) != null) - return null; + var existing = downloadsList.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmapSetInfo.OnlineBeatmapSetID); + + if (existing != null) return existing; + + if (api == null) return null; ProgressNotification downloadNotification = new ProgressNotification { diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 4bf3442453..66b3ff8bf9 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -160,13 +160,17 @@ namespace osu.Game.Overlays.Direct } // we already have an active download running. - if ((DownloadRequest = beatmaps.Download(SetInfo)) == null) + if (beatmaps.GetExistingDownload(SetInfo) != null) { content.MoveToX(-5, 50, Easing.OutSine).Then() .MoveToX(5, 100, Easing.InOutSine).Then() .MoveToX(-5, 100, Easing.InOutSine).Then() .MoveToX(0, 50, Easing.InSine).Then(); + + return; } + + DownloadRequest = beatmaps.Download(SetInfo); } protected override void LoadComplete() diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 54fda5a38d..9c07e1087f 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -176,7 +176,7 @@ namespace osu.Game.Overlays { // if a new map was imported, we should remove it from search results (download completed etc.) panels?.FirstOrDefault(p => p.SetInfo.OnlineBeatmapSetID == set.OnlineBeatmapSetID)?.FadeOut(400).Expire(); - BeatmapSets = BeatmapSets.Where(b => b.OnlineBeatmapSetID != set.OnlineBeatmapSetID); + BeatmapSets = BeatmapSets?.Where(b => b.OnlineBeatmapSetID != set.OnlineBeatmapSetID); } private void updateResultCounts() From d12a5e927a2154449583ad7b9015ade70b30cdeb Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 9 Sep 2017 11:03:25 +0530 Subject: [PATCH 83/93] Rename property. --- osu.Game/Beatmaps/BeatmapManager.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 472e44f36b..6c3a703c19 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -68,7 +68,7 @@ namespace osu.Game.Beatmaps private readonly APIAccess api; - private readonly List downloadsList; + private readonly List currentDownloads; // ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised) private BeatmapIPCChannel ipc; @@ -100,7 +100,7 @@ namespace osu.Game.Beatmaps if (importHost != null) ipc = new BeatmapIPCChannel(importHost, this); - downloadsList = new List(); + currentDownloads = new List(); } /// @@ -194,7 +194,7 @@ namespace osu.Game.Beatmaps /// A new , or an existing one if a download is already in progress. public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo) { - var existing = downloadsList.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmapSetInfo.OnlineBeatmapSetID); + var existing = currentDownloads.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmapSetInfo.OnlineBeatmapSetID); if (existing != null) return existing; @@ -221,25 +221,25 @@ namespace osu.Game.Beatmaps using (var archive = new OszArchiveReader(stream)) Import(archive); - downloadsList.Remove(request); + currentDownloads.Remove(request); }; request.Failure += data => { downloadNotification.State = ProgressNotificationState.Completed; Logger.Error(data, "Failed to get beatmap download information"); - downloadsList.Remove(request); + currentDownloads.Remove(request); }; downloadNotification.CancelRequested += () => { request.Cancel(); - downloadsList.Remove(request); + currentDownloads.Remove(request); downloadNotification.State = ProgressNotificationState.Cancelled; return true; }; - downloadsList.Add(request); + currentDownloads.Add(request); PostNotification?.Invoke(downloadNotification); // don't run in the main api queue as this is a long-running task. @@ -254,7 +254,7 @@ namespace osu.Game.Beatmaps /// /// The whose download request is wanted. /// The object if it exists, or null. - public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => downloadsList.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID); + public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => currentDownloads.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID); /// /// Delete a beatmap from the manager. From 0c2bad1de4abce4610b6e4d263b3ef103709b8f6 Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 9 Sep 2017 12:44:27 +0530 Subject: [PATCH 84/93] Get rid of some properties and todos. --- osu.Game/Beatmaps/BeatmapManager.cs | 7 +-- osu.Game/Overlays/Direct/DirectPanel.cs | 66 ++++++++++++------------- 2 files changed, 33 insertions(+), 40 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 6c3a703c19..f58b3505c5 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -68,7 +68,7 @@ namespace osu.Game.Beatmaps private readonly APIAccess api; - private readonly List currentDownloads; + private readonly List currentDownloads = new List(); // ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised) private BeatmapIPCChannel ipc; @@ -99,8 +99,6 @@ namespace osu.Game.Beatmaps if (importHost != null) ipc = new BeatmapIPCChannel(importHost, this); - - currentDownloads = new List(); } /// @@ -194,7 +192,7 @@ namespace osu.Game.Beatmaps /// A new , or an existing one if a download is already in progress. public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo) { - var existing = currentDownloads.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmapSetInfo.OnlineBeatmapSetID); + var existing = GetExistingDownload(beatmapSetInfo); if (existing != null) return existing; @@ -243,7 +241,6 @@ namespace osu.Game.Beatmaps PostNotification?.Invoke(downloadNotification); // don't run in the main api queue as this is a long-running task. - // TODO: ensure the Success/Failure callbacks are being scheduled to the main thread for thread safety. Task.Run(() => request.Perform(api)); return request; diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 66b3ff8bf9..6f1f581d0b 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -38,38 +38,6 @@ namespace osu.Game.Overlays.Direct private BeatmapManager beatmaps; private NotificationOverlay notifications; - private DownloadBeatmapSetRequest downloadRequest; - protected DownloadBeatmapSetRequest DownloadRequest - { - get { return downloadRequest; } - set - { - if (value == null || downloadRequest == value) return; - - downloadRequest = value; - - progressBar.FadeIn(400, Easing.OutQuint); - progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); - - progressBar.Current.Value = 0; - - downloadRequest.Failure += e => - { - progressBar.Current.Value = 0; - progressBar.FadeOut(500); - Logger.Error(e, "Failed to get beatmap download information"); - }; - - downloadRequest.DownloadProgressed += progress => progressBar.Current.Value = progress; - - downloadRequest.Success += data => - { - progressBar.Current.Value = 1; - progressBar.FadeOut(500); - }; - } - } - protected override Container Content => content; protected DirectPanel(BeatmapSetInfo setInfo) @@ -128,7 +96,10 @@ namespace osu.Game.Overlays.Direct } }); - DownloadRequest = beatmaps.GetExistingDownload(SetInfo); + var downloadRequest = beatmaps.GetExistingDownload(SetInfo); + + if (downloadRequest != null) + attachDownload(downloadRequest); } protected override bool OnHover(InputState state) @@ -159,9 +130,9 @@ namespace osu.Game.Overlays.Direct return; } - // we already have an active download running. if (beatmaps.GetExistingDownload(SetInfo) != null) { + // we already have an active download running. content.MoveToX(-5, 50, Easing.OutSine).Then() .MoveToX(5, 100, Easing.InOutSine).Then() .MoveToX(-5, 100, Easing.InOutSine).Then() @@ -170,7 +141,32 @@ namespace osu.Game.Overlays.Direct return; } - DownloadRequest = beatmaps.Download(SetInfo); + var request = beatmaps.Download(SetInfo); + + attachDownload(request); + } + + private void attachDownload(DownloadBeatmapSetRequest request) + { + progressBar.FadeIn(400, Easing.OutQuint); + progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); + + progressBar.Current.Value = 0; + + request.Failure += e => + { + progressBar.Current.Value = 0; + progressBar.FadeOut(500); + Logger.Error(e, "Failed to get beatmap download information"); + }; + + request.DownloadProgressed += progress => progressBar.Current.Value = progress; + + request.Success += data => + { + progressBar.Current.Value = 1; + progressBar.FadeOut(500); + }; } protected override void LoadComplete() From 0a9ca8a1ff89c58f39b171256239be41640ea3e0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 10 Sep 2017 11:53:47 +0900 Subject: [PATCH 85/93] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 4e7ea6af4f..a617245a42 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 4e7ea6af4f59f21f6afc522fb063c05417e1a5fe +Subproject commit a617245a4261d7d6e138c2fddbbeaa7940d24ca7 From f33bd700c5ae1f1ecd602b8a1dfe1f15c7739129 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 08:27:29 +0900 Subject: [PATCH 86/93] Fix individual volume controls not being adjustable via wheel They were blocking each others' input unnecessarily. --- .../Graphics/UserInterface/Volume/VolumeControl.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index 4c108e793a..8c777f491b 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -15,11 +15,7 @@ namespace osu.Game.Graphics.UserInterface.Volume { private readonly VolumeMeter volumeMeterMaster; - private void volumeChanged(double newVolume) - { - Show(); - schedulePopOut(); - } + protected override bool BlockPassThroughMouse => false; public VolumeControl() { @@ -85,6 +81,12 @@ namespace osu.Game.Graphics.UserInterface.Volume return false; } + private void volumeChanged(double newVolume) + { + Show(); + schedulePopOut(); + } + [BackgroundDependencyLoader] private void load(AudioManager audio) { From 8d919e42c9eb04202547972893ad4261cf3ead78 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 11:18:53 +0900 Subject: [PATCH 87/93] Fix nullref when loading MusicController VisualTest after Player VisualTest --- osu.Game/Overlays/MusicController.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 0a06439c3e..64d0d628f0 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -302,8 +302,8 @@ namespace osu.Game.Overlays else { //figure out the best direction based on order in playlist. - var last = playlist.BeatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo.ID).Count(); - var next = beatmap == null ? -1 : playlist.BeatmapSets.TakeWhile(b => b.ID != beatmap.BeatmapSetInfo.ID).Count(); + var last = playlist.BeatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo?.ID).Count(); + var next = beatmap == null ? -1 : playlist.BeatmapSets.TakeWhile(b => b.ID != beatmap.BeatmapSetInfo?.ID).Count(); direction = last > next ? TransformDirection.Prev : TransformDirection.Next; } From 4f6c93aa0f711b1a9aad7e0c2479b258d4f1faf1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 11:34:40 +0900 Subject: [PATCH 88/93] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index a617245a42..0fe1e50b38 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit a617245a4261d7d6e138c2fddbbeaa7940d24ca7 +Subproject commit 0fe1e50b38ff9ce8aceba231eede3333cb73bb23 From eedfbdc0e8de2f3da4418a20ac42e1b84ee16404 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 11:41:09 +0900 Subject: [PATCH 89/93] Add nullref check in KeyCounterCollection's Add method --- osu.Game/Screens/Play/KeyCounterCollection.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Play/KeyCounterCollection.cs b/osu.Game/Screens/Play/KeyCounterCollection.cs index 0f6c5984c4..d21be71785 100644 --- a/osu.Game/Screens/Play/KeyCounterCollection.cs +++ b/osu.Game/Screens/Play/KeyCounterCollection.cs @@ -28,6 +28,8 @@ namespace osu.Game.Screens.Play public override void Add(KeyCounter key) { + if (key == null) throw new ArgumentNullException(nameof(key)); + base.Add(key); key.IsCounting = IsCounting; key.FadeTime = FadeTime; From 3cacee300ace35b41947bf374c1e15550b0b99e9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 11:41:29 +0900 Subject: [PATCH 90/93] Fix a false resharper positive --- .../OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs index 72ba421344..c6ecc3a506 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs @@ -51,6 +51,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing foreach (OsuDifficultyHitObject h in onScreen) { + // ReSharper disable once PossibleNullReferenceException (resharper not smart enough to understand IEnumerator.MoveNext()) h.TimeUntilHit -= latest.DeltaTime; // Calculate reading strain here } From 7170fbd0873252304f1a49bdd933965f7c368303 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 12:35:40 +0900 Subject: [PATCH 91/93] Target .NET 4.6.1 --- osu.Desktop.Deploy/osu.Desktop.Deploy.csproj | 2 +- osu.Desktop.Tests/osu.Desktop.Tests.csproj | 2 +- osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj | 2 +- osu.Desktop/osu.Desktop.csproj | 2 +- osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj | 2 +- osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj | 2 +- osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj | 2 +- osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj | 2 +- osu.Game.Tests/osu.Game.Tests.csproj | 2 +- osu.Game/osu.Game.csproj | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj index c6474eae5a..c090342a4b 100644 --- a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj +++ b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj @@ -9,7 +9,7 @@ Properties osu.Desktop.Deploy osu.Desktop.Deploy - v4.5.2 + v4.6.1 512 true diff --git a/osu.Desktop.Tests/osu.Desktop.Tests.csproj b/osu.Desktop.Tests/osu.Desktop.Tests.csproj index 86268e6110..975af1a782 100644 --- a/osu.Desktop.Tests/osu.Desktop.Tests.csproj +++ b/osu.Desktop.Tests/osu.Desktop.Tests.csproj @@ -9,7 +9,7 @@ Properties osu.Desktop.Tests osu.Desktop.Tests - v4.5 + v4.6.1 512 diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 8bba59207f..33019909c6 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -22,7 +22,7 @@ OnOutputUpdated false LocalIntranet - v4.5 + v4.6.1 true publish\ true diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index bbca4145c6..661c17699b 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -22,7 +22,7 @@ OnOutputUpdated false LocalIntranet - v4.5 + v4.6.1 true publish\ true diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 79ef5f4ba8..2ae2262ac7 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -9,7 +9,7 @@ Properties osu.Game.Rulesets.Catch osu.Game.Rulesets.Catch - v4.5 + v4.6.1 512 diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 890c9116cf..5f39054d82 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -9,7 +9,7 @@ Properties osu.Game.Rulesets.Mania osu.Game.Rulesets.Mania - v4.5 + v4.6.1 512 diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj index 0c9e53cf69..857f47f9b9 100644 --- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj +++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj @@ -9,7 +9,7 @@ Properties osu.Game.Rulesets.Osu osu.Game.Rulesets.Osu - v4.5 + v4.6.1 512 diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index 33748a267f..e1987ec96d 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -9,7 +9,7 @@ Properties osu.Game.Rulesets.Taiko osu.Game.Rulesets.Taiko - v4.5 + v4.6.1 512 diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 8ec68b41be..220b1aac7f 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -7,7 +7,7 @@ Library osu.Game.Tests osu.Game.Tests - v4.5 + v4.6.1 true diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index defa9f8a6d..d20618a2ae 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -9,7 +9,7 @@ Properties osu.Game osu.Game - v4.5 + v4.6.1 512 From 712c6942a9f0072af9c7a4c1b6cbd7fcfc1af692 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 12:39:06 +0900 Subject: [PATCH 92/93] Update submodules --- osu-framework | 2 +- osu-resources | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu-framework b/osu-framework index 0fe1e50b38..e24d24ae70 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 0fe1e50b38ff9ce8aceba231eede3333cb73bb23 +Subproject commit e24d24ae70a78cea5a11635c37d2808d29233e96 diff --git a/osu-resources b/osu-resources index f6042e1cb3..a4418111f8 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit f6042e1cb37cfad6c879d0e1245f7880c7fcd5f5 +Subproject commit a4418111f8ed2350a6fd46fe69258884f0757745 From 512232c1c887c9e5d7f4b118e6238bf315b17cee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 14:25:01 +0900 Subject: [PATCH 93/93] Fix regression causing autoplay to fail --- osu.Game/Rulesets/UI/RulesetContainer.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index e2701faca0..34b079951d 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -77,13 +77,6 @@ namespace osu.Game.Rulesets.UI Ruleset = ruleset; } - [BackgroundDependencyLoader] - private void load() - { - KeyBindingInputManager = CreateInputManager(); - KeyBindingInputManager.RelativeSizeAxes = Axes.Both; - } - /// /// Checks whether all HitObjects have been judged, and invokes OnAllJudged. /// @@ -194,6 +187,9 @@ namespace osu.Game.Rulesets.UI // Post-process the beatmap processor.PostProcess(Beatmap); + KeyBindingInputManager = CreateInputManager(); + KeyBindingInputManager.RelativeSizeAxes = Axes.Both; + // Add mods, should always be the last thing applied to give full control to mods applyMods(Mods); }