diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 280c2f45d4..8d0d78120a 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -133,26 +133,26 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy if (ConversionDifficulty > 6.5) { - if ((convertType & PatternType.LowProbability) > 0) + if (convertType.HasFlag(PatternType.LowProbability)) return generateNRandomNotes(HitObject.StartTime, 0.78, 0.3, 0); return generateNRandomNotes(HitObject.StartTime, 0.85, 0.36, 0.03); } if (ConversionDifficulty > 4) { - if ((convertType & PatternType.LowProbability) > 0) + if (convertType.HasFlag(PatternType.LowProbability)) return generateNRandomNotes(HitObject.StartTime, 0.43, 0.08, 0); return generateNRandomNotes(HitObject.StartTime, 0.56, 0.18, 0); } if (ConversionDifficulty > 2.5) { - if ((convertType & PatternType.LowProbability) > 0) + if (convertType.HasFlag(PatternType.LowProbability)) return generateNRandomNotes(HitObject.StartTime, 0.3, 0, 0); return generateNRandomNotes(HitObject.StartTime, 0.37, 0.08, 0); } - if ((convertType & PatternType.LowProbability) > 0) + if (convertType.HasFlag(PatternType.LowProbability)) return generateNRandomNotes(HitObject.StartTime, 0.17, 0, 0); return generateNRandomNotes(HitObject.StartTime, 0.27, 0, 0); } @@ -209,7 +209,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy var pattern = new Pattern(); int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true); - if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < TotalColumns) + if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns) { while (PreviousPattern.ColumnHasObject(nextColumn)) nextColumn = Random.Next(RandomStart, TotalColumns); @@ -361,7 +361,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy bool isDoubleSample(SampleInfo sample) => sample.Name == SampleInfo.HIT_CLAP || sample.Name == SampleInfo.HIT_FINISH; - bool canGenerateTwoNotes = (convertType & PatternType.LowProbability) == 0; + bool canGenerateTwoNotes = !convertType.HasFlag(PatternType.LowProbability); canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(HitObject.StartTime).Any(isDoubleSample); if (canGenerateTwoNotes) @@ -391,7 +391,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy int columnRepeat = Math.Min(spanCount, TotalColumns); int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true); - if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < TotalColumns) + if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns) { while (PreviousPattern.ColumnHasObject(nextColumn)) nextColumn = Random.Next(RandomStart, TotalColumns); @@ -425,7 +425,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy var pattern = new Pattern(); int holdColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true); - if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < TotalColumns) + if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns) { while (PreviousPattern.ColumnHasObject(holdColumn)) holdColumn = Random.Next(RandomStart, TotalColumns); diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index 0e839d87a2..84ebfdb839 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -21,7 +21,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy private readonly PatternType convertType; - public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair, IBeatmap originalBeatmap) + public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, + PatternType lastStair, IBeatmap originalBeatmap) : base(random, hitObject, beatmap, previousPattern, originalBeatmap) { if (previousTime > hitObject.StartTime) throw new ArgumentOutOfRangeException(nameof(previousTime)); @@ -79,7 +80,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy else convertType |= PatternType.LowProbability; - if ((convertType & PatternType.KeepSingle) == 0) + if (!convertType.HasFlag(PatternType.KeepSingle)) { if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && TotalColumns != 8) convertType |= PatternType.Mirror; @@ -107,7 +108,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy int lastColumn = PreviousPattern.HitObjects.FirstOrDefault()?.Column ?? 0; - if ((convertType & PatternType.Reverse) > 0 && PreviousPattern.HitObjects.Any()) + if (convertType.HasFlag(PatternType.Reverse) && PreviousPattern.HitObjects.Any()) { // Generate a new pattern by copying the last hit objects in reverse-column order for (int i = RandomStart; i < TotalColumns; i++) @@ -117,7 +118,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy return pattern; } - if ((convertType & PatternType.Cycle) > 0 && PreviousPattern.HitObjects.Count() == 1 + if (convertType.HasFlag(PatternType.Cycle) && PreviousPattern.HitObjects.Count() == 1 // If we convert to 7K + 1, let's not overload the special key && (TotalColumns != 8 || lastColumn != 0) // Make sure the last column was not the centre column @@ -130,7 +131,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy return pattern; } - if ((convertType & PatternType.ForceStack) > 0 && PreviousPattern.HitObjects.Any()) + if (convertType.HasFlag(PatternType.ForceStack) && PreviousPattern.HitObjects.Any()) { // Generate a new pattern by placing on the already filled columns for (int i = RandomStart; i < TotalColumns; i++) @@ -142,7 +143,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy if (PreviousPattern.HitObjects.Count() == 1) { - if ((convertType & PatternType.Stair) > 0) + if (convertType.HasFlag(PatternType.Stair)) { // Generate a new pattern by placing on the next column, cycling back to the start if there is no "next" int targetColumn = lastColumn + 1; @@ -153,7 +154,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy return pattern; } - if ((convertType & PatternType.ReverseStair) > 0) + if (convertType.HasFlag(PatternType.ReverseStair)) { // Generate a new pattern by placing on the previous column, cycling back to the end if there is no "previous" int targetColumn = lastColumn - 1; @@ -165,10 +166,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy } } - if ((convertType & PatternType.KeepSingle) > 0) + if (convertType.HasFlag(PatternType.KeepSingle)) return pattern = generateRandomNotes(1); - if ((convertType & PatternType.Mirror) > 0) + if (convertType.HasFlag(PatternType.Mirror)) { if (ConversionDifficulty > 6.5) return pattern = generateRandomPatternWithMirrored(0.12, 0.38, 0.12); @@ -179,21 +180,21 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy if (ConversionDifficulty > 6.5) { - if ((convertType & PatternType.LowProbability) > 0) + if (convertType.HasFlag(PatternType.LowProbability)) return pattern = generateRandomPattern(0.78, 0.42, 0, 0); return pattern = generateRandomPattern(1, 0.62, 0, 0); } if (ConversionDifficulty > 4) { - if ((convertType & PatternType.LowProbability) > 0) + if (convertType.HasFlag(PatternType.LowProbability)) return pattern = generateRandomPattern(0.35, 0.08, 0, 0); return pattern = generateRandomPattern(0.52, 0.15, 0, 0); } if (ConversionDifficulty > 2) { - if ((convertType & PatternType.LowProbability) > 0) + if (convertType.HasFlag(PatternType.LowProbability)) return pattern = generateRandomPattern(0.18, 0, 0, 0); return pattern = generateRandomPattern(0.45, 0, 0, 0); } @@ -204,9 +205,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy { foreach (var obj in pattern.HitObjects) { - if ((convertType & PatternType.Stair) > 0 && obj.Column == TotalColumns - 1) + if (convertType.HasFlag(PatternType.Stair) && obj.Column == TotalColumns - 1) StairType = PatternType.ReverseStair; - if ((convertType & PatternType.ReverseStair) > 0 && obj.Column == RandomStart) + if (convertType.HasFlag(PatternType.ReverseStair) && obj.Column == RandomStart) StairType = PatternType.Stair; } } @@ -225,7 +226,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy { var pattern = new Pattern(); - bool allowStacking = (convertType & PatternType.ForceNotStack) == 0; + bool allowStacking = !convertType.HasFlag(PatternType.ForceNotStack); if (!allowStacking) noteCount = Math.Min(noteCount, TotalColumns - RandomStart - PreviousPattern.ColumnWithObjects); @@ -235,7 +236,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy { while (pattern.ColumnHasObject(nextColumn) || PreviousPattern.ColumnHasObject(nextColumn) && !allowStacking) { - if ((convertType & PatternType.Gathered) > 0) + if (convertType.HasFlag(PatternType.Gathered)) { nextColumn++; if (nextColumn == TotalColumns) @@ -367,7 +368,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy { addToCentre = false; - if ((convertType & PatternType.ForceNotStack) > 0) + if (convertType.HasFlag(PatternType.ForceNotStack)) return getRandomNoteCount(1 / 2f + p2 / 2, p2, (p2 + p3) / 2, p3); switch (TotalColumns) diff --git a/osu.Game.Tests/Visual/TestCaseIconButton.cs b/osu.Game.Tests/Visual/TestCaseIconButton.cs index 16363da527..14cba71ec8 100644 --- a/osu.Game.Tests/Visual/TestCaseIconButton.cs +++ b/osu.Game.Tests/Visual/TestCaseIconButton.cs @@ -25,11 +25,7 @@ namespace osu.Game.Tests.Visual Children = new[] { new NamedIconButton("No change", new IconButton()), - new NamedIconButton("Background colours", new IconButton - { - FlashColour = Color4.DarkGreen, - HoverColour = Color4.Green, - }), + new NamedIconButton("Background colours", new ColouredIconButton()), new NamedIconButton("Full-width", new IconButton { ButtonSize = new Vector2(200, 30) }), new NamedIconButton("Unchanging size", new IconButton(), false), new NamedIconButton("Icon colours", new IconButton @@ -41,6 +37,15 @@ namespace osu.Game.Tests.Visual }; } + private class ColouredIconButton : IconButton + { + public ColouredIconButton() + { + FlashColour = Color4.DarkGreen; + HoverColour = Color4.Green; + } + } + private class NamedIconButton : Container { public NamedIconButton(string name, IconButton button, bool allowSizeChange = true) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index fc4d43080e..49780199fd 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -45,6 +45,11 @@ namespace osu.Game.Beatmaps /// public event Action BeatmapDownloadBegan; + /// + /// Fired when a beatmap download is interrupted, due to user cancellation or other failures. + /// + public event Action BeatmapDownloadFailed; + /// /// A default representation of a WorkingBeatmap to use when no beatmap is available. /// @@ -143,7 +148,7 @@ namespace osu.Game.Beatmaps return; } - var downloadNotification = new ProgressNotification + var downloadNotification = new DownloadNotification { CompletionText = $"Imported {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}!", Text = $"Downloading {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}", @@ -175,6 +180,8 @@ namespace osu.Game.Beatmaps request.Failure += error => { + BeatmapDownloadFailed?.Invoke(request); + if (error is OperationCanceledException) return; downloadNotification.State = ProgressNotificationState.Cancelled; @@ -453,5 +460,21 @@ namespace osu.Game.Beatmaps protected override Texture GetBackground() => null; protected override Track GetTrack() => null; } + + private class DownloadNotification : ProgressNotification + { + public override bool IsImportant => false; + + protected override Notification CreateCompletionNotification() => new SilencedProgressCompletionNotification + { + Activated = CompletionClickAction, + Text = CompletionText + }; + + private class SilencedProgressCompletionNotification : ProgressCompletionNotification + { + public override bool IsImportant => false; + } + } } } diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs index 6acb58e165..6f4d4c0d6f 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs @@ -5,6 +5,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; +using osu.Game.Online.API.Requests; namespace osu.Game.Beatmaps.Drawables { @@ -19,9 +20,9 @@ namespace osu.Game.Beatmaps.Drawables private BeatmapManager beatmaps; /// - /// Whether the associated beatmap set has been downloading (by this instance or any other instance). + /// Holds the current download state of the beatmap, whether is has already been downloaded, is in progress, or is not downloaded. /// - public readonly BindableBool Downloaded = new BindableBool(); + public readonly Bindable DownloadState = new Bindable(); public BeatmapSetDownloader(BeatmapSetInfo set, bool noVideo = false) { @@ -36,10 +37,16 @@ namespace osu.Game.Beatmaps.Drawables beatmaps.ItemAdded += setAdded; beatmaps.ItemRemoved += setRemoved; + beatmaps.BeatmapDownloadBegan += downloadBegan; + beatmaps.BeatmapDownloadFailed += downloadFailed; // initial value - if (set.OnlineBeatmapSetID != null) - Downloaded.Value = beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Any(); + if (set.OnlineBeatmapSetID != null && beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Any()) + DownloadState.Value = DownloadStatus.Downloaded; + else if (beatmaps.GetExistingDownload(set) != null) + DownloadState.Value = DownloadStatus.Downloading; + else + DownloadState.Value = DownloadStatus.NotDownloaded; } protected override void Dispose(bool isDisposing) @@ -50,6 +57,8 @@ namespace osu.Game.Beatmaps.Drawables { beatmaps.ItemAdded -= setAdded; beatmaps.ItemRemoved -= setRemoved; + beatmaps.BeatmapDownloadBegan -= downloadBegan; + beatmaps.BeatmapDownloadFailed -= downloadFailed; } } @@ -57,28 +66,45 @@ namespace osu.Game.Beatmaps.Drawables /// Begin downloading the associated beatmap set. /// /// True if downloading began. False if an existing download is active or completed. - public bool Download() + public void Download() { - if (Downloaded.Value) - return false; - - if (beatmaps.GetExistingDownload(set) != null) - return false; + if (DownloadState.Value > DownloadStatus.NotDownloaded) + return; beatmaps.Download(set, noVideo); - return true; + + DownloadState.Value = DownloadStatus.Downloading; } private void setAdded(BeatmapSetInfo s) { if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID) - Downloaded.Value = true; + DownloadState.Value = DownloadStatus.Downloaded; } private void setRemoved(BeatmapSetInfo s) { if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID) - Downloaded.Value = false; + DownloadState.Value = DownloadStatus.NotDownloaded; + } + + private void downloadBegan(DownloadBeatmapSetRequest d) + { + if (d.BeatmapSet.OnlineBeatmapSetID == set.OnlineBeatmapSetID) + DownloadState.Value = DownloadStatus.Downloading; + } + + private void downloadFailed(DownloadBeatmapSetRequest d) + { + if (d.BeatmapSet.OnlineBeatmapSetID == set.OnlineBeatmapSetID) + DownloadState.Value = DownloadStatus.NotDownloaded; + } + + public enum DownloadStatus + { + NotDownloaded, + Downloading, + Downloaded, } } } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index c79938e613..52d9f31814 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -62,28 +62,30 @@ namespace osu.Game.Beatmaps.Formats protected override void ParseLine(Beatmap beatmap, Section section, string line) { + var strippedLine = StripComments(line); + switch (section) { case Section.General: - handleGeneral(line); + handleGeneral(strippedLine); return; case Section.Editor: - handleEditor(line); + handleEditor(strippedLine); return; case Section.Metadata: handleMetadata(line); return; case Section.Difficulty: - handleDifficulty(line); + handleDifficulty(strippedLine); return; case Section.Events: - handleEvent(line); + handleEvent(strippedLine); return; case Section.TimingPoints: - handleTimingPoint(line); + handleTimingPoint(strippedLine); return; case Section.HitObjects: - handleHitObject(line); + handleHitObject(strippedLine); return; } @@ -305,9 +307,9 @@ namespace osu.Game.Beatmaps.Formats bool omitFirstBarSignature = false; if (split.Length >= 8) { - int effectFlags = int.Parse(split[7]); - kiaiMode = (effectFlags & 1) > 0; - omitFirstBarSignature = (effectFlags & 8) > 0; + EffectFlags effectFlags = (EffectFlags)int.Parse(split[7]); + kiaiMode = effectFlags.HasFlag(EffectFlags.Kiai); + omitFirstBarSignature = effectFlags.HasFlag(EffectFlags.OmitFirstBarLine); } string stringSampleSet = sampleSet.ToString().ToLower(); @@ -405,5 +407,13 @@ namespace osu.Game.Beatmaps.Formats private double getOffsetTime() => ApplyOffsets ? offset : 0; private double getOffsetTime(double time) => time + (ApplyOffsets ? offset : 0); + + [Flags] + internal enum EffectFlags + { + None = 0, + Kiai = 1, + OmitFirstBarLine = 8 + } } } diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index c8874c3bc7..91c1c98438 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -57,6 +57,8 @@ namespace osu.Game.Beatmaps.Formats protected virtual void ParseLine(T output, Section section, string line) { + line = StripComments(line); + switch (section) { case Section.Colours: @@ -65,6 +67,14 @@ namespace osu.Game.Beatmaps.Formats } } + protected string StripComments(string line) + { + var index = line.IndexOf("//", StringComparison.Ordinal); + if (index > 0) + return line.Substring(0, index); + return line; + } + private bool hasComboColours; private void handleColours(T output, string line) diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 868ae5206a..b418cbd5ec 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -42,6 +42,8 @@ namespace osu.Game.Beatmaps.Formats protected override void ParseLine(Storyboard storyboard, Section section, string line) { + line = StripComments(line); + switch (section) { case Section.Events: diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index d065ecdd5f..0ba49929e9 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -26,10 +26,10 @@ namespace osu.Game.Graphics.UserInterface set { direction = value; - base.Direction = (direction & BarDirection.Horizontal) > 0 ? FillDirection.Vertical : FillDirection.Horizontal; + base.Direction = direction.HasFlag(BarDirection.Horizontal) ? FillDirection.Vertical : FillDirection.Horizontal; foreach (var bar in Children) { - bar.Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, 1.0f / Children.Count) : new Vector2(1.0f / Children.Count, 1); + bar.Size = direction.HasFlag(BarDirection.Horizontal) ? new Vector2(1, 1.0f / Children.Count) : new Vector2(1.0f / Children.Count, 1); bar.Direction = direction; } } @@ -56,14 +56,14 @@ namespace osu.Game.Graphics.UserInterface if (bar.Bar != null) { bar.Bar.Length = length; - bar.Bar.Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, size) : new Vector2(size, 1); + bar.Bar.Size = direction.HasFlag(BarDirection.Horizontal) ? new Vector2(1, size) : new Vector2(size, 1); } else { Add(new Bar { RelativeSizeAxes = Axes.Both, - Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, size) : new Vector2(size, 1), + Size = direction.HasFlag(BarDirection.Horizontal) ? new Vector2(1, size) : new Vector2(size, 1), Length = length, Direction = Direction, }); diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 5a25fe641d..eca7bf57c8 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -3,31 +3,17 @@ using OpenTK; using OpenTK.Graphics; -using osu.Framework.Allocation; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Framework.Input; -using osu.Game.Graphics.Containers; namespace osu.Game.Graphics.UserInterface { - public class IconButton : OsuClickableContainer + public class IconButton : OsuAnimatedButton { public const float BUTTON_SIZE = 30; - private Color4? flashColour; - /// - /// The colour that should be flashed when the is clicked. - /// - public Color4 FlashColour - { - get { return flashColour ?? Color4.White; } - set { flashColour = value; } - } - private Color4? iconColour; + /// /// The icon colour. This does not affect . /// @@ -42,6 +28,7 @@ namespace osu.Game.Graphics.UserInterface } private Color4? iconHoverColour; + /// /// The icon colour while the is hovered. /// @@ -51,20 +38,6 @@ namespace osu.Game.Graphics.UserInterface set { iconHoverColour = value; } } - private Color4? hoverColour; - /// - /// The background colour of the while it is hovered. - /// - public Color4 HoverColour - { - get { return hoverColour ?? Color4.White; } - set - { - hoverColour = value; - hover.Colour = value; - } - } - /// /// The icon. /// @@ -88,93 +61,39 @@ namespace osu.Game.Graphics.UserInterface /// public Vector2 ButtonSize { - get { return content.Size; } - set { content.Size = value; } + get => Content.Size; + set + { + Content.RelativeSizeAxes = Axes.None; + Content.Size = value; + } } - private readonly Container content; private readonly SpriteIcon icon; - private readonly Box hover; public IconButton() { AutoSizeAxes = Axes.Both; + ButtonSize = new Vector2(BUTTON_SIZE); - Children = new Drawable[] + Add(icon = new SpriteIcon { - content = new Container - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Size = new Vector2(BUTTON_SIZE), - CornerRadius = 5, - Masking = true, - EdgeEffect = new EdgeEffectParameters - { - Colour = Color4.Black.Opacity(0.04f), - Type = EdgeEffectType.Shadow, - Radius = 5, - }, - Children = new Drawable[] - { - hover = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - }, - icon = new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Size = new Vector2(18), - } - } - } - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - if (hoverColour == null) - HoverColour = colours.Yellow.Opacity(0.6f); - - if (flashColour == null) - FlashColour = colours.Yellow; - - Enabled.ValueChanged += enabled => this.FadeColour(enabled ? Color4.White : colours.Gray9, 200, Easing.OutQuint); + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Size = new Vector2(18), + }); } protected override bool OnHover(InputState state) { - hover.FadeIn(500, Easing.OutQuint); icon.FadeColour(IconHoverColour, 500, Easing.OutQuint); return base.OnHover(state); } protected override void OnHoverLost(InputState state) { - hover.FadeOut(500, Easing.OutQuint); icon.FadeColour(IconColour, 500, Easing.OutQuint); base.OnHoverLost(state); } - - protected override bool OnClick(InputState state) - { - hover.FlashColour(FlashColour, 800, Easing.OutQuint); - return base.OnClick(state); - } - - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) - { - content.ScaleTo(0.75f, 2000, Easing.OutQuint); - return base.OnMouseDown(state, args); - } - - protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) - { - content.ScaleTo(1, 1000, Easing.OutElastic); - return base.OnMouseUp(state, args); - } } } diff --git a/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs b/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs new file mode 100644 index 0000000000..990a2f20a9 --- /dev/null +++ b/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs @@ -0,0 +1,109 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input; +using osu.Game.Graphics.Containers; +using OpenTK.Graphics; + +namespace osu.Game.Graphics.UserInterface +{ + /// + /// Highlight on hover, bounce on click. + /// + public class OsuAnimatedButton : OsuClickableContainer + { + /// + /// The colour that should be flashed when the is clicked. + /// + protected Color4 FlashColour = Color4.White.Opacity(0.3f); + + private Color4 hoverColour = Color4.White.Opacity(0.1f); + + /// + /// The background colour of the while it is hovered. + /// + protected Color4 HoverColour + { + get => hoverColour; + set + { + hoverColour = value; + hover.Colour = value; + } + } + + protected override Container Content => content; + + private readonly Container content; + private readonly Box hover; + + public OsuAnimatedButton() + { + base.Content.Add(content = new Container + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + CornerRadius = 5, + Masking = true, + EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.Black.Opacity(0.04f), + Type = EdgeEffectType.Shadow, + Radius = 5, + }, + Children = new Drawable[] + { + hover = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = HoverColour, + Blending = BlendingMode.Additive, + Alpha = 0, + }, + } + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Enabled.BindValueChanged(enabled => this.FadeColour(enabled ? Color4.White : colours.Gray9, 200, Easing.OutQuint), true); + } + + protected override bool OnHover(InputState state) + { + hover.FadeIn(500, Easing.OutQuint); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + hover.FadeOut(500, Easing.OutQuint); + base.OnHoverLost(state); + } + + protected override bool OnClick(InputState state) + { + hover.FlashColour(FlashColour, 800, Easing.OutQuint); + return base.OnClick(state); + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + Content.ScaleTo(0.75f, 2000, Easing.OutQuint); + return base.OnMouseDown(state, args); + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + Content.ScaleTo(1, 1000, Easing.OutElastic); + return base.OnMouseUp(state, args); + } + } +} diff --git a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs index f490306acf..dd5454314d 100644 --- a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs +++ b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs @@ -56,15 +56,15 @@ namespace osu.Game.Graphics.UserInterface set { base.Origin = value; - c1.Origin = c1.Anchor = (value & Anchor.x2) > 0 ? Anchor.TopLeft : Anchor.TopRight; - c2.Origin = c2.Anchor = (value & Anchor.x2) > 0 ? Anchor.TopRight : Anchor.TopLeft; + c1.Origin = c1.Anchor = value.HasFlag(Anchor.x2) ? Anchor.TopLeft : Anchor.TopRight; + c2.Origin = c2.Anchor = value.HasFlag(Anchor.x2) ? Anchor.TopRight : Anchor.TopLeft; - X = (value & Anchor.x2) > 0 ? SIZE_RETRACTED.X * shear * 0.5f : 0; + X = value.HasFlag(Anchor.x2) ? SIZE_RETRACTED.X * shear * 0.5f : 0; Remove(c1); Remove(c2); - c1.Depth = (value & Anchor.x2) > 0 ? 0 : 1; - c2.Depth = (value & Anchor.x2) > 0 ? 1 : 0; + c1.Depth = value.HasFlag(Anchor.x2) ? 0 : 1; + c2.Depth = value.HasFlag(Anchor.x2) ? 1 : 0; Add(c1); Add(c2); } diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs index 4fce6a49fb..7a227f4bfa 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs @@ -61,20 +61,23 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons Action = () => { - if (!downloader.Download()) + if (downloader.DownloadState.Value == BeatmapSetDownloader.DownloadStatus.Downloading) { Content.MoveToX(-5, 50, Easing.OutSine).Then() .MoveToX(5, 100, Easing.InOutSine).Then() .MoveToX(-5, 100, Easing.InOutSine).Then() .MoveToX(0, 50, Easing.InSine); + return; } + + downloader.Download(); }; - downloader.Downloaded.ValueChanged += d => + downloader.DownloadState.ValueChanged += d => { - if (d) + if (d == BeatmapSetDownloader.DownloadStatus.Downloaded) this.FadeOut(200); - else + else if (d == BeatmapSetDownloader.DownloadStatus.NotDownloaded) this.FadeIn(200); }; } diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 4060f26008..c9e6f39270 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -168,11 +168,10 @@ namespace osu.Game.Overlays.Direct }, new DownloadButton(SetInfo) { - Size = new Vector2(30), + Size = new Vector2(50, 30), Margin = new MarginPadding(horizontal_padding), - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Colour = colours.Gray5, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, }, }, }, diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 812a0e2073..17c5153dab 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -120,8 +120,8 @@ namespace osu.Game.Overlays.Direct Alpha = 0, Child = new DownloadButton(SetInfo) { - Size = new Vector2(height - vertical_padding * 2), - Margin = new MarginPadding { Left = vertical_padding }, + Size = new Vector2(height - vertical_padding * 3), + Margin = new MarginPadding { Left = vertical_padding, Right = vertical_padding }, }, }, new FillFlowContainer diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index e63c290ce5..76da4b61b0 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -99,6 +99,7 @@ namespace osu.Game.Overlays.Direct attachDownload(downloadRequest); beatmaps.BeatmapDownloadBegan += attachDownload; + beatmaps.ItemAdded += setAdded; } public override bool DisposeOnDeathRemoval => true; @@ -107,6 +108,7 @@ namespace osu.Game.Overlays.Direct { base.Dispose(isDisposing); beatmaps.BeatmapDownloadBegan -= attachDownload; + beatmaps.ItemAdded -= setAdded; } protected override void Update() @@ -171,6 +173,12 @@ namespace osu.Game.Overlays.Direct }; } + private void setAdded(BeatmapSetInfo s) + { + if (s.OnlineBeatmapSetID == SetInfo.OnlineBeatmapSetID) + progressBar.FadeOut(500); + } + protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index 1ffa8dbd35..7758e171c5 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -1,76 +1,109 @@ // Copyright (c) 2007-2018 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.Input; +using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; using OpenTK; namespace osu.Game.Overlays.Direct { - public class DownloadButton : OsuClickableContainer + public class DownloadButton : OsuAnimatedButton { private readonly SpriteIcon icon; + private readonly SpriteIcon checkmark; + private readonly BeatmapSetDownloader downloader; + private readonly Box background; + + private OsuColour colours; public DownloadButton(BeatmapSetInfo set, bool noVideo = false) { - BeatmapSetDownloader downloader; - Children = new Drawable[] + AddRange(new Drawable[] { downloader = new BeatmapSetDownloader(set, noVideo), + background = new Box + { + RelativeSizeAxes = Axes.Both, + Depth = float.MaxValue + }, icon = new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(30), - Icon = FontAwesome.fa_osu_chevron_down_o, + Size = new Vector2(13), + Icon = FontAwesome.fa_download, }, - }; + checkmark = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + X = 8, + Size = Vector2.Zero, + Icon = FontAwesome.fa_check, + } + }); Action = () => { - if (!downloader.Download()) + if (downloader.DownloadState == BeatmapSetDownloader.DownloadStatus.Downloading) { + // todo: replace with ShakeContainer after https://github.com/ppy/osu/pull/2909 is merged. Content.MoveToX(-5, 50, Easing.OutSine).Then() .MoveToX(5, 100, Easing.InOutSine).Then() .MoveToX(-5, 100, Easing.InOutSine).Then() .MoveToX(0, 50, Easing.InSine); } - }; - - downloader.Downloaded.ValueChanged += d => - { - if (d) - this.FadeOut(200); + else if (downloader.DownloadState == BeatmapSetDownloader.DownloadStatus.Downloaded) + { + // TODO: Jump to song select with this set when the capability is implemented + } else - this.FadeIn(200); + { + downloader.Download(); + } }; } - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + protected override void LoadComplete() { - icon.ScaleTo(0.9f, 1000, Easing.Out); - return base.OnMouseDown(state, args); + base.LoadComplete(); + downloader.DownloadState.BindValueChanged(updateState, true); + FinishTransforms(true); } - protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + [BackgroundDependencyLoader(permitNulls: true)] + private void load(OsuColour colours) { - icon.ScaleTo(1f, 500, Easing.OutElastic); - return base.OnMouseUp(state, args); + this.colours = colours; } - protected override bool OnHover(InputState state) + private void updateState(BeatmapSetDownloader.DownloadStatus state) { - icon.ScaleTo(1.1f, 500, Easing.OutElastic); - return base.OnHover(state); - } + switch (state) + { + case BeatmapSetDownloader.DownloadStatus.NotDownloaded: + background.FadeColour(colours.Gray4, 500, Easing.InOutExpo); + icon.MoveToX(0, 500, Easing.InOutExpo); + checkmark.ScaleTo(Vector2.Zero, 500, Easing.InOutExpo); + break; - protected override void OnHoverLost(InputState state) - { - icon.ScaleTo(1f, 500, Easing.OutElastic); + case BeatmapSetDownloader.DownloadStatus.Downloading: + background.FadeColour(colours.Blue, 500, Easing.InOutExpo); + icon.MoveToX(0, 500, Easing.InOutExpo); + checkmark.ScaleTo(Vector2.Zero, 500, Easing.InOutExpo); + break; + + case BeatmapSetDownloader.DownloadStatus.Downloaded: + background.FadeColour(colours.Green, 500, Easing.InOutExpo); + icon.MoveToX(-8, 500, Easing.InOutExpo); + checkmark.ScaleTo(new Vector2(13), 500, Easing.InOutExpo); + break; + } } } } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index a57d5fd183..56af04c498 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -142,14 +142,14 @@ namespace osu.Game.Overlays Anchor = Anchor.Centre, Children = new[] { - prevButton = new IconButton + prevButton = new MusicIconButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, Action = prev, Icon = FontAwesome.fa_step_backward, }, - playButton = new IconButton + playButton = new MusicIconButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -158,7 +158,7 @@ namespace osu.Game.Overlays Action = play, Icon = FontAwesome.fa_play_circle_o, }, - nextButton = new IconButton + nextButton = new MusicIconButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -167,7 +167,7 @@ namespace osu.Game.Overlays }, } }, - playlistButton = new IconButton + playlistButton = new MusicIconButton { Origin = Anchor.Centre, Anchor = Anchor.CentreRight, @@ -405,6 +405,16 @@ namespace osu.Game.Overlays Prev } + private class MusicIconButton : IconButton + { + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + HoverColour = colours.YellowDark.Opacity(0.6f); + FlashColour = colours.Yellow; + } + } + private class Background : BufferedContainer { private readonly Sprite sprite; diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 3dc8f5ec15..d891cd96e8 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -128,7 +128,8 @@ namespace osu.Game.Overlays var section = sections.Children.FirstOrDefault(s => s.AcceptTypes.Any(accept => accept.IsAssignableFrom(ourType))); section?.Add(notification, notification.DisplayOnTop ? -runningDepth : runningDepth); - State = Visibility.Visible; + if (notification.IsImportant) + State = Visibility.Visible; updateCounts(); }); diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index d2b5ae1829..3a3fcb54e0 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -23,6 +23,11 @@ namespace osu.Game.Overlays.Notifications /// public event Action Closed; + /// + /// Whether this notification should forcefully display itself. + /// + public virtual bool IsImportant => true; + /// /// Run on user activating the notification. Return true to close. /// diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index c7870a72de..4514f3c33c 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -118,9 +118,9 @@ namespace osu.Game.Overlays.Toolbar { Direction = FillDirection.Vertical, RelativeSizeAxes = Axes.Both, //stops us being considered in parent's autosize - Anchor = (TooltipAnchor & Anchor.x0) > 0 ? Anchor.BottomLeft : Anchor.BottomRight, + Anchor = TooltipAnchor.HasFlag(Anchor.x0) ? Anchor.BottomLeft : Anchor.BottomRight, Origin = TooltipAnchor, - Position = new Vector2((TooltipAnchor & Anchor.x0) > 0 ? 5 : -5, 5), + Position = new Vector2(TooltipAnchor.HasFlag(Anchor.x0) ? 5 : -5, 5), Alpha = 0, Children = new[] { diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index 95589d8953..48512a71c2 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -39,14 +39,14 @@ namespace osu.Game.Rulesets.Objects.Legacy HitObject result = null; - if ((type & ConvertHitObjectType.Circle) > 0) + if (type.HasFlag(ConvertHitObjectType.Circle)) { result = CreateHit(new Vector2(int.Parse(split[0]), int.Parse(split[1])), combo); if (split.Length > 5) readCustomSampleBanks(split[5], bankInfo); } - else if ((type & ConvertHitObjectType.Slider) > 0) + else if (type.HasFlag(ConvertHitObjectType.Slider)) { var pos = new Vector2(int.Parse(split[0]), int.Parse(split[1])); @@ -150,14 +150,14 @@ namespace osu.Game.Rulesets.Objects.Legacy result = CreateSlider(pos, combo, points, length, curveType, repeatCount, nodeSamples); } - else if ((type & ConvertHitObjectType.Spinner) > 0) + else if (type.HasFlag(ConvertHitObjectType.Spinner)) { result = CreateSpinner(new Vector2(512, 384) / 2, Convert.ToDouble(split[5], CultureInfo.InvariantCulture) + offset); if (split.Length > 6) readCustomSampleBanks(split[6], bankInfo); } - else if ((type & ConvertHitObjectType.Hold) > 0) + else if (type.HasFlag(ConvertHitObjectType.Hold)) { // Note: Hold is generated by BMS converts @@ -266,7 +266,7 @@ namespace osu.Game.Rulesets.Objects.Legacy } }; - if ((type & LegacySoundType.Finish) > 0) + if (type.HasFlag(LegacySoundType.Finish)) { soundTypes.Add(new SampleInfo { @@ -276,7 +276,7 @@ namespace osu.Game.Rulesets.Objects.Legacy }); } - if ((type & LegacySoundType.Whistle) > 0) + if (type.HasFlag(LegacySoundType.Whistle)) { soundTypes.Add(new SampleInfo { @@ -286,7 +286,7 @@ namespace osu.Game.Rulesets.Objects.Legacy }); } - if ((type & LegacySoundType.Clap) > 0) + if (type.HasFlag(LegacySoundType.Clap)) { soundTypes.Add(new SampleInfo { diff --git a/osu.Game/Rulesets/Replays/Legacy/LegacyReplayFrame.cs b/osu.Game/Rulesets/Replays/Legacy/LegacyReplayFrame.cs index d39d765bfe..5bd56e0cc0 100644 --- a/osu.Game/Rulesets/Replays/Legacy/LegacyReplayFrame.cs +++ b/osu.Game/Rulesets/Replays/Legacy/LegacyReplayFrame.cs @@ -15,10 +15,10 @@ namespace osu.Game.Rulesets.Replays.Legacy public bool MouseLeft => MouseLeft1 || MouseLeft2; public bool MouseRight => MouseRight1 || MouseRight2; - public bool MouseLeft1 => (ButtonState & ReplayButtonState.Left1) > 0; - public bool MouseRight1 => (ButtonState & ReplayButtonState.Right1) > 0; - public bool MouseLeft2 => (ButtonState & ReplayButtonState.Left2) > 0; - public bool MouseRight2 => (ButtonState & ReplayButtonState.Right2) > 0; + public bool MouseLeft1 => ButtonState.HasFlag(ReplayButtonState.Left1); + public bool MouseRight1 => ButtonState.HasFlag(ReplayButtonState.Right1); + public bool MouseLeft2 => ButtonState.HasFlag(ReplayButtonState.Left2); + public bool MouseRight2 => ButtonState.HasFlag(ReplayButtonState.Right2); public ReplayButtonState ButtonState; diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs index f46cc7ef9d..5928fbaa1b 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs @@ -27,16 +27,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline public TimelineButton() { - InternalChild = button = new IconButton - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - IconColour = OsuColour.Gray(0.35f), - IconHoverColour = Color4.White, - HoverColour = OsuColour.Gray(0.25f), - FlashColour = OsuColour.Gray(0.5f), - Action = () => Action?.Invoke() - }; + InternalChild = button = new TimelineIconButton { Action = () => Action?.Invoke() }; button.Enabled.BindTo(Enabled); Width = button.ButtonSize.X; @@ -48,5 +39,18 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline button.ButtonSize = new Vector2(button.ButtonSize.X, DrawHeight); } + + private class TimelineIconButton : IconButton + { + public TimelineIconButton() + { + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + IconColour = OsuColour.Gray(0.35f); + IconHoverColour = Color4.White; + HoverColour = OsuColour.Gray(0.25f); + FlashColour = OsuColour.Gray(0.5f); + } + } } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index b406bda411..49a180902b 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -169,7 +169,7 @@ namespace osu.Game.Screens.Play OnPause = () => { pauseContainer.Retries = RestartCount; - hudOverlay.KeyCounter.IsCounting = pauseContainer.IsPaused; + hudOverlay.KeyCounter.IsCounting = !pauseContainer.IsPaused; }, OnResume = () => hudOverlay.KeyCounter.IsCounting = true, Children = new[] @@ -219,9 +219,7 @@ namespace osu.Game.Screens.Play { if (!IsCurrentScreen) return; - //we want to hide the hitrenderer immediately (looks better). - //we may be able to remove this once the mouse cursor trail is improved. - RulesetContainer?.Hide(); + pauseContainer.Hide(); Restart(); }, } diff --git a/osu.Game/Skinning/LegacySkinDecoder.cs b/osu.Game/Skinning/LegacySkinDecoder.cs index 0ef54c7310..d4f1c5c6f1 100644 --- a/osu.Game/Skinning/LegacySkinDecoder.cs +++ b/osu.Game/Skinning/LegacySkinDecoder.cs @@ -14,6 +14,8 @@ namespace osu.Game.Skinning protected override void ParseLine(SkinConfiguration skin, Section section, string line) { + line = StripComments(line); + switch (section) { case Section.General: