From 545049941592cda599e92ae24d67f9c21f057aee Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 19 Jun 2017 14:32:53 +0200 Subject: [PATCH 01/72] Implement OsuScreen::CanBeatmapChange and use it in the music controller --- osu.Game/OsuGame.cs | 11 +++++---- osu.Game/Overlays/MusicController.cs | 35 ++++++++++++++++++++++++---- osu.Game/Screens/OsuScreen.cs | 2 ++ osu.Game/Screens/Play/Player.cs | 2 ++ osu.Game/Screens/Ranking/Results.cs | 2 ++ 5 files changed, 43 insertions(+), 9 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 7e5b913d10..fd68aa0fb3 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -298,21 +298,22 @@ namespace osu.Game private Container overlayContent; - private OsuScreen currentScreen; + public readonly Bindable CurrentScreen = new Bindable(); + private FrameworkConfigManager frameworkConfig; private void screenChanged(Screen newScreen) { - currentScreen = newScreen as OsuScreen; + CurrentScreen.Value = newScreen as OsuScreen; - if (currentScreen == null) + if (CurrentScreen.Value == null) { Exit(); return; } //central game screen change logic. - if (!currentScreen.ShowOverlays) + if (!CurrentScreen.Value.ShowOverlays) { settings.State = Visibility.Hidden; Toolbar.State = Visibility.Hidden; @@ -362,7 +363,7 @@ namespace osu.Game mainContent.Padding = new MarginPadding { Top = Toolbar.Position.Y + Toolbar.DrawHeight }; - Cursor.State = currentScreen?.HasLocalCursorDisplayed == false ? Visibility.Visible : Visibility.Hidden; + Cursor.State = CurrentScreen.Value?.HasLocalCursorDisplayed == false ? Visibility.Visible : Visibility.Hidden; } private void screenAdded(Screen newScreen) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 3a8a0a883a..e3dca32383 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -16,13 +16,14 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.Input; using osu.Framework.Localisation; +using osu.Framework.Threading; using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Framework.Threading; using osu.Game.Overlays.Music; using osu.Game.Graphics.UserInterface; +using osu.Game.Screens; namespace osu.Game.Overlays { @@ -39,7 +40,9 @@ namespace osu.Game.Overlays private Drawable currentBackground; private DragBar progressBar; + private IconButton prevButton; private IconButton playButton; + private IconButton nextButton; private IconButton playlistButton; private SpriteText title, artist; @@ -50,9 +53,13 @@ namespace osu.Game.Overlays private readonly Bindable beatmapBacking = new Bindable(); + private readonly Bindable currentScreenBacking = new Bindable(); + private Container dragContainer; private Container playerContainer; + private bool canChangeBeatmap; + public MusicController() { Width = 400; @@ -81,7 +88,7 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(OsuGameBase game, OsuColour colours, LocalisationEngine localisation) + private void load(OsuGame game, OsuColour colours, LocalisationEngine localisation) { this.localisation = localisation; @@ -153,7 +160,7 @@ namespace osu.Game.Overlays Anchor = Anchor.Centre, Children = new[] { - new IconButton + prevButton = new IconButton { Action = prev, Icon = FontAwesome.fa_step_backward, @@ -165,7 +172,7 @@ namespace osu.Game.Overlays Action = play, Icon = FontAwesome.fa_play_circle_o, }, - new IconButton + nextButton = new IconButton { Action = next, Icon = FontAwesome.fa_step_forward, @@ -197,6 +204,7 @@ namespace osu.Game.Overlays }; beatmapBacking.BindTo(game.Beatmap); + currentScreenBacking.BindTo(game.CurrentScreen); playlist.StateChanged += (c, s) => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, EasingTypes.OutQuint); } @@ -206,9 +214,24 @@ namespace osu.Game.Overlays beatmapBacking.ValueChanged += beatmapChanged; beatmapBacking.TriggerChange(); + currentScreenBacking.ValueChanged += screenChanged; + currentScreenBacking.TriggerChange(); + base.LoadComplete(); } + private void screenChanged(OsuScreen newScreen) + { + canChangeBeatmap = newScreen?.CanChangeBeatmap ?? false; + + prevButton.Enabled = canChangeBeatmap; + playButton.Enabled = canChangeBeatmap; + nextButton.Enabled = canChangeBeatmap; + playlistButton.Enabled = canChangeBeatmap; + + progressBar.IsEnabled = canChangeBeatmap; + } + protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); @@ -250,12 +273,16 @@ namespace osu.Game.Overlays private void prev() { + if(!canChangeBeatmap) return; + queuedDirection = TransformDirection.Prev; playlist.PlayPrevious(); } private void next() { + if (!canChangeBeatmap) return; + queuedDirection = TransformDirection.Next; playlist.PlayNext(); } diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index de9c698f2a..855ddbbd2f 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -29,6 +29,8 @@ namespace osu.Game.Screens internal virtual bool AllowRulesetChange => true; + internal virtual bool CanChangeBeatmap => true; + private readonly Bindable beatmap = new Bindable(); private readonly Bindable ruleset = new Bindable(); diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index c38ea65f90..f22133fa6a 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -32,6 +32,8 @@ namespace osu.Game.Screens.Play internal override bool ShowOverlays => false; + internal override bool CanChangeBeatmap => false; + internal override bool HasLocalCursorDisplayed => !pauseContainer.IsPaused && !HasFailed && HitRenderer.ProvidingUserCursor; public BeatmapInfo BeatmapInfo; diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index 2523ce05ec..36bfa67f86 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -279,5 +279,7 @@ namespace osu.Game.Screens.Ranking modeChangeButtons.Current.TriggerChange(); } + + internal override bool CanChangeBeatmap => false; } } From 13df0e0b04d575c0baf9ccbe8badc41fc392d87d Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 19 Jun 2017 14:52:36 +0200 Subject: [PATCH 02/72] Fixed test case --- osu.Game/OsuGame.cs | 2 -- osu.Game/OsuGameBase.cs | 3 +++ osu.Game/Overlays/MusicController.cs | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index fd68aa0fb3..cea041b04d 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -298,8 +298,6 @@ namespace osu.Game private Container overlayContent; - public readonly Bindable CurrentScreen = new Bindable(); - private FrameworkConfigManager frameworkConfig; private void screenChanged(Screen newScreen) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 306cdaddf0..56224675c1 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -18,6 +18,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Cursor; using osu.Game.Graphics.Processing; using osu.Game.Online.API; +using osu.Game.Screens; using SQLite.Net; using osu.Framework.Graphics.Performance; @@ -45,6 +46,8 @@ namespace osu.Game public readonly Bindable Beatmap = new Bindable(); + public readonly Bindable CurrentScreen = new Bindable(); + private Bindable fpsDisplayVisible; protected AssemblyName AssemblyName => Assembly.GetEntryAssembly()?.GetName() ?? new AssemblyName { Version = new Version() }; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index e3dca32383..3c91b8de41 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -88,7 +88,7 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(OsuGame game, OsuColour colours, LocalisationEngine localisation) + private void load(OsuGameBase game, OsuColour colours, LocalisationEngine localisation) { this.localisation = localisation; @@ -222,7 +222,7 @@ namespace osu.Game.Overlays private void screenChanged(OsuScreen newScreen) { - canChangeBeatmap = newScreen?.CanChangeBeatmap ?? false; + canChangeBeatmap = newScreen?.CanChangeBeatmap ?? true; prevButton.Enabled = canChangeBeatmap; playButton.Enabled = canChangeBeatmap; From 9cc5dc6c2b90b861cafa70f51df0755cb0dd1bb3 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 19 Jun 2017 15:03:07 +0200 Subject: [PATCH 03/72] Only disallow changing the current track, not pausing or seeking it --- osu.Game/Overlays/MusicController.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 3c91b8de41..2d2cdd1b23 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -225,11 +225,8 @@ namespace osu.Game.Overlays canChangeBeatmap = newScreen?.CanChangeBeatmap ?? true; prevButton.Enabled = canChangeBeatmap; - playButton.Enabled = canChangeBeatmap; nextButton.Enabled = canChangeBeatmap; playlistButton.Enabled = canChangeBeatmap; - - progressBar.IsEnabled = canChangeBeatmap; } protected override void UpdateAfterChildren() @@ -249,7 +246,7 @@ namespace osu.Game.Overlays progressBar.UpdatePosition(track.Length == 0 ? 0 : (float)(track.CurrentTime / track.Length)); playButton.Icon = track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o; - if (track.HasCompleted && !track.Looping) next(); + if (track.HasCompleted && !track.Looping && canChangeBeatmap) next(); } else playButton.Icon = FontAwesome.fa_play_circle_o; @@ -273,16 +270,12 @@ namespace osu.Game.Overlays private void prev() { - if(!canChangeBeatmap) return; - queuedDirection = TransformDirection.Prev; playlist.PlayPrevious(); } private void next() { - if (!canChangeBeatmap) return; - queuedDirection = TransformDirection.Next; playlist.PlayNext(); } From 73f2709a2dc106d8438bee6d015a4451470ac8d5 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 19 Jun 2017 16:30:58 +0200 Subject: [PATCH 04/72] Move logic into PlaylistOverlay --- osu.Game/Overlays/Music/PlaylistOverlay.cs | 13 +++++++++++-- osu.Game/Overlays/MusicController.cs | 19 +------------------ 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 1ed7da83b6..e524089602 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -7,17 +7,18 @@ using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Configuration; +using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Input; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Graphics; +using osu.Game.Screens; using OpenTK; using OpenTK.Graphics; -using osu.Framework.Extensions; -using osu.Framework.Input; namespace osu.Game.Overlays.Music { @@ -35,9 +36,13 @@ namespace osu.Game.Overlays.Music private readonly Bindable beatmapBacking = new Bindable(); + private readonly Bindable currentScreenBacking = new Bindable(); + public IEnumerable BeatmapSets; private InputManager inputManager; + private bool canChangeBeatmap => currentScreenBacking.Value?.CanChangeBeatmap != false; + [BackgroundDependencyLoader] private void load(OsuGameBase game, BeatmapDatabase beatmaps, OsuColour colours, UserInputManager inputManager) { @@ -86,6 +91,7 @@ namespace osu.Game.Overlays.Music list.BeatmapSets = BeatmapSets = beatmaps.GetAllWithChildren().ToList(); beatmapBacking.BindTo(game.Beatmap); + currentScreenBacking.BindTo(game.CurrentScreen); filter.Search.OnCommit = (sender, newText) => { var beatmap = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault(); @@ -152,6 +158,9 @@ namespace osu.Game.Overlays.Music private void playSpecified(BeatmapInfo info) { + if (!canChangeBeatmap) + return; + beatmapBacking.Value = beatmaps.GetWorkingBeatmap(info, beatmapBacking); Task.Run(() => diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 2d2cdd1b23..dfccc3ec64 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -53,13 +53,9 @@ namespace osu.Game.Overlays private readonly Bindable beatmapBacking = new Bindable(); - private readonly Bindable currentScreenBacking = new Bindable(); - private Container dragContainer; private Container playerContainer; - private bool canChangeBeatmap; - public MusicController() { Width = 400; @@ -204,7 +200,6 @@ namespace osu.Game.Overlays }; beatmapBacking.BindTo(game.Beatmap); - currentScreenBacking.BindTo(game.CurrentScreen); playlist.StateChanged += (c, s) => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, EasingTypes.OutQuint); } @@ -214,21 +209,9 @@ namespace osu.Game.Overlays beatmapBacking.ValueChanged += beatmapChanged; beatmapBacking.TriggerChange(); - currentScreenBacking.ValueChanged += screenChanged; - currentScreenBacking.TriggerChange(); - base.LoadComplete(); } - private void screenChanged(OsuScreen newScreen) - { - canChangeBeatmap = newScreen?.CanChangeBeatmap ?? true; - - prevButton.Enabled = canChangeBeatmap; - nextButton.Enabled = canChangeBeatmap; - playlistButton.Enabled = canChangeBeatmap; - } - protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); @@ -246,7 +229,7 @@ namespace osu.Game.Overlays progressBar.UpdatePosition(track.Length == 0 ? 0 : (float)(track.CurrentTime / track.Length)); playButton.Icon = track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o; - if (track.HasCompleted && !track.Looping && canChangeBeatmap) next(); + if (track.HasCompleted && !track.Looping) next(); } else playButton.Icon = FontAwesome.fa_play_circle_o; From cb8b3cb8fba9a3efc94305ff5e0d33adbdc5330e Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 19 Jun 2017 16:31:45 +0200 Subject: [PATCH 05/72] CI fix --- osu.Game/Overlays/MusicController.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index dfccc3ec64..79de415614 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -23,7 +23,6 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Music; using osu.Game.Graphics.UserInterface; -using osu.Game.Screens; namespace osu.Game.Overlays { From 8bee06943b816c76a155f59bf76c0bb1af9d14df Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 19 Jun 2017 16:33:08 +0200 Subject: [PATCH 06/72] Removed ununsed variables --- osu.Game/Overlays/MusicController.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 79de415614..cee0ab88c6 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -39,9 +39,7 @@ namespace osu.Game.Overlays private Drawable currentBackground; private DragBar progressBar; - private IconButton prevButton; private IconButton playButton; - private IconButton nextButton; private IconButton playlistButton; private SpriteText title, artist; @@ -155,7 +153,7 @@ namespace osu.Game.Overlays Anchor = Anchor.Centre, Children = new[] { - prevButton = new IconButton + new IconButton { Action = prev, Icon = FontAwesome.fa_step_backward, @@ -167,7 +165,7 @@ namespace osu.Game.Overlays Action = play, Icon = FontAwesome.fa_play_circle_o, }, - nextButton = new IconButton + new IconButton { Action = next, Icon = FontAwesome.fa_step_forward, From 15a1dd14a6f96e2a8b13947da7126402a7fae385 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 19 Jun 2017 16:45:21 +0200 Subject: [PATCH 07/72] CanChangeBeatmap -> CanBeatmapChange --- osu.Game/Overlays/Music/PlaylistOverlay.cs | 4 ++-- osu.Game/Screens/OsuScreen.cs | 2 +- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/Ranking/Results.cs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index e524089602..afe866c0df 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -41,7 +41,7 @@ namespace osu.Game.Overlays.Music public IEnumerable BeatmapSets; private InputManager inputManager; - private bool canChangeBeatmap => currentScreenBacking.Value?.CanChangeBeatmap != false; + private bool canBeatmapChange => currentScreenBacking.Value?.CanBeatmapChange != false; [BackgroundDependencyLoader] private void load(OsuGameBase game, BeatmapDatabase beatmaps, OsuColour colours, UserInputManager inputManager) @@ -158,7 +158,7 @@ namespace osu.Game.Overlays.Music private void playSpecified(BeatmapInfo info) { - if (!canChangeBeatmap) + if (!canBeatmapChange) return; beatmapBacking.Value = beatmaps.GetWorkingBeatmap(info, beatmapBacking); diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 855ddbbd2f..6fbabd675e 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -29,7 +29,7 @@ namespace osu.Game.Screens internal virtual bool AllowRulesetChange => true; - internal virtual bool CanChangeBeatmap => true; + internal virtual bool CanBeatmapChange => true; private readonly Bindable beatmap = new Bindable(); diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index f22133fa6a..47649372bf 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Play internal override bool ShowOverlays => false; - internal override bool CanChangeBeatmap => false; + internal override bool CanBeatmapChange => false; internal override bool HasLocalCursorDisplayed => !pauseContainer.IsPaused && !HasFailed && HitRenderer.ProvidingUserCursor; diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index 36bfa67f86..8cd45e4b5d 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -280,6 +280,6 @@ namespace osu.Game.Screens.Ranking modeChangeButtons.Current.TriggerChange(); } - internal override bool CanChangeBeatmap => false; + internal override bool CanBeatmapChange => false; } } From aec46a57c82729057793a79b7a6c628ddf0422ab Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 19 Jun 2017 17:33:58 +0200 Subject: [PATCH 08/72] Restart the current track when pressing PREVIOUS or NEXT rather than doing nothing --- osu.Game/Overlays/Music/PlaylistOverlay.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index afe866c0df..aa4cfdc00f 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -159,7 +159,10 @@ namespace osu.Game.Overlays.Music private void playSpecified(BeatmapInfo info) { if (!canBeatmapChange) + { + beatmapBacking.Value?.Track?.Seek(0); return; + } beatmapBacking.Value = beatmaps.GetWorkingBeatmap(info, beatmapBacking); From 667e6a2d6bddad3e426805ffeaf06ea44410384a Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 19 Jun 2017 18:06:39 +0200 Subject: [PATCH 09/72] Applied suggested changes --- osu.Game/OsuGame.cs | 11 +++++++---- osu.Game/OsuGameBase.cs | 2 -- osu.Game/Overlays/Music/PlaylistOverlay.cs | 7 ++----- osu.Game/Overlays/MusicController.cs | 15 +++++++++++++++ osu.Game/Screens/OsuScreen.cs | 2 +- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/Ranking/Results.cs | 2 +- 7 files changed, 27 insertions(+), 14 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index cea041b04d..6a80840e93 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -298,20 +298,21 @@ namespace osu.Game private Container overlayContent; + private OsuScreen currentScreen; private FrameworkConfigManager frameworkConfig; private void screenChanged(Screen newScreen) { - CurrentScreen.Value = newScreen as OsuScreen; + currentScreen = newScreen as OsuScreen; - if (CurrentScreen.Value == null) + if (currentScreen == null) { Exit(); return; } //central game screen change logic. - if (!CurrentScreen.Value.ShowOverlays) + if (!currentScreen.ShowOverlays) { settings.State = Visibility.Hidden; Toolbar.State = Visibility.Hidden; @@ -326,6 +327,8 @@ namespace osu.Game } ScreenChanged?.Invoke(newScreen); + + musicController.AllowBeatmapChange = currentScreen.AllowBeatmapChange; } protected override bool OnExiting() @@ -361,7 +364,7 @@ namespace osu.Game mainContent.Padding = new MarginPadding { Top = Toolbar.Position.Y + Toolbar.DrawHeight }; - Cursor.State = CurrentScreen.Value?.HasLocalCursorDisplayed == false ? Visibility.Visible : Visibility.Hidden; + Cursor.State = currentScreen?.HasLocalCursorDisplayed == false ? Visibility.Visible : Visibility.Hidden; } private void screenAdded(Screen newScreen) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 56224675c1..5350cd03ea 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -46,8 +46,6 @@ namespace osu.Game public readonly Bindable Beatmap = new Bindable(); - public readonly Bindable CurrentScreen = new Bindable(); - private Bindable fpsDisplayVisible; protected AssemblyName AssemblyName => Assembly.GetEntryAssembly()?.GetName() ?? new AssemblyName { Version = new Version() }; diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index aa4cfdc00f..53844a02d2 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -36,13 +36,11 @@ namespace osu.Game.Overlays.Music private readonly Bindable beatmapBacking = new Bindable(); - private readonly Bindable currentScreenBacking = new Bindable(); + public bool AllowBeatmapChange = true; public IEnumerable BeatmapSets; private InputManager inputManager; - private bool canBeatmapChange => currentScreenBacking.Value?.CanBeatmapChange != false; - [BackgroundDependencyLoader] private void load(OsuGameBase game, BeatmapDatabase beatmaps, OsuColour colours, UserInputManager inputManager) { @@ -91,7 +89,6 @@ namespace osu.Game.Overlays.Music list.BeatmapSets = BeatmapSets = beatmaps.GetAllWithChildren().ToList(); beatmapBacking.BindTo(game.Beatmap); - currentScreenBacking.BindTo(game.CurrentScreen); filter.Search.OnCommit = (sender, newText) => { var beatmap = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault(); @@ -158,7 +155,7 @@ namespace osu.Game.Overlays.Music private void playSpecified(BeatmapInfo info) { - if (!canBeatmapChange) + if (!AllowBeatmapChange) { beatmapBacking.Value?.Track?.Seek(0); return; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index cee0ab88c6..457174a67f 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -53,6 +53,21 @@ namespace osu.Game.Overlays private Container dragContainer; private Container playerContainer; + private bool allowBeatmapChange = true; + + public bool AllowBeatmapChange + { + get + { + return allowBeatmapChange; + } + set + { + allowBeatmapChange = value; + playlist.AllowBeatmapChange = value; + } + } + public MusicController() { Width = 400; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 6fbabd675e..3eb26a01a9 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -29,7 +29,7 @@ namespace osu.Game.Screens internal virtual bool AllowRulesetChange => true; - internal virtual bool CanBeatmapChange => true; + internal virtual bool AllowBeatmapChange => true; private readonly Bindable beatmap = new Bindable(); diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 47649372bf..f92d16faf8 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Play internal override bool ShowOverlays => false; - internal override bool CanBeatmapChange => false; + internal override bool AllowBeatmapChange => false; internal override bool HasLocalCursorDisplayed => !pauseContainer.IsPaused && !HasFailed && HitRenderer.ProvidingUserCursor; diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index 8cd45e4b5d..866bccc5fe 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -280,6 +280,6 @@ namespace osu.Game.Screens.Ranking modeChangeButtons.Current.TriggerChange(); } - internal override bool CanBeatmapChange => false; + internal override bool AllowBeatmapChange => false; } } From b9cf0e47ee0a7442a52e8cc53aa2e35d8bbd246c Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 19 Jun 2017 18:12:26 +0200 Subject: [PATCH 10/72] CI fix --- osu.Game/OsuGameBase.cs | 1 - osu.Game/Overlays/Music/PlaylistOverlay.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 5350cd03ea..306cdaddf0 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -18,7 +18,6 @@ using osu.Game.Graphics; using osu.Game.Graphics.Cursor; using osu.Game.Graphics.Processing; using osu.Game.Online.API; -using osu.Game.Screens; using SQLite.Net; using osu.Framework.Graphics.Performance; diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 53844a02d2..c810b29748 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -16,7 +16,6 @@ using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Graphics; -using osu.Game.Screens; using OpenTK; using OpenTK.Graphics; From b4437329cceb11092ecae9fced3049a4128c53cf Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 19 Jun 2017 18:34:56 +0200 Subject: [PATCH 11/72] Removed redundant variable --- osu.Game/Overlays/MusicController.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 457174a67f..480cf6fc74 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -53,17 +53,14 @@ namespace osu.Game.Overlays private Container dragContainer; private Container playerContainer; - private bool allowBeatmapChange = true; - public bool AllowBeatmapChange { get { - return allowBeatmapChange; + return playlist.AllowBeatmapChange; } set { - allowBeatmapChange = value; playlist.AllowBeatmapChange = value; } } From 1b95991e40a0ad60e2b824905690e91dfa50ed5d Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 19 Jun 2017 19:05:09 +0200 Subject: [PATCH 12/72] Extended condition --- osu.Game/Overlays/MusicController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 480cf6fc74..f0d79534af 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -238,7 +238,7 @@ namespace osu.Game.Overlays progressBar.UpdatePosition(track.Length == 0 ? 0 : (float)(track.CurrentTime / track.Length)); playButton.Icon = track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o; - if (track.HasCompleted && !track.Looping) next(); + if (track.HasCompleted && !track.Looping && AllowBeatmapChange) next(); } else playButton.Icon = FontAwesome.fa_play_circle_o; From 03c13620c84acd339b9f52dcc43b38e281a1d392 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Tue, 20 Jun 2017 02:12:05 +0200 Subject: [PATCH 13/72] Filter the playlist overlay's beatmap list --- osu.Game/Overlays/Music/PlaylistOverlay.cs | 36 +++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index c810b29748..0825e936ee 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -35,7 +35,41 @@ namespace osu.Game.Overlays.Music private readonly Bindable beatmapBacking = new Bindable(); - public bool AllowBeatmapChange = true; + private bool allowBeatmapChange = true; + + public bool AllowBeatmapChange + { + get + { + return allowBeatmapChange; + } + set + { + if (!IsLoaded || allowBeatmapChange == value) return; + + allowBeatmapChange = value; + + // Get the new list of available beatmap sets + if (allowBeatmapChange) + list.BeatmapSets = BeatmapSets; + else if (beatmapBacking.Value != null) + { + list.BeatmapSets = new List() + { + beatmapBacking.Value.BeatmapSetInfo + }; + } + else + list.BeatmapSets = new List(); + + // Apply the current filter + list.Filter(filter.Search.Text); + + // Select the current beatmap + if (beatmapBacking.Value != null) + list.SelectedItem = beatmapBacking.Value.BeatmapSetInfo; + } + } public IEnumerable BeatmapSets; private InputManager inputManager; From 354f5167790bf8e6cf0c65cf158b4895350ecac7 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Tue, 20 Jun 2017 15:19:59 +0200 Subject: [PATCH 14/72] Moved load condition and simplify list selection --- osu.Game/Overlays/Music/PlaylistOverlay.cs | 5 ++--- osu.Game/Overlays/MusicController.cs | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 0825e936ee..1a8f8fcb06 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Music } set { - if (!IsLoaded || allowBeatmapChange == value) return; + if (allowBeatmapChange == value) return; allowBeatmapChange = value; @@ -66,8 +66,7 @@ namespace osu.Game.Overlays.Music list.Filter(filter.Search.Text); // Select the current beatmap - if (beatmapBacking.Value != null) - list.SelectedItem = beatmapBacking.Value.BeatmapSetInfo; + list.SelectedItem = beatmapBacking.Value?.BeatmapSetInfo; } } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index f0d79534af..12b6768319 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -61,7 +61,8 @@ namespace osu.Game.Overlays } set { - playlist.AllowBeatmapChange = value; + if(IsLoaded) + playlist.AllowBeatmapChange = value; } } From edd7fd585c8d4d445e69c33797d64a6303d679ff Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Wed, 21 Jun 2017 00:51:32 +0200 Subject: [PATCH 15/72] Disable beatmap changing buttons when entering a screen that disallows changing the beatmap --- osu.Game/Graphics/UserInterface/IconButton.cs | 47 ++++++++++++++++++- osu.Game/Overlays/Music/PlaylistOverlay.cs | 41 ---------------- osu.Game/Overlays/MusicController.cs | 40 +++++++++++++--- 3 files changed, 80 insertions(+), 48 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 7cacd09618..8d7f223624 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -33,6 +33,39 @@ namespace osu.Game.Graphics.UserInterface set { icon.Scale = value; } } + private Color4 disabledColour; + + public override bool Enabled + { + get + { + return base.Enabled; + } + + set + { + if (base.Enabled == value) return; + + base.Enabled = value; + + if (!value) + { + FadeColour(disabledColour, 200, EasingTypes.OutQuint); + content.ScaleTo(1, 200, EasingTypes.OutElastic); + + if (Hovering) + hover.FadeOut(200, EasingTypes.OutQuint); + } + else + { + FadeColour(Color4.White, 200, EasingTypes.OutQuint); + + if(Hovering) + hover.FadeIn(500, EasingTypes.OutQuint); + } + } + } + public IconButton() { AutoSizeAxes = Axes.Both; @@ -79,34 +112,46 @@ namespace osu.Game.Graphics.UserInterface { hover.Colour = colours.Yellow.Opacity(0.6f); flashColour = colours.Yellow; + disabledColour = colours.Gray9; } protected override bool OnHover(InputState state) { + if (!Enabled) + return true; + hover.FadeIn(500, EasingTypes.OutQuint); return base.OnHover(state); } protected override void OnHoverLost(InputState state) { + if (!Enabled) + return; + hover.FadeOut(500, EasingTypes.OutQuint); base.OnHoverLost(state); } protected override bool OnClick(InputState state) { - hover.FlashColour(flashColour, 800, EasingTypes.OutQuint); return base.OnClick(state); } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { + if (!Enabled) + return true; + content.ScaleTo(0.75f, 2000, EasingTypes.OutQuint); return base.OnMouseDown(state, args); } protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { + if (!Enabled) + return true; + content.ScaleTo(1, 1000, EasingTypes.OutElastic); return base.OnMouseUp(state, args); } diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 1a8f8fcb06..580b53a34a 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -35,41 +35,6 @@ namespace osu.Game.Overlays.Music private readonly Bindable beatmapBacking = new Bindable(); - private bool allowBeatmapChange = true; - - public bool AllowBeatmapChange - { - get - { - return allowBeatmapChange; - } - set - { - if (allowBeatmapChange == value) return; - - allowBeatmapChange = value; - - // Get the new list of available beatmap sets - if (allowBeatmapChange) - list.BeatmapSets = BeatmapSets; - else if (beatmapBacking.Value != null) - { - list.BeatmapSets = new List() - { - beatmapBacking.Value.BeatmapSetInfo - }; - } - else - list.BeatmapSets = new List(); - - // Apply the current filter - list.Filter(filter.Search.Text); - - // Select the current beatmap - list.SelectedItem = beatmapBacking.Value?.BeatmapSetInfo; - } - } - public IEnumerable BeatmapSets; private InputManager inputManager; @@ -187,12 +152,6 @@ namespace osu.Game.Overlays.Music private void playSpecified(BeatmapInfo info) { - if (!AllowBeatmapChange) - { - beatmapBacking.Value?.Track?.Seek(0); - return; - } - beatmapBacking.Value = beatmaps.GetWorkingBeatmap(info, beatmapBacking); Task.Run(() => diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 12b6768319..e7cd4ce2ba 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -39,9 +39,13 @@ namespace osu.Game.Overlays private Drawable currentBackground; private DragBar progressBar; + private IconButton prevButton; private IconButton playButton; + private IconButton nextButton; private IconButton playlistButton; + private Color4 colorYellow; + private SpriteText title, artist; private PlaylistOverlay playlist; @@ -53,16 +57,36 @@ namespace osu.Game.Overlays private Container dragContainer; private Container playerContainer; + private bool showPlaylistOnceAvailable; + + private bool allowBeatmapChange = true; + public bool AllowBeatmapChange { get { - return playlist.AllowBeatmapChange; + return allowBeatmapChange; } set { - if(IsLoaded) - playlist.AllowBeatmapChange = value; + if (allowBeatmapChange == value) return; + + allowBeatmapChange = value; + + // Toggle the playlist's visibility if required + if (!allowBeatmapChange) + { + showPlaylistOnceAvailable = playlist.State == Visibility.Visible; + + if (showPlaylistOnceAvailable) + playlist?.Hide(); + } + else if (showPlaylistOnceAvailable) + playlist?.Show(); + + prevButton.Enabled = allowBeatmapChange; + nextButton.Enabled = allowBeatmapChange; + playlistButton.Enabled = allowBeatmapChange; } } @@ -166,7 +190,7 @@ namespace osu.Game.Overlays Anchor = Anchor.Centre, Children = new[] { - new IconButton + prevButton = new IconButton { Action = prev, Icon = FontAwesome.fa_step_backward, @@ -178,7 +202,7 @@ namespace osu.Game.Overlays Action = play, Icon = FontAwesome.fa_play_circle_o, }, - new IconButton + nextButton = new IconButton { Action = next, Icon = FontAwesome.fa_step_forward, @@ -211,7 +235,9 @@ namespace osu.Game.Overlays beatmapBacking.BindTo(game.Beatmap); - playlist.StateChanged += (c, s) => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, EasingTypes.OutQuint); + colorYellow = colours.Yellow; + + playlist.StateChanged += (c, s) => playlistButton.FadeColour(s == Visibility.Visible ? colorYellow : Color4.White, 200, EasingTypes.OutQuint); } protected override void LoadComplete() @@ -384,6 +410,8 @@ namespace osu.Game.Overlays FadeOut(transition_length, EasingTypes.OutQuint); dragContainer.ScaleTo(0.9f, transition_length, EasingTypes.OutQuint); + + showPlaylistOnceAvailable = false; } private enum TransformDirection From 70096b6c8668869351bebadb29fb0f20121f9d1c Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Wed, 21 Jun 2017 01:28:43 +0200 Subject: [PATCH 16/72] Bug fixes --- osu.Game/Overlays/MusicController.cs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index e7cd4ce2ba..ed7f357855 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -73,6 +73,10 @@ namespace osu.Game.Overlays allowBeatmapChange = value; + prevButton.Enabled = allowBeatmapChange; + nextButton.Enabled = allowBeatmapChange; + playlistButton.Enabled = allowBeatmapChange; + // Toggle the playlist's visibility if required if (!allowBeatmapChange) { @@ -81,12 +85,8 @@ namespace osu.Game.Overlays if (showPlaylistOnceAvailable) playlist?.Hide(); } - else if (showPlaylistOnceAvailable) + else if (showPlaylistOnceAvailable && State == Visibility.Visible) playlist?.Show(); - - prevButton.Enabled = allowBeatmapChange; - nextButton.Enabled = allowBeatmapChange; - playlistButton.Enabled = allowBeatmapChange; } } @@ -237,7 +237,11 @@ namespace osu.Game.Overlays colorYellow = colours.Yellow; - playlist.StateChanged += (c, s) => playlistButton.FadeColour(s == Visibility.Visible ? colorYellow : Color4.White, 200, EasingTypes.OutQuint); + playlist.StateChanged += (c, s) => + { + if (playlistButton.Enabled) + playlistButton.FadeColour(s == Visibility.Visible ? colorYellow : Color4.White, 200, EasingTypes.OutQuint); + }; } protected override void LoadComplete() @@ -402,6 +406,9 @@ namespace osu.Game.Overlays FadeIn(transition_length, EasingTypes.OutQuint); dragContainer.ScaleTo(1, transition_length, EasingTypes.OutElastic); + + if(Alpha == 0) + showPlaylistOnceAvailable = false; } protected override void PopOut() @@ -410,8 +417,6 @@ namespace osu.Game.Overlays FadeOut(transition_length, EasingTypes.OutQuint); dragContainer.ScaleTo(0.9f, transition_length, EasingTypes.OutQuint); - - showPlaylistOnceAvailable = false; } private enum TransformDirection From 2db0466722949ca98693eccd46bf80ad149816a0 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Wed, 21 Jun 2017 02:47:11 +0200 Subject: [PATCH 17/72] Readded color flash and simplify logic --- osu.Game/Graphics/UserInterface/IconButton.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 8d7f223624..c6fb3d1896 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -54,14 +54,14 @@ namespace osu.Game.Graphics.UserInterface content.ScaleTo(1, 200, EasingTypes.OutElastic); if (Hovering) - hover.FadeOut(200, EasingTypes.OutQuint); + OnHoverLost(new InputState()); } else { FadeColour(Color4.White, 200, EasingTypes.OutQuint); - if(Hovering) - hover.FadeIn(500, EasingTypes.OutQuint); + if (Hovering) + OnHover(new InputState()); } } } @@ -135,6 +135,7 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnClick(InputState state) { + hover.FlashColour(flashColour, 800, EasingTypes.OutQuint); return base.OnClick(state); } From 7a9d430a28686e643fce5017f572f95a1b188055 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Wed, 21 Jun 2017 12:17:59 +0200 Subject: [PATCH 18/72] Applied suggested changes --- osu.Game/Graphics/UserInterface/IconButton.cs | 73 ++++++++++--------- osu.Game/OsuGame.cs | 2 +- osu.Game/Overlays/MusicController.cs | 59 +++++++-------- 3 files changed, 65 insertions(+), 69 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index c6fb3d1896..a409f954f6 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Input; +using osu.Framework.Graphics.Transforms; namespace osu.Game.Graphics.UserInterface { @@ -35,37 +36,6 @@ namespace osu.Game.Graphics.UserInterface private Color4 disabledColour; - public override bool Enabled - { - get - { - return base.Enabled; - } - - set - { - if (base.Enabled == value) return; - - base.Enabled = value; - - if (!value) - { - FadeColour(disabledColour, 200, EasingTypes.OutQuint); - content.ScaleTo(1, 200, EasingTypes.OutElastic); - - if (Hovering) - OnHoverLost(new InputState()); - } - else - { - FadeColour(Color4.White, 200, EasingTypes.OutQuint); - - if (Hovering) - OnHover(new InputState()); - } - } - } - public IconButton() { AutoSizeAxes = Axes.Both; @@ -113,11 +83,44 @@ namespace osu.Game.Graphics.UserInterface hover.Colour = colours.Yellow.Opacity(0.6f); flashColour = colours.Yellow; disabledColour = colours.Gray9; + + Enabled.ValueChanged += enabledChanged; + } + + private void enabledChanged(bool newEnabled) + { + if (newEnabled) + { + // Only fade the colour to white if there is no colour transformation pending + bool colorTransformation = false; + foreach (ITransform t in Transforms) + { + if (t is TransformColour) + { + colorTransformation = true; + break; + } + } + + if(!colorTransformation) + FadeColour(Color4.White, 200, EasingTypes.OutQuint); + + if (Hovering) + OnHover(new InputState()); + } + else + { + FadeColour(disabledColour, 200, EasingTypes.OutQuint); + content.ScaleTo(1, 200, EasingTypes.OutElastic); + + if (Hovering) + OnHoverLost(new InputState()); + } } protected override bool OnHover(InputState state) { - if (!Enabled) + if (!Enabled.Value) return true; hover.FadeIn(500, EasingTypes.OutQuint); @@ -126,7 +129,7 @@ namespace osu.Game.Graphics.UserInterface protected override void OnHoverLost(InputState state) { - if (!Enabled) + if (!Enabled.Value) return; hover.FadeOut(500, EasingTypes.OutQuint); @@ -141,7 +144,7 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { - if (!Enabled) + if (!Enabled.Value) return true; content.ScaleTo(0.75f, 2000, EasingTypes.OutQuint); @@ -150,7 +153,7 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { - if (!Enabled) + if (!Enabled.Value) return true; content.ScaleTo(1, 1000, EasingTypes.OutElastic); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 6a80840e93..4a1e54152c 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -328,7 +328,7 @@ namespace osu.Game ScreenChanged?.Invoke(newScreen); - musicController.AllowBeatmapChange = currentScreen.AllowBeatmapChange; + Beatmap.Disabled = !currentScreen.AllowBeatmapChange; } protected override bool OnExiting() diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index ed7f357855..c84201a7b7 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -59,36 +59,7 @@ namespace osu.Game.Overlays private bool showPlaylistOnceAvailable; - private bool allowBeatmapChange = true; - - public bool AllowBeatmapChange - { - get - { - return allowBeatmapChange; - } - set - { - if (allowBeatmapChange == value) return; - - allowBeatmapChange = value; - - prevButton.Enabled = allowBeatmapChange; - nextButton.Enabled = allowBeatmapChange; - playlistButton.Enabled = allowBeatmapChange; - - // Toggle the playlist's visibility if required - if (!allowBeatmapChange) - { - showPlaylistOnceAvailable = playlist.State == Visibility.Visible; - - if (showPlaylistOnceAvailable) - playlist?.Hide(); - } - else if (showPlaylistOnceAvailable && State == Visibility.Visible) - playlist?.Show(); - } - } + private bool AllowBeatmapChange => !beatmapBacking.Disabled; public MusicController() { @@ -239,7 +210,7 @@ namespace osu.Game.Overlays playlist.StateChanged += (c, s) => { - if (playlistButton.Enabled) + if (AllowBeatmapChange) playlistButton.FadeColour(s == Visibility.Visible ? colorYellow : Color4.White, 200, EasingTypes.OutQuint); }; } @@ -249,9 +220,30 @@ namespace osu.Game.Overlays beatmapBacking.ValueChanged += beatmapChanged; beatmapBacking.TriggerChange(); + beatmapBacking.DisabledChanged += beatmapDisabledChanged; + beatmapDisabledChanged(beatmapBacking.Disabled); + base.LoadComplete(); } + private void beatmapDisabledChanged(bool newBeatmapDisabled) + { + prevButton.Enabled.Value = !newBeatmapDisabled; + nextButton.Enabled.Value = !newBeatmapDisabled; + playlistButton.Enabled.Value = !newBeatmapDisabled; + + // Toggle the playlist's visibility if required + if (newBeatmapDisabled) + { + showPlaylistOnceAvailable = playlist.State == Visibility.Visible; + + if (showPlaylistOnceAvailable) + playlist?.Hide(); + } + else if (showPlaylistOnceAvailable && State == Visibility.Visible) + playlist?.Show(); + } + protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); @@ -281,7 +273,8 @@ namespace osu.Game.Overlays if (track == null) { - playlist.PlayNext(); + if (AllowBeatmapChange) + playlist.PlayNext(); return; } @@ -407,7 +400,7 @@ namespace osu.Game.Overlays FadeIn(transition_length, EasingTypes.OutQuint); dragContainer.ScaleTo(1, transition_length, EasingTypes.OutElastic); - if(Alpha == 0) + if (Alpha == 0) showPlaylistOnceAvailable = false; } From 67292a5dcf09fc8e6d4236f99820621f4dec8589 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Wed, 21 Jun 2017 12:27:45 +0200 Subject: [PATCH 19/72] Brought ITransform in line with framework changes --- osu.Game/Graphics/UserInterface/IconButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 561581c341..faabfb3e74 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -93,7 +93,7 @@ namespace osu.Game.Graphics.UserInterface { // Only fade the colour to white if there is no colour transformation pending bool colorTransformation = false; - foreach (ITransform t in Transforms) + foreach (ITransform t in Transforms) { if (t is TransformColour) { From 8b07565025ff2343f511108d7b01c8e73deceb46 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Wed, 21 Jun 2017 16:33:26 +0200 Subject: [PATCH 20/72] Added test case usability, namings and bug fixes --- .../Tests/TestCaseMusicController.cs | 19 ++++++++++++++--- osu.Game/Graphics/UserInterface/IconButton.cs | 21 ++++--------------- osu.Game/Overlays/MusicController.cs | 14 ++++++------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs b/osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs index 5665bf859a..282f5207c0 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs @@ -1,11 +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.Testing; +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Timing; -using osu.Game.Overlays; using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; +using osu.Framework.Timing; +using osu.Game; +using osu.Game.Beatmaps; +using osu.Game.Overlays; namespace osu.Desktop.VisualTests.Tests { @@ -15,11 +19,19 @@ namespace osu.Desktop.VisualTests.Tests private MusicController mc; + private readonly Bindable beatmapBacking = new Bindable(); + public TestCaseMusicController() { Clock = new FramedClock(); } + [BackgroundDependencyLoader] + private void load(OsuGameBase game) + { + beatmapBacking.BindTo(game.Beatmap); + } + public override void Reset() { base.Reset(); @@ -33,6 +45,7 @@ namespace osu.Desktop.VisualTests.Tests AddToggleStep(@"toggle visibility", state => mc.State = state ? Visibility.Visible : Visibility.Hidden); AddStep(@"show", () => mc.State = Visibility.Visible); + AddToggleStep(@"toggle beatmap lock", state => beatmapBacking.Disabled = state); } } } diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index faabfb3e74..6b35aeac80 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input; -using osu.Framework.Graphics.Transforms; namespace osu.Game.Graphics.UserInterface { @@ -34,7 +33,7 @@ namespace osu.Game.Graphics.UserInterface set { icon.Scale = value; } } - private Color4 disabledColour; + private Color4 disableColour; public IconButton() { @@ -82,7 +81,7 @@ namespace osu.Game.Graphics.UserInterface { hover.Colour = colours.Yellow.Opacity(0.6f); flashColour = colours.Yellow; - disabledColour = colours.Gray9; + disableColour = colours.Gray9; Enabled.ValueChanged += enabledChanged; } @@ -91,26 +90,14 @@ namespace osu.Game.Graphics.UserInterface { if (newEnabled) { - // Only fade the colour to white if there is no colour transformation pending - bool colorTransformation = false; - foreach (ITransform t in Transforms) - { - if (t is TransformColour) - { - colorTransformation = true; - break; - } - } - - if(!colorTransformation) - FadeColour(Color4.White, 200, EasingTypes.OutQuint); + FadeColour(Color4.White, 200, EasingTypes.OutQuint); if (Hovering) OnHover(new InputState()); } else { - FadeColour(disabledColour, 200, EasingTypes.OutQuint); + FadeColour(disableColour, 200, EasingTypes.OutQuint); content.ScaleTo(1, 200, EasingTypes.OutElastic); if (Hovering) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 53a8204534..8ab17d8785 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -45,7 +45,7 @@ namespace osu.Game.Overlays private IconButton nextButton; private IconButton playlistButton; - private Color4 colorYellow; + private Color4 playlistButtonColor; private SpriteText title, artist; @@ -60,8 +60,6 @@ namespace osu.Game.Overlays private bool showPlaylistOnceAvailable; - private bool AllowBeatmapChange => !beatmapBacking.Disabled; - public MusicController() { Width = 400; @@ -207,12 +205,12 @@ namespace osu.Game.Overlays beatmapBacking.BindTo(game.Beatmap); - colorYellow = colours.Yellow; + playlistButtonColor = colours.Yellow; playlist.StateChanged += (c, s) => { - if (AllowBeatmapChange) - playlistButton.FadeColour(s == Visibility.Visible ? colorYellow : Color4.White, 200, EasingTypes.OutQuint); + if (!beatmapBacking.Disabled) + playlistButton.FadeColour(s == Visibility.Visible ? playlistButtonColor : Color4.White, 200, EasingTypes.OutQuint); }; } @@ -262,7 +260,7 @@ namespace osu.Game.Overlays progressBar.UpdatePosition(track.Length == 0 ? 0 : (float)(track.CurrentTime / track.Length)); playButton.Icon = track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o; - if (track.HasCompleted && !track.Looping && AllowBeatmapChange) next(); + if (track.HasCompleted && !track.Looping && !beatmapBacking.Disabled) next(); } else playButton.Icon = FontAwesome.fa_play_circle_o; @@ -274,7 +272,7 @@ namespace osu.Game.Overlays if (track == null) { - if (AllowBeatmapChange) + if (!beatmapBacking.Disabled) playlist.PlayNext(); return; } From 3b2df5fa0f9e84331fe03bcad96bd4f126b80158 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Wed, 21 Jun 2017 16:46:30 +0200 Subject: [PATCH 21/72] Renaming and smaller optimizations --- osu.Game/Overlays/MusicController.cs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 8ab17d8785..b35918c79f 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -209,7 +209,7 @@ namespace osu.Game.Overlays playlist.StateChanged += (c, s) => { - if (!beatmapBacking.Disabled) + if (playlistButton.Enabled) playlistButton.FadeColour(s == Visibility.Visible ? playlistButtonColor : Color4.White, 200, EasingTypes.OutQuint); }; } @@ -217,30 +217,28 @@ namespace osu.Game.Overlays protected override void LoadComplete() { beatmapBacking.ValueChanged += beatmapChanged; - beatmapBacking.TriggerChange(); - beatmapBacking.DisabledChanged += beatmapDisabledChanged; - beatmapDisabledChanged(beatmapBacking.Disabled); + beatmapBacking.TriggerChange(); base.LoadComplete(); } - private void beatmapDisabledChanged(bool newBeatmapDisabled) + private void beatmapDisabledChanged(bool newBeatmapBackingDisabled) { - prevButton.Enabled.Value = !newBeatmapDisabled; - nextButton.Enabled.Value = !newBeatmapDisabled; - playlistButton.Enabled.Value = !newBeatmapDisabled; + prevButton.Enabled.Value = !newBeatmapBackingDisabled; + nextButton.Enabled.Value = !newBeatmapBackingDisabled; + playlistButton.Enabled.Value = !newBeatmapBackingDisabled; // Toggle the playlist's visibility if required - if (newBeatmapDisabled) + if (newBeatmapBackingDisabled) { showPlaylistOnceAvailable = playlist.State == Visibility.Visible; if (showPlaylistOnceAvailable) - playlist?.Hide(); + playlist.Hide(); } else if (showPlaylistOnceAvailable && State == Visibility.Visible) - playlist?.Show(); + playlist.Show(); } protected override void UpdateAfterChildren() From 0e1b49dff93e57bff21c923d94b66251a1b3ff4a Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sun, 25 Jun 2017 20:56:22 +0200 Subject: [PATCH 22/72] Applied suggested changes --- osu.Game/Overlays/MusicController.cs | 10 +++++----- osu.Game/Screens/Ranking/Results.cs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index b35918c79f..90253f40a3 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -223,14 +223,14 @@ namespace osu.Game.Overlays base.LoadComplete(); } - private void beatmapDisabledChanged(bool newBeatmapBackingDisabled) + private void beatmapDisabledChanged(bool disabled) { - prevButton.Enabled.Value = !newBeatmapBackingDisabled; - nextButton.Enabled.Value = !newBeatmapBackingDisabled; - playlistButton.Enabled.Value = !newBeatmapBackingDisabled; + prevButton.Enabled.Value = !disabled; + nextButton.Enabled.Value = !disabled; + playlistButton.Enabled.Value = !disabled; // Toggle the playlist's visibility if required - if (newBeatmapBackingDisabled) + if (disabled) { showPlaylistOnceAvailable = playlist.State == Visibility.Visible; diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index 8bbe8a25c6..d82927f3b4 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -33,6 +33,8 @@ namespace osu.Game.Screens.Ranking internal override bool AllowRulesetChange => false; + internal override bool AllowBeatmapChange => false; + private Container currentPage; private static readonly Vector2 background_blur = new Vector2(20); @@ -280,7 +282,5 @@ namespace osu.Game.Screens.Ranking modeChangeButtons.Current.TriggerChange(); } - - internal override bool AllowBeatmapChange => false; } } From c053733ea942ca927375f0402437ae343f731633 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 14 Jul 2017 12:09:55 +0200 Subject: [PATCH 23/72] Updated to use ppy's implementation --- osu.Game/Graphics/UserInterface/IconButton.cs | 4 ++-- osu.Game/OsuGame.cs | 2 -- osu.Game/Overlays/MusicController.cs | 7 ++----- osu.Game/Screens/OsuScreen.cs | 2 -- osu.Game/Screens/Play/Player.cs | 2 -- osu.Game/Screens/Ranking/Results.cs | 2 -- 6 files changed, 4 insertions(+), 15 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 842c2d88dc..89be0316b2 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -93,7 +93,7 @@ namespace osu.Game.Graphics.UserInterface { FadeColour(Color4.White, 200, EasingTypes.OutQuint); - if (Hovering) + if (IsHovered) OnHover(new InputState()); } else @@ -101,7 +101,7 @@ namespace osu.Game.Graphics.UserInterface FadeColour(disableColour, 200, EasingTypes.OutQuint); content.ScaleTo(1, 200, EasingTypes.OutElastic); - if (Hovering) + if (IsHovered) OnHoverLost(new InputState()); } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 576c55fd0e..843861c0da 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -329,8 +329,6 @@ namespace osu.Game } ScreenChanged?.Invoke(newScreen); - - Beatmap.Disabled = !currentScreen.AllowBeatmapChange; } protected override bool OnExiting() diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index e9fa9af038..81b1fef52e 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -262,7 +262,8 @@ namespace osu.Game.Overlays progressBar.UpdatePosition(track.Length == 0 ? 0 : (float)(track.CurrentTime / track.Length)); playButton.Icon = track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o; - if (track.HasCompleted && !track.Looping && !beatmapBacking.Disabled) next(); + if (track.HasCompleted && !track.Looping && !beatmapBacking.Disabled) + next(); } else playButton.Icon = FontAwesome.fa_play_circle_o; @@ -287,16 +288,12 @@ namespace osu.Game.Overlays private void prev() { - if (beatmapBacking.Disabled) return; - queuedDirection = TransformDirection.Prev; playlist.PlayPrevious(); } private void next() { - if (beatmapBacking.Disabled) return; - queuedDirection = TransformDirection.Next; playlist.PlayNext(); } diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index e7cc84891a..64223db100 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -35,8 +35,6 @@ namespace osu.Game.Screens /// internal virtual bool AllowBeatmapRulesetChange => true; - internal virtual bool AllowBeatmapChange => true; - private readonly Bindable beatmap = new Bindable(); private readonly Bindable ruleset = new Bindable(); diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index e27631f6b8..c9ca91faa0 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -33,8 +33,6 @@ namespace osu.Game.Screens.Play internal override bool ShowOverlays => false; - internal override bool AllowBeatmapChange => false; - internal override bool HasLocalCursorDisplayed => !pauseContainer.IsPaused && !HasFailed && HitRenderer.ProvidingUserCursor; public BeatmapInfo BeatmapInfo; diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index 92732310f3..636851e14d 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -33,8 +33,6 @@ namespace osu.Game.Screens.Ranking internal override bool AllowBeatmapRulesetChange => false; - internal override bool AllowBeatmapChange => false; - private Container currentPage; private static readonly Vector2 background_blur = new Vector2(20); From 00a622da1a2462245aad37a9ededc1a55413a607 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 14 Jul 2017 12:31:12 +0200 Subject: [PATCH 24/72] Let disabled icon buttons be interactive again --- osu.Game/Graphics/UserInterface/IconButton.cs | 33 +------------------ 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 89be0316b2..124406d7bb 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -84,42 +84,17 @@ namespace osu.Game.Graphics.UserInterface flashColour = colours.Yellow; disableColour = colours.Gray9; - Enabled.ValueChanged += enabledChanged; - } - - private void enabledChanged(bool newEnabled) - { - if (newEnabled) - { - FadeColour(Color4.White, 200, EasingTypes.OutQuint); - - if (IsHovered) - OnHover(new InputState()); - } - else - { - FadeColour(disableColour, 200, EasingTypes.OutQuint); - content.ScaleTo(1, 200, EasingTypes.OutElastic); - - if (IsHovered) - OnHoverLost(new InputState()); - } + Enabled.ValueChanged += newEnabled => FadeColour(newEnabled ? Color4.White : disableColour, 200, EasingTypes.OutQuint); } protected override bool OnHover(InputState state) { - if (!Enabled.Value) - return true; - hover.FadeIn(500, EasingTypes.OutQuint); return base.OnHover(state); } protected override void OnHoverLost(InputState state) { - if (!Enabled.Value) - return; - hover.FadeOut(500, EasingTypes.OutQuint); base.OnHoverLost(state); } @@ -132,18 +107,12 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { - if (!Enabled.Value) - return true; - content.ScaleTo(0.75f, 2000, EasingTypes.OutQuint); return base.OnMouseDown(state, args); } protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { - if (!Enabled.Value) - return true; - content.ScaleTo(1, 1000, EasingTypes.OutElastic); return base.OnMouseUp(state, args); } From a95339dc1dd76d63fd87a642708aa22ec81bf5a2 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 14 Jul 2017 12:37:56 +0200 Subject: [PATCH 25/72] Removed the reopening of the playlist overlay --- osu.Game/Overlays/MusicController.cs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 81b1fef52e..8845f11d86 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -59,8 +59,6 @@ namespace osu.Game.Overlays private Container dragContainer; private Container playerContainer; - private bool showPlaylistOnceAvailable; - public MusicController() { Width = 400; @@ -233,16 +231,8 @@ namespace osu.Game.Overlays nextButton.Enabled.Value = !disabled; playlistButton.Enabled.Value = !disabled; - // Toggle the playlist's visibility if required if (disabled) - { - showPlaylistOnceAvailable = playlist.State == Visibility.Visible; - - if (showPlaylistOnceAvailable) - playlist.Hide(); - } - else if (showPlaylistOnceAvailable && State == Visibility.Visible) - playlist.Show(); + playlist.Hide(); } protected override void UpdateAfterChildren() @@ -401,9 +391,6 @@ namespace osu.Game.Overlays FadeIn(transition_length, EasingTypes.OutQuint); dragContainer.ScaleTo(1, transition_length, EasingTypes.OutElastic); - - if (Alpha == 0) - showPlaylistOnceAvailable = false; } protected override void PopOut() From d2c18026f256638522183fe8a40509ec61445178 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 14 Jul 2017 12:45:24 +0200 Subject: [PATCH 26/72] Removed unnecessary variables --- osu.Game/Graphics/UserInterface/IconButton.cs | 5 +---- osu.Game/Overlays/MusicController.cs | 14 ++++---------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 124406d7bb..a9210c69fb 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -34,8 +34,6 @@ namespace osu.Game.Graphics.UserInterface set { icon.Scale = value; } } - private Color4 disableColour; - public IconButton() { AutoSizeAxes = Axes.Both; @@ -82,9 +80,8 @@ namespace osu.Game.Graphics.UserInterface { hover.Colour = colours.Yellow.Opacity(0.6f); flashColour = colours.Yellow; - disableColour = colours.Gray9; - Enabled.ValueChanged += newEnabled => FadeColour(newEnabled ? Color4.White : disableColour, 200, EasingTypes.OutQuint); + Enabled.ValueChanged += newEnabled => FadeColour(newEnabled ? Color4.White : colours.Gray9, 200, EasingTypes.OutQuint); } protected override bool OnHover(InputState state) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 8845f11d86..a5be07401d 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -207,13 +207,7 @@ namespace osu.Game.Overlays beatmapBacking.BindTo(game.Beatmap); - playlistButtonColor = colours.Yellow; - - playlist.StateChanged += (c, s) => - { - if (playlistButton.Enabled) - playlistButton.FadeColour(s == Visibility.Visible ? playlistButtonColor : Color4.White, 200, EasingTypes.OutQuint); - }; + playlist.StateChanged += (c, s) => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, EasingTypes.OutQuint); } protected override void LoadComplete() @@ -227,12 +221,12 @@ namespace osu.Game.Overlays private void beatmapDisabledChanged(bool disabled) { + if (disabled) + playlist.Hide(); + prevButton.Enabled.Value = !disabled; nextButton.Enabled.Value = !disabled; playlistButton.Enabled.Value = !disabled; - - if (disabled) - playlist.Hide(); } protected override void UpdateAfterChildren() From c0fd4a765e9af6877f64bd4656ecdaec85e92828 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 14 Jul 2017 12:46:07 +0200 Subject: [PATCH 27/72] Removed unused variable --- osu.Game/Overlays/MusicController.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index a5be07401d..36ecbe4560 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -46,8 +46,6 @@ namespace osu.Game.Overlays private IconButton nextButton; private IconButton playlistButton; - private Color4 playlistButtonColor; - private SpriteText title, artist; private PlaylistOverlay playlist; From b01a6d46c9093a5b9b2eb5244dba95bd9a2eb74e Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 14 Jul 2017 12:54:37 +0200 Subject: [PATCH 28/72] Added beatmap lock functionallity to the music controller's test case --- .../Tests/TestCaseMusicController.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs b/osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs index cbb2775234..346c826d5e 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs @@ -4,7 +4,11 @@ using osu.Framework.Testing; using osu.Framework.Graphics; using osu.Framework.Timing; +using osu.Game; +using osu.Game.Beatmaps; using osu.Game.Overlays; +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics.Containers; namespace osu.Desktop.VisualTests.Tests @@ -13,6 +17,8 @@ namespace osu.Desktop.VisualTests.Tests { public override string Description => @"Tests music controller ui."; + private readonly Bindable beatmapBacking = new Bindable(); + public TestCaseMusicController() { Clock = new FramedClock(); @@ -26,6 +32,13 @@ namespace osu.Desktop.VisualTests.Tests AddToggleStep(@"toggle visibility", state => mc.State = state ? Visibility.Visible : Visibility.Hidden); AddStep(@"show", () => mc.State = Visibility.Visible); + AddToggleStep(@"toggle beatmap lock", state => beatmapBacking.Disabled = state); + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase game) + { + beatmapBacking.BindTo(game.Beatmap); } } } From 9ee59dd63703a7549d651f7b189a24c6fafef5f1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jul 2017 20:38:35 +0900 Subject: [PATCH 29/72] Add the ability to create migrations on a per-store level Now stores store versions to the database itself. --- osu.Game/Beatmaps/BeatmapStore.cs | 33 ++++++++++++++++++++++++ osu.Game/Database/DatabaseBackedStore.cs | 24 +++++++++++++++++ osu.Game/Database/StoreVersion.cs | 15 +++++++++++ osu.Game/OsuGameBase.cs | 3 +++ osu.Game/osu.Game.csproj | 1 + 5 files changed, 76 insertions(+) create mode 100644 osu.Game/Database/StoreVersion.cs diff --git a/osu.Game/Beatmaps/BeatmapStore.cs b/osu.Game/Beatmaps/BeatmapStore.cs index 4a7336535e..f9019537a0 100644 --- a/osu.Game/Beatmaps/BeatmapStore.cs +++ b/osu.Game/Beatmaps/BeatmapStore.cs @@ -17,6 +17,12 @@ namespace osu.Game.Beatmaps public event Action BeatmapSetAdded; public event Action BeatmapSetRemoved; + /// + /// The current version of this store. Used for migrations (see ). + /// The initial version is 1. + /// + protected override int StoreVersion => 1; + public BeatmapStore(SQLiteConnection connection) : base(connection) { @@ -50,6 +56,33 @@ namespace osu.Game.Beatmaps cleanupPendingDeletions(); } + /// + /// Perform migrations between two store versions. + /// + /// The current store version. This will be zero on a fresh database initialisation. + /// The target version which we are migrating to (equal to the current ). + protected override void PerformMigration(int currentVersion, int newVersion) + { + base.PerformMigration(currentVersion, newVersion); + + while (currentVersion++ < newVersion) + { + switch (currentVersion) + { + case 1: + // initialising from a version before we had versioning (or a fresh install). + + // force adding of Protected column (not automatically migrated). + Connection.MigrateTable(); + + // remove all existing beatmaps. + foreach (var b in Connection.GetAllWithChildren(null, true)) + Connection.Delete(b, true); + break; + } + } + } + /// /// Add a to the database. /// diff --git a/osu.Game/Database/DatabaseBackedStore.cs b/osu.Game/Database/DatabaseBackedStore.cs index 8366775483..bb61fc1870 100644 --- a/osu.Game/Database/DatabaseBackedStore.cs +++ b/osu.Game/Database/DatabaseBackedStore.cs @@ -17,6 +17,8 @@ namespace osu.Game.Database protected readonly Storage Storage; protected readonly SQLiteConnection Connection; + protected virtual int StoreVersion => 1; + protected DatabaseBackedStore(SQLiteConnection connection, Storage storage = null) { Storage = storage; @@ -31,6 +33,28 @@ namespace osu.Game.Database Logger.Error(e, $@"Failed to initialise the {GetType()}! Trying again with a clean database..."); Prepare(true); } + + checkMigrations(); + } + + private void checkMigrations() + { + var storeName = GetType().Name; + + var reportedVersion = Connection.Table().FirstOrDefault(s => s.StoreName == storeName) ?? new StoreVersion + { + StoreName = storeName, + Version = 0 + }; + + if (reportedVersion.Version != StoreVersion) + PerformMigration(reportedVersion.Version, reportedVersion.Version = StoreVersion); + + Connection.InsertOrReplace(reportedVersion); + } + + protected virtual void PerformMigration(int currentVersion, int newVersion) + { } /// diff --git a/osu.Game/Database/StoreVersion.cs b/osu.Game/Database/StoreVersion.cs new file mode 100644 index 0000000000..00314875a6 --- /dev/null +++ b/osu.Game/Database/StoreVersion.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 SQLite.Net.Attributes; + +namespace osu.Game.Database +{ + public class StoreVersion + { + [PrimaryKey] + public string StoreName { get; set; } + + public int Version { get; set; } + } +} diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index b507aa2315..0dec4228de 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -18,6 +18,7 @@ using osu.Game.Graphics.Processing; using osu.Game.Online.API; using SQLite.Net; using osu.Framework.Graphics.Performance; +using osu.Game.Database; using osu.Game.IO; using osu.Game.Rulesets; using osu.Game.Rulesets.Scoring; @@ -97,6 +98,8 @@ namespace osu.Game SQLiteConnection connection = Host.Storage.GetDatabase(@"client"); + connection.CreateTable(); + 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)); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f8509314be..5ac76ed00e 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -80,6 +80,7 @@ + From e5306997dd816c4dbb7fff6fb2fa42bf1586d97d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jul 2017 20:50:26 +0900 Subject: [PATCH 30/72] Fix VisualTests --- osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs b/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs index 61e87a6621..51c78ff442 100644 --- a/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs +++ b/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs @@ -6,6 +6,7 @@ using osu.Desktop.VisualTests.Platform; using osu.Framework.Testing; using osu.Framework.MathUtils; using osu.Game.Beatmaps; +using osu.Game.Database; using osu.Game.Rulesets; using osu.Game.Screens.Select; using osu.Game.Screens.Select.Filter; @@ -29,6 +30,7 @@ namespace osu.Desktop.VisualTests.Tests var storage = new TestStorage(@"TestCasePlaySongSelect"); var backingDatabase = storage.GetDatabase(@"client"); + backingDatabase.CreateTable(); rulesets = new RulesetStore(backingDatabase); manager = new BeatmapManager(storage, null, backingDatabase, rulesets); From 7d4218ea6c9c90142b7ac22c418259cac5810658 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jul 2017 12:46:38 +0900 Subject: [PATCH 31/72] Add option to import from osu-stable Also adds an option to delete all beatmaps for testing purposes. --- osu.Game/Beatmaps/BeatmapManager.cs | 16 ++++++ .../Sections/Maintenance/GeneralSettings.cs | 51 +++++++++++++++++++ .../Settings/Sections/MaintenanceSection.cs | 2 + osu.Game/osu.Game.csproj | 1 + 4 files changed, 70 insertions(+) create mode 100644 osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 99117afe35..97031547c0 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -390,5 +390,21 @@ namespace osu.Game.Beatmaps catch { return new TrackVirtual(); } } } + + public void ImportFromStable() + { + + string stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!", "Songs"); + if (!Directory.Exists(stableInstallPath)) + stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".osu", "Songs"); + + if (!Directory.Exists(stableInstallPath)) + { + Logger.Log("Couldn't find an osu!stable installation!", LoggingTarget.Information, LogLevel.Error); + return; + } + + Import(Directory.GetDirectories(stableInstallPath)); + } } } diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs new file mode 100644 index 0000000000..684bfcb39d --- /dev/null +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs @@ -0,0 +1,51 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Threading.Tasks; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Overlays.Settings.Sections.Maintenance +{ + public class GeneralSettings : SettingsSubsection + { + private OsuButton importButton; + private OsuButton deleteButton; + + protected override string Header => "General"; + + [BackgroundDependencyLoader] + private void load(BeatmapManager beatmaps) + { + Children = new Drawable[] + { + importButton = new OsuButton + { + RelativeSizeAxes = Axes.X, + Text = "Import beatmaps from stable", + Action = () => + { + importButton.Enabled.Value = false; + Task.Run(() => beatmaps.ImportFromStable()).ContinueWith(t => Schedule(() => importButton.Enabled.Value = true)); + } + }, + deleteButton = new OsuButton + { + RelativeSizeAxes = Axes.X, + Text = "Delete ALL beatmaps", + Action = () => + { + deleteButton.Enabled.Value = false; + Task.Run(() => + { + foreach (var b in beatmaps.GetAllUsableBeatmapSets()) + beatmaps.Delete(b); + }).ContinueWith(t => Schedule(() => deleteButton.Enabled.Value = true)); + } + }, + }; + } + } +} diff --git a/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs b/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs index 529cec79c1..b42c64d324 100644 --- a/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs +++ b/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs @@ -3,6 +3,7 @@ using osu.Framework.Graphics; using osu.Game.Graphics; +using osu.Game.Overlays.Settings.Sections.Maintenance; using OpenTK; namespace osu.Game.Overlays.Settings.Sections @@ -17,6 +18,7 @@ namespace osu.Game.Overlays.Settings.Sections FlowContent.Spacing = new Vector2(0, 5); Children = new Drawable[] { + new GeneralSettings() }; } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 5ac76ed00e..b3ed0d2b28 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -104,6 +104,7 @@ + From d51ce896f94db37c8cd050bc8624907373c5d600 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jul 2017 12:46:54 +0900 Subject: [PATCH 32/72] Add locking to all BeatmapManager operations --- osu.Game/Beatmaps/BeatmapManager.cs | 60 ++++++++++++++++++----------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 97031547c0..e62fd2fc5d 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -108,9 +108,13 @@ namespace osu.Game.Beatmaps /// The beatmap to be imported. public BeatmapSetInfo Import(ArchiveReader archiveReader) { - BeatmapSetInfo set = importToStorage(archiveReader); - Import(set); - return set; + // let's only allow one concurrent import at a time for now. + lock (this) + { + BeatmapSetInfo set = importToStorage(archiveReader); + Import(set); + return set; + } } /// @@ -132,10 +136,13 @@ namespace osu.Game.Beatmaps /// The beatmap to delete. public void Delete(BeatmapSetInfo beatmapSet) { - if (!beatmaps.Delete(beatmapSet)) return; + lock (this) + { + if (!beatmaps.Delete(beatmapSet)) return; - if (!beatmapSet.Protected) - files.Dereference(beatmapSet.Files); + if (!beatmapSet.Protected) + files.Dereference(beatmapSet.Files); + } } /// @@ -145,9 +152,12 @@ namespace osu.Game.Beatmaps /// The beatmap to restore. public void Undelete(BeatmapSetInfo beatmapSet) { - if (!beatmaps.Undelete(beatmapSet)) return; + lock (this) + { + if (!beatmaps.Undelete(beatmapSet)) return; - files.Reference(beatmapSet.Files); + files.Reference(beatmapSet.Files); + } } /// @@ -158,22 +168,25 @@ namespace osu.Game.Beatmaps /// A instance correlating to the provided . public WorkingBeatmap GetWorkingBeatmap(BeatmapInfo beatmapInfo, WorkingBeatmap previous = null) { - if (beatmapInfo == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo) - return DefaultBeatmap; + lock (this) + { + if (beatmapInfo == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo) + return DefaultBeatmap; - beatmaps.Populate(beatmapInfo); + beatmaps.Populate(beatmapInfo); - if (beatmapInfo.BeatmapSet == null) - throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetInfoID} is not in the local database."); + if (beatmapInfo.BeatmapSet == null) + throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetInfoID} is not in the local database."); - if (beatmapInfo.Metadata == null) - beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata; + if (beatmapInfo.Metadata == null) + beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata; - WorkingBeatmap working = new BeatmapManagerWorkingBeatmap(files.Store, beatmapInfo); + WorkingBeatmap working = new BeatmapManagerWorkingBeatmap(files.Store, beatmapInfo); - previous?.TransferTo(working); + previous?.TransferTo(working); - return working; + return working; + } } /// @@ -325,10 +338,13 @@ namespace osu.Game.Beatmaps /// A list of available . public List GetAllUsableBeatmapSets(bool populate = true) { - if (populate) - return beatmaps.QueryAndPopulate(b => !b.DeletePending).ToList(); - else - return beatmaps.Query(b => !b.DeletePending).ToList(); + lock (this) + { + if (populate) + return beatmaps.QueryAndPopulate(b => !b.DeletePending).ToList(); + else + return beatmaps.Query(b => !b.DeletePending).ToList(); + } } protected class BeatmapManagerWorkingBeatmap : WorkingBeatmap From e448f79154a6d9c33b9f240c65b14051fda0bc59 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jul 2017 12:47:23 +0900 Subject: [PATCH 33/72] Fix deleted beatmaps not correctly being removed from the playlist --- osu.Game/Overlays/Music/PlaylistList.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 88f499f9a6..3dd514edeb 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -80,7 +80,7 @@ namespace osu.Game.Overlays.Music public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet) { - PlaylistItem itemToRemove = items.Children.FirstOrDefault(item => item.BeatmapSetInfo == beatmapSet); + PlaylistItem itemToRemove = items.Children.FirstOrDefault(item => item.BeatmapSetInfo.ID == beatmapSet.ID); if (itemToRemove != null) items.Remove(itemToRemove); } From a55586f2ad26f4a37ac3f5b5a420f73a9dd90282 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jul 2017 13:54:43 +0900 Subject: [PATCH 34/72] FIx potential sequence of execution issues in PlaylistOverlay --- osu.Game/Overlays/Music/PlaylistOverlay.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 31fe755d2b..100b397890 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -77,11 +77,11 @@ namespace osu.Game.Overlays.Music }, }; + beatmaps.BeatmapSetAdded += s => Schedule(() => list.AddBeatmapSet(s)); + beatmaps.BeatmapSetRemoved += s => Schedule(() => list.RemoveBeatmapSet(s)); + list.BeatmapSets = BeatmapSets = beatmaps.GetAllUsableBeatmapSets(); - // todo: these should probably be above the query. - beatmaps.BeatmapSetAdded += s => list.AddBeatmapSet(s); - beatmaps.BeatmapSetRemoved += s => list.RemoveBeatmapSet(s); beatmapBacking.BindTo(game.Beatmap); From e691dd12c527132ca80276336cf86a7b364179c0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jul 2017 14:22:14 +0900 Subject: [PATCH 35/72] Fix potential sequen of execution issues in BeatmapCarousel --- osu.Game/Screens/Select/BeatmapCarousel.cs | 10 ++++++++-- osu.Game/Screens/Select/SongSelect.cs | 7 ++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 743a0a0f63..63992915aa 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -107,6 +107,14 @@ namespace osu.Game.Screens.Select }); } + public void RemoveBeatmap(BeatmapSetInfo beatmapSet) + { + Schedule(delegate + { + removeGroup(groups.Find(b => b.BeatmapSet.ID == beatmapSet.ID)); + }); + } + public void SelectBeatmap(BeatmapInfo beatmap, bool animated = true) { if (beatmap == null) @@ -128,8 +136,6 @@ namespace osu.Game.Screens.Select } } - public void RemoveBeatmap(BeatmapSetInfo info) => removeGroup(groups.Find(b => b.BeatmapSet.ID == info.ID)); - public Action SelectionChanged; public Action StartRequested; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index bbd292870e..d2aec8d919 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -280,7 +280,7 @@ namespace osu.Game.Screens.Select carousel.Filter(criteria, debounce); } - private void onBeatmapSetAdded(BeatmapSetInfo s) => carousel.AddBeatmap(s); + private void onBeatmapSetAdded(BeatmapSetInfo s) => Schedule(() => addBeatmapSet(s)); private void onBeatmapSetRemoved(BeatmapSetInfo s) => Schedule(() => removeBeatmapSet(s)); @@ -375,6 +375,11 @@ namespace osu.Game.Screens.Select } } + private void addBeatmapSet(BeatmapSetInfo beatmapSet) + { + carousel.AddBeatmap(beatmapSet); + } + private void removeBeatmapSet(BeatmapSetInfo beatmapSet) { carousel.RemoveBeatmap(beatmapSet); From 6616721e3721ef37e562c54b84185bedae938712 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jul 2017 14:42:04 +0900 Subject: [PATCH 36/72] Don't block imports and BeatmapStore operations using the same lock --- osu.Game/Beatmaps/BeatmapManager.cs | 43 ++++++++++++++--------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index e62fd2fc5d..16a1268e88 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -102,6 +102,8 @@ namespace osu.Game.Beatmaps } } + private object ImportLock = new object(); + /// /// Import a beatmap from an . /// @@ -109,7 +111,7 @@ namespace osu.Game.Beatmaps public BeatmapSetInfo Import(ArchiveReader archiveReader) { // let's only allow one concurrent import at a time for now. - lock (this) + lock (ImportLock) { BeatmapSetInfo set = importToStorage(archiveReader); Import(set); @@ -126,7 +128,8 @@ namespace osu.Game.Beatmaps // If we have an ID then we already exist in the database. if (beatmapSetInfo.ID != 0) return; - beatmaps.Add(beatmapSetInfo); + lock (beatmaps) + beatmaps.Add(beatmapSetInfo); } /// @@ -136,13 +139,11 @@ namespace osu.Game.Beatmaps /// The beatmap to delete. public void Delete(BeatmapSetInfo beatmapSet) { - lock (this) - { + lock (beatmaps) if (!beatmaps.Delete(beatmapSet)) return; - if (!beatmapSet.Protected) - files.Dereference(beatmapSet.Files); - } + if (!beatmapSet.Protected) + files.Dereference(beatmapSet.Files); } /// @@ -152,12 +153,10 @@ namespace osu.Game.Beatmaps /// The beatmap to restore. public void Undelete(BeatmapSetInfo beatmapSet) { - lock (this) - { + lock (beatmaps) if (!beatmaps.Undelete(beatmapSet)) return; - files.Reference(beatmapSet.Files); - } + files.Reference(beatmapSet.Files); } /// @@ -168,25 +167,23 @@ namespace osu.Game.Beatmaps /// A instance correlating to the provided . public WorkingBeatmap GetWorkingBeatmap(BeatmapInfo beatmapInfo, WorkingBeatmap previous = null) { - lock (this) - { - if (beatmapInfo == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo) - return DefaultBeatmap; + if (beatmapInfo == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo) + return DefaultBeatmap; + lock (beatmaps) beatmaps.Populate(beatmapInfo); - if (beatmapInfo.BeatmapSet == null) - throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetInfoID} is not in the local database."); + if (beatmapInfo.BeatmapSet == null) + throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetInfoID} is not in the local database."); - if (beatmapInfo.Metadata == null) - beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata; + if (beatmapInfo.Metadata == null) + beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata; - WorkingBeatmap working = new BeatmapManagerWorkingBeatmap(files.Store, beatmapInfo); + WorkingBeatmap working = new BeatmapManagerWorkingBeatmap(files.Store, beatmapInfo); - previous?.TransferTo(working); + previous?.TransferTo(working); - return working; - } + return working; } /// From d93d9e619019ab0b34f1a3a618ea9de8f2f8e47c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jul 2017 15:08:56 +0900 Subject: [PATCH 37/72] Tidy up file deletion after import --- osu.Game/Beatmaps/BeatmapManager.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 16a1268e88..646ae3fae9 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -87,11 +87,12 @@ namespace osu.Game.Beatmaps // TODO: Add a check to prevent files from storage to be deleted. try { - File.Delete(path); + if (File.Exists(path)) + File.Delete(path); } catch (Exception e) { - Logger.Error(e, $@"Could not delete file at {path}"); + Logger.Error(e, $@"Could not delete original file after import ({Path.GetFileName(path)})"); } } catch (Exception e) From f5b0253e8234f142f61981bffa17b84acd5ae6ed Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jul 2017 15:36:23 +0900 Subject: [PATCH 38/72] Apply CI fixes --- osu.Game/Beatmaps/BeatmapManager.cs | 41 +++++++++++++++++++---------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 646ae3fae9..de65db1a5a 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -103,7 +103,7 @@ namespace osu.Game.Beatmaps } } - private object ImportLock = new object(); + private readonly object importLock = new object(); /// /// Import a beatmap from an . @@ -112,7 +112,7 @@ namespace osu.Game.Beatmaps public BeatmapSetInfo Import(ArchiveReader archiveReader) { // let's only allow one concurrent import at a time for now. - lock (ImportLock) + lock (importLock) { BeatmapSetInfo set = importToStorage(archiveReader); Import(set); @@ -192,7 +192,8 @@ namespace osu.Game.Beatmaps /// public void Reset() { - beatmaps.Reset(); + lock (beatmaps) + beatmaps.Reset(); } /// @@ -202,12 +203,15 @@ namespace osu.Game.Beatmaps /// The first result for the provided query, or null if no results were found. public BeatmapSetInfo QueryBeatmapSet(Func query) { - BeatmapSetInfo set = beatmaps.Query().FirstOrDefault(query); + lock (beatmaps) + { + BeatmapSetInfo set = beatmaps.Query().FirstOrDefault(query); - if (set != null) - beatmaps.Populate(set); + if (set != null) + beatmaps.Populate(set); - return set; + return set; + } } /// @@ -215,7 +219,10 @@ namespace osu.Game.Beatmaps /// /// The query. /// Results from the provided query. - public List QueryBeatmapSets(Expression> query) => beatmaps.QueryAndPopulate(query); + public List QueryBeatmapSets(Expression> query) + { + lock (beatmaps) return beatmaps.QueryAndPopulate(query); + } /// /// Perform a lookup query on available s. @@ -224,12 +231,15 @@ namespace osu.Game.Beatmaps /// The first result for the provided query, or null if no results were found. public BeatmapInfo QueryBeatmap(Func query) { - BeatmapInfo set = beatmaps.Query().FirstOrDefault(query); + lock (beatmaps) + { + BeatmapInfo set = beatmaps.Query().FirstOrDefault(query); - if (set != null) - beatmaps.Populate(set); + if (set != null) + beatmaps.Populate(set); - return set; + return set; + } } /// @@ -237,7 +247,10 @@ namespace osu.Game.Beatmaps /// /// The query. /// Results from the provided query. - public List QueryBeatmaps(Expression> query) => beatmaps.QueryAndPopulate(query); + public List QueryBeatmaps(Expression> query) + { + lock (beatmaps) return beatmaps.QueryAndPopulate(query); + } /// /// Creates an from a valid storage path. @@ -336,7 +349,7 @@ namespace osu.Game.Beatmaps /// A list of available . public List GetAllUsableBeatmapSets(bool populate = true) { - lock (this) + lock (beatmaps) { if (populate) return beatmaps.QueryAndPopulate(b => !b.DeletePending).ToList(); From c48bf3940e163df31e5291f8da5348ca02317f48 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jul 2017 16:55:58 +0900 Subject: [PATCH 39/72] Add a progress notification when importing beatmaps --- osu.Game/Beatmaps/BeatmapManager.cs | 29 ++++++++++++++++++++++++++--- osu.Game/OsuGameBase.cs | 2 +- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index de65db1a5a..f32dbc8322 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -17,6 +17,7 @@ using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.IO; using osu.Game.IO; using osu.Game.IPC; +using osu.Game.Overlays.Notifications; using osu.Game.Rulesets; using SQLite.Net; using FileInfo = osu.Game.IO.FileInfo; @@ -48,13 +49,14 @@ namespace osu.Game.Beatmaps private readonly FileStore files; private readonly RulesetStore rulesets; + private readonly Action postNotification; private readonly BeatmapStore beatmaps; // ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised) private BeatmapIPCChannel ipc; - public BeatmapManager(Storage storage, FileStore files, SQLiteConnection connection, RulesetStore rulesets, IIpcHost importHost = null) + public BeatmapManager(Storage storage, FileStore files, SQLiteConnection connection, RulesetStore rulesets, IIpcHost importHost = null, Action postNotification = null) { beatmaps = new BeatmapStore(connection); beatmaps.BeatmapSetAdded += s => BeatmapSetAdded?.Invoke(s); @@ -63,24 +65,43 @@ namespace osu.Game.Beatmaps this.storage = storage; this.files = files; this.rulesets = rulesets; + this.postNotification = postNotification; if (importHost != null) ipc = new BeatmapIPCChannel(importHost, this); } /// - /// Import multiple from filesystem . + /// Import one or more from filesystem . + /// This will post a notification tracking import progress. /// - /// Multiple locations on disk. + /// One or more beatmap locations on disk. public void Import(params string[] paths) { + var notification = new ProgressNotification + { + Text = "Beatmap import is initialising...", + Progress = 0, + State = ProgressNotificationState.Active, + }; + + postNotification?.Invoke(notification); + + int i = 0; foreach (string path in paths) { + if (notification.State == ProgressNotificationState.Cancelled) + // user requested abort + return; + try { + notification.Text = $"Importing ({i} of {paths.Length})\n{Path.GetFileName(path)}"; using (ArchiveReader reader = getReaderFrom(path)) Import(reader); + notification.Progress = (float)++i / paths.Length; + // We may or may not want to delete the file depending on where it is stored. // e.g. reconstructing/repairing database with beatmaps from default storage. // Also, not always a single file, i.e. for LegacyFilesystemReader @@ -101,6 +122,8 @@ namespace osu.Game.Beatmaps Logger.Error(e, @"Could not import beatmap set"); } } + + notification.State = ProgressNotificationState.Completed; } private readonly object importLock = new object(); diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 0dec4228de..8a09c7aac7 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -102,7 +102,7 @@ namespace osu.Game 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, Host, PostNotification)); dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, connection, Host, BeatmapManager)); dependencies.Cache(new OsuColour()); From 8458622c4d4b82754004be7832e7e120309d16ee Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sat, 29 Jul 2017 16:03:17 +0300 Subject: [PATCH 40/72] Add ScrollToSelected method --- osu.Game/Screens/Select/BeatmapCarousel.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 743a0a0f63..1177d820c3 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -281,6 +281,12 @@ namespace osu.Game.Screens.Select perform(); } + public void ScrollToSelected(bool animated = true) + { + float selectedY = computeYPositions(animated); + ScrollTo(selectedY, animated); + } + private BeatmapGroup createGroup(BeatmapSetInfo beatmapSet) { foreach (var b in beatmapSet.Beatmaps) @@ -420,8 +426,7 @@ namespace osu.Game.Screens.Select } finally { - float selectedY = computeYPositions(animated); - ScrollTo(selectedY, animated); + ScrollToSelected(animated); } } From e121b119be21d896b8754c43e5fdf3daf2433d0c Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sat, 29 Jul 2017 17:33:20 +0300 Subject: [PATCH 41/72] Added "scroll to" container --- osu.Game/Screens/Select/SongSelect.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index bbd292870e..57e2183853 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -31,6 +31,7 @@ namespace osu.Game.Screens.Select private BeatmapManager manager; protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(); + private readonly ActionContainer actionContainer; private readonly BeatmapCarousel carousel; private DialogOverlay dialogOverlay; @@ -129,6 +130,12 @@ namespace osu.Game.Screens.Select Right = left_area_padding, }, }); + Add(actionContainer = new ActionContainer + { + RelativeSizeAxes = Axes.Y, + Width = 250, + OnHoverAction = () => carousel.ScrollToSelected(), + }); if (ShowFooter) { @@ -409,5 +416,16 @@ namespace osu.Game.Screens.Select return base.OnKeyDown(state, args); } + + private class ActionContainer : Container + { + public Action OnHoverAction; + + protected override bool OnHover(InputState state) + { + OnHoverAction?.Invoke(); + return base.OnHover(state); + } + } } } From 6b3a81f5671b064e9ab067819f94a6c4ac675673 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sat, 29 Jul 2017 17:42:32 +0300 Subject: [PATCH 42/72] Fix hard crash when pressing random if no beatmaps avaliable --- osu.Game/Screens/Select/BeatmapCarousel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 1177d820c3..9e5446a573 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -181,12 +181,12 @@ namespace osu.Game.Screens.Select if (groups.Count == 0) return; - randomSelectedBeatmaps.Push(new KeyValuePair(selectedGroup, selectedGroup.SelectedPanel)); - var visibleGroups = getVisibleGroups(); if (!visibleGroups.Any()) return; + randomSelectedBeatmaps.Push(new KeyValuePair(selectedGroup, selectedGroup.SelectedPanel)); + BeatmapGroup group; if (randomType == SelectionRandomType.RandomPermutation) From 62365090add453e1120d21090e100d605f3f7d01 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sat, 29 Jul 2017 17:51:11 +0300 Subject: [PATCH 43/72] Removed useless variable --- osu.Game/Screens/Select/SongSelect.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 57e2183853..94740c0216 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -31,7 +31,6 @@ namespace osu.Game.Screens.Select private BeatmapManager manager; protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(); - private readonly ActionContainer actionContainer; private readonly BeatmapCarousel carousel; private DialogOverlay dialogOverlay; @@ -130,7 +129,7 @@ namespace osu.Game.Screens.Select Right = left_area_padding, }, }); - Add(actionContainer = new ActionContainer + Add(new ActionContainer { RelativeSizeAxes = Axes.Y, Width = 250, From df5094c0d4aab957f4894de87de27f77542e1b13 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Jul 2017 18:03:55 +0900 Subject: [PATCH 44/72] Rework how notifications are distributed --- osu.Game/Beatmaps/BeatmapManager.cs | 11 +++++++---- osu.Game/OsuGame.cs | 3 +++ osu.Game/OsuGameBase.cs | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index f32dbc8322..c471502d88 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -49,14 +49,18 @@ namespace osu.Game.Beatmaps private readonly FileStore files; private readonly RulesetStore rulesets; - private readonly Action postNotification; private readonly BeatmapStore beatmaps; // ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised) private BeatmapIPCChannel ipc; - public BeatmapManager(Storage storage, FileStore files, SQLiteConnection connection, RulesetStore rulesets, IIpcHost importHost = null, Action postNotification = null) + /// + /// Set an endpoint for notifications to be posted to. + /// + public Action PostNotification { private get; set; } + + public BeatmapManager(Storage storage, FileStore files, SQLiteConnection connection, RulesetStore rulesets, IIpcHost importHost = null) { beatmaps = new BeatmapStore(connection); beatmaps.BeatmapSetAdded += s => BeatmapSetAdded?.Invoke(s); @@ -65,7 +69,6 @@ namespace osu.Game.Beatmaps this.storage = storage; this.files = files; this.rulesets = rulesets; - this.postNotification = postNotification; if (importHost != null) ipc = new BeatmapIPCChannel(importHost, this); @@ -85,7 +88,7 @@ namespace osu.Game.Beatmaps State = ProgressNotificationState.Active, }; - postNotification?.Invoke(notification); + PostNotification?.Invoke(notification); int i = 0; foreach (string path in paths) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index fe6d2dbb41..4082ed4ecd 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -149,6 +149,9 @@ namespace osu.Game { base.LoadComplete(); + // hook up notifications to components. + BeatmapManager.PostNotification = n => notificationOverlay?.Post(n); + AddRange(new Drawable[] { new VolumeControlReceptor { diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 8a09c7aac7..0dec4228de 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -102,7 +102,7 @@ namespace osu.Game 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, PostNotification)); + dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, Host)); dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, connection, Host, BeatmapManager)); dependencies.Cache(new OsuColour()); From 92b3c7ac08c260fc0c1f5afa3306cbba4157fed2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Jul 2017 18:38:42 +0900 Subject: [PATCH 45/72] Fix the whole database being retrieved when importing each beatmap --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index c471502d88..8cced2d5f4 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -308,7 +308,7 @@ namespace osu.Game.Beatmaps var hash = hashable.ComputeSHA2Hash(); // check if this beatmap has already been imported and exit early if so. - var beatmapSet = beatmaps.QueryAndPopulate().FirstOrDefault(b => b.Hash == hash); + var beatmapSet = beatmaps.QueryAndPopulate(b => b.Hash == hash).FirstOrDefault(); if (beatmapSet != null) { Undelete(beatmapSet); From bc8f8de0495e6b8702e800b73456128ecc3f0a2f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Jul 2017 18:41:54 +0900 Subject: [PATCH 46/72] Make QueryAndPopulate's filter non-optional (you basically *never* want this missing) --- osu.Game/Database/DatabaseBackedStore.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/DatabaseBackedStore.cs b/osu.Game/Database/DatabaseBackedStore.cs index bb61fc1870..bd25acc41b 100644 --- a/osu.Game/Database/DatabaseBackedStore.cs +++ b/osu.Game/Database/DatabaseBackedStore.cs @@ -83,9 +83,9 @@ namespace osu.Game.Database /// /// Query and populate results. /// - /// An optional filter to refine results. + /// An filter to refine results. /// - public List QueryAndPopulate(Expression> filter = null) + public List QueryAndPopulate(Expression> filter) where T : class { checkType(typeof(T)); From f67822a59b9256f221de0461806df238073f8063 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Jul 2017 18:52:59 +0900 Subject: [PATCH 47/72] Add progress for deleting all maps --- osu.Game/Beatmaps/BeatmapManager.cs | 30 +++++++++++++++++++ .../Sections/Maintenance/GeneralSettings.cs | 6 +--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 8cced2d5f4..3890abd341 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -459,5 +459,35 @@ namespace osu.Game.Beatmaps Import(Directory.GetDirectories(stableInstallPath)); } + + public void DeleteAll() + { + var maps = GetAllUsableBeatmapSets().ToArray(); + + if (maps.Length == 0) return; + + var notification = new ProgressNotification + { + Progress = 0, + State = ProgressNotificationState.Active, + }; + + PostNotification?.Invoke(notification); + + int i = 0; + + foreach (var b in maps) + { + if (notification.State == ProgressNotificationState.Cancelled) + // user requested abort + return; + + notification.Text = $"Deleting ({i} of {maps.Length})"; + notification.Progress = (float)++i / maps.Length; + Delete(b); + } + + notification.State = ProgressNotificationState.Completed; + } } } diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs index 684bfcb39d..9d13a2ae2f 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs @@ -38,11 +38,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance Action = () => { deleteButton.Enabled.Value = false; - Task.Run(() => - { - foreach (var b in beatmaps.GetAllUsableBeatmapSets()) - beatmaps.Delete(b); - }).ContinueWith(t => Schedule(() => deleteButton.Enabled.Value = true)); + Task.Run(() => beatmaps.DeleteAll()).ContinueWith(t => Schedule(() => deleteButton.Enabled.Value = true)); } }, }; From 700c7753c3d2096741aeefa9718506fb8a3196a9 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Mon, 31 Jul 2017 14:20:12 +0300 Subject: [PATCH 48/72] Applied suggestions --- osu.Game/Screens/Select/SongSelect.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 94740c0216..fd314e1559 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -129,11 +129,10 @@ namespace osu.Game.Screens.Select Right = left_area_padding, }, }); - Add(new ActionContainer + Add(new ResetScrollContainer(() => carousel.ScrollToSelected()) { RelativeSizeAxes = Axes.Y, Width = 250, - OnHoverAction = () => carousel.ScrollToSelected(), }); if (ShowFooter) @@ -416,13 +415,18 @@ namespace osu.Game.Screens.Select return base.OnKeyDown(state, args); } - private class ActionContainer : Container + private class ResetScrollContainer : Container { - public Action OnHoverAction; + private readonly Action onHoverAction; + + public ResetScrollContainer(Action onHoverAction) + { + this.onHoverAction = onHoverAction; + } protected override bool OnHover(InputState state) { - OnHoverAction?.Invoke(); + onHoverAction?.Invoke(); return base.OnHover(state); } } From 404497fa101504da2488331e6160346fda145caf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Jul 2017 21:48:03 +0900 Subject: [PATCH 49/72] Allow a single beatmap to reference the same file multiple times This fixes incorrect reference counts causing database desync. --- osu.Game/Beatmaps/BeatmapManager.cs | 16 +++++++---- osu.Game/Beatmaps/BeatmapSetFileInfo.cs | 14 +++++++-- osu.Game/Beatmaps/BeatmapSetInfo.cs | 5 ++-- osu.Game/Database/DatabaseBackedStore.cs | 1 - osu.Game/IO/FileInfo.cs | 2 -- osu.Game/IO/FileStore.cs | 36 +++++++++++++++--------- 6 files changed, 46 insertions(+), 28 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 99117afe35..15225fe821 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -19,7 +19,6 @@ using osu.Game.IO; using osu.Game.IPC; using osu.Game.Rulesets; using SQLite.Net; -using FileInfo = osu.Game.IO.FileInfo; namespace osu.Game.Beatmaps { @@ -135,7 +134,7 @@ namespace osu.Game.Beatmaps if (!beatmaps.Delete(beatmapSet)) return; if (!beatmapSet.Protected) - files.Dereference(beatmapSet.Files); + files.Dereference(beatmapSet.Files.Select(f => f.FileInfo)); } /// @@ -147,7 +146,8 @@ namespace osu.Game.Beatmaps { if (!beatmaps.Undelete(beatmapSet)) return; - files.Reference(beatmapSet.Files); + if (!beatmapSet.Protected) + files.Reference(beatmapSet.Files.Select(f => f.FileInfo)); } /// @@ -265,12 +265,16 @@ namespace osu.Game.Beatmaps return beatmapSet; } - List fileInfos = new List(); + List fileInfos = new List(); // import files to manager foreach (string file in reader.Filenames) using (Stream s = reader.GetStream(file)) - fileInfos.Add(files.Add(s, file)); + fileInfos.Add(new BeatmapSetFileInfo + { + Filename = file, + FileInfo = files.Add(s) + }); BeatmapMetadata metadata; @@ -366,7 +370,7 @@ namespace osu.Game.Beatmaps catch { return null; } } - private string getPathForFile(string filename) => BeatmapSetInfo.Files.First(f => f.Filename == filename).StoragePath; + private string getPathForFile(string filename) => BeatmapSetInfo.Files.First(f => f.Filename == filename).FileInfo.StoragePath; protected override Texture GetBackground() { diff --git a/osu.Game/Beatmaps/BeatmapSetFileInfo.cs b/osu.Game/Beatmaps/BeatmapSetFileInfo.cs index d18b1e833b..a05362b32d 100644 --- a/osu.Game/Beatmaps/BeatmapSetFileInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetFileInfo.cs @@ -2,16 +2,26 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Game.IO; +using SQLite.Net.Attributes; using SQLiteNetExtensions.Attributes; namespace osu.Game.Beatmaps { public class BeatmapSetFileInfo { - [ForeignKey(typeof(BeatmapSetInfo))] + [PrimaryKey, AutoIncrement] + public int ID { get; set; } + + [ForeignKey(typeof(BeatmapSetInfo)), NotNull] public int BeatmapSetInfoID { get; set; } - [ForeignKey(typeof(FileInfo))] + [ForeignKey(typeof(FileInfo)), NotNull] public int FileInfoID { get; set; } + + [OneToOne(CascadeOperations = CascadeOperation.CascadeRead)] + public FileInfo FileInfo { get; set; } + + [NotNull] + public string Filename { get; set; } } } \ No newline at end of file diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index a99ba94e9a..f47affcab8 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using osu.Game.IO; using SQLite.Net.Attributes; using SQLiteNetExtensions.Attributes; @@ -37,8 +36,8 @@ namespace osu.Game.Beatmaps public string StoryboardFile => Files.FirstOrDefault(f => f.Filename.EndsWith(".osb"))?.Filename; - [ManyToMany(typeof(BeatmapSetFileInfo), CascadeOperations = CascadeOperation.CascadeRead)] - public List Files { get; set; } + [OneToMany(CascadeOperations = CascadeOperation.All)] + public List Files { get; set; } public bool Protected { get; set; } } diff --git a/osu.Game/Database/DatabaseBackedStore.cs b/osu.Game/Database/DatabaseBackedStore.cs index bb61fc1870..5214372a8b 100644 --- a/osu.Game/Database/DatabaseBackedStore.cs +++ b/osu.Game/Database/DatabaseBackedStore.cs @@ -101,7 +101,6 @@ namespace osu.Game.Database public void Populate(T item, bool recursive = true) { checkType(item.GetType()); - Connection.GetChildren(item, recursive); } diff --git a/osu.Game/IO/FileInfo.cs b/osu.Game/IO/FileInfo.cs index 6f4c4b26e8..367fd68f7b 100644 --- a/osu.Game/IO/FileInfo.cs +++ b/osu.Game/IO/FileInfo.cs @@ -11,8 +11,6 @@ namespace osu.Game.IO [PrimaryKey, AutoIncrement] public int ID { get; set; } - public string Filename { get; set; } - [Indexed(Unique = true)] public string Hash { get; set; } diff --git a/osu.Game/IO/FileStore.cs b/osu.Game/IO/FileStore.cs index e8cabafe17..2132037559 100644 --- a/osu.Game/IO/FileStore.cs +++ b/osu.Game/IO/FileStore.cs @@ -42,15 +42,11 @@ namespace osu.Game.IO deletePending(); } - public FileInfo Add(Stream data, string filename = null) + public FileInfo Add(Stream data) { string hash = data.ComputeSHA2Hash(); - var info = new FileInfo - { - Filename = filename, - Hash = hash, - }; + var info = new FileInfo { Hash = hash }; var existing = Connection.Table().FirstOrDefault(f => f.Hash == info.Hash); @@ -79,20 +75,32 @@ namespace osu.Game.IO public void Reference(IEnumerable files) { - foreach (var f in files) + Connection.RunInTransaction(() => { - f.ReferenceCount++; - Connection.Update(f); - } + var incrementedFiles = files.GroupBy(f => f.ID).Select(f => + { + var accurateRefCount = Connection.Get(f.First().ID); + accurateRefCount.ReferenceCount += f.Count(); + return accurateRefCount; + }); + + Connection.UpdateAll(incrementedFiles); + }); } public void Dereference(IEnumerable files) { - foreach (var f in files) + Connection.RunInTransaction(() => { - f.ReferenceCount--; - Connection.Update(f); - } + var incrementedFiles = files.GroupBy(f => f.ID).Select(f => + { + var accurateRefCount = Connection.Get(f.First().ID); + accurateRefCount.ReferenceCount -= f.Count(); + return accurateRefCount; + }); + + Connection.UpdateAll(incrementedFiles); + }); } private void deletePending() From 6af0629cc0ea8db5b86018a5d51e3374e531bbe6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Aug 2017 09:37:33 +0900 Subject: [PATCH 50/72] Remove unnecessary newline --- osu.Game/Beatmaps/BeatmapManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 3890abd341..784d440584 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -446,7 +446,6 @@ namespace osu.Game.Beatmaps public void ImportFromStable() { - string stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!", "Songs"); if (!Directory.Exists(stableInstallPath)) stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".osu", "Songs"); From ed3e78452e6e01ef7d0a82dbd4687ce259b3932b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Aug 2017 09:38:43 +0900 Subject: [PATCH 51/72] Lock beatmaps for good measure --- osu.Game/Beatmaps/BeatmapManager.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 784d440584..a23fab5393 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -308,7 +308,10 @@ namespace osu.Game.Beatmaps var hash = hashable.ComputeSHA2Hash(); // check if this beatmap has already been imported and exit early if so. - var beatmapSet = beatmaps.QueryAndPopulate(b => b.Hash == hash).FirstOrDefault(); + BeatmapSetInfo beatmapSet; + lock (beatmaps) + beatmapSet = beatmaps.QueryAndPopulate(b => b.Hash == hash).FirstOrDefault(); + if (beatmapSet != null) { Undelete(beatmapSet); From c060d32765d486f49e7ac9b1d02b71c3579809ad Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Aug 2017 10:08:05 +0900 Subject: [PATCH 52/72] Separate out startup tasks to ensure they run after migrations --- osu.Game/Beatmaps/BeatmapStore.cs | 12 ++++++++---- osu.Game/Database/DatabaseBackedStore.cs | 20 ++++++++++++++++++-- osu.Game/IO/FileStore.cs | 4 ++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapStore.cs b/osu.Game/Beatmaps/BeatmapStore.cs index 102900ae81..d1c33d1151 100644 --- a/osu.Game/Beatmaps/BeatmapStore.cs +++ b/osu.Game/Beatmaps/BeatmapStore.cs @@ -52,7 +52,11 @@ namespace osu.Game.Beatmaps Connection.CreateTable(); Connection.CreateTable(); Connection.CreateTable(); + } + protected override void StartupTasks() + { + base.StartupTasks(); cleanupPendingDeletions(); } @@ -60,12 +64,12 @@ namespace osu.Game.Beatmaps /// Perform migrations between two store versions. /// /// The current store version. This will be zero on a fresh database initialisation. - /// The target version which we are migrating to (equal to the current ). - protected override void PerformMigration(int currentVersion, int newVersion) + /// The target version which we are migrating to (equal to the current ). + protected override void PerformMigration(int currentVersion, int targetVersion) { - base.PerformMigration(currentVersion, newVersion); + base.PerformMigration(currentVersion, targetVersion); - while (currentVersion++ < newVersion) + while (currentVersion++ < targetVersion) { switch (currentVersion) { diff --git a/osu.Game/Database/DatabaseBackedStore.cs b/osu.Game/Database/DatabaseBackedStore.cs index 5214372a8b..ae3409bbcf 100644 --- a/osu.Game/Database/DatabaseBackedStore.cs +++ b/osu.Game/Database/DatabaseBackedStore.cs @@ -51,14 +51,30 @@ namespace osu.Game.Database PerformMigration(reportedVersion.Version, reportedVersion.Version = StoreVersion); Connection.InsertOrReplace(reportedVersion); + + StartupTasks(); } - protected virtual void PerformMigration(int currentVersion, int newVersion) + /// + /// Called when the database version of this store doesn't match the local version. + /// Any manual migration operations should be performed in this. + /// + /// The current store version. This will be zero on a fresh database initialisation. + /// The target version which we are migrating to (equal to the current ). + protected virtual void PerformMigration(int currentVersion, int targetVersion) { } /// - /// Prepare this database for use. + /// Perform any common startup tasks. Runs after and . + /// + protected virtual void StartupTasks() + { + + } + + /// + /// Prepare this database for use. Tables should be created here. /// protected abstract void Prepare(bool reset = false); diff --git a/osu.Game/IO/FileStore.cs b/osu.Game/IO/FileStore.cs index 2132037559..e35382ea8c 100644 --- a/osu.Game/IO/FileStore.cs +++ b/osu.Game/IO/FileStore.cs @@ -38,7 +38,11 @@ namespace osu.Game.IO Connection.DropTable(); Connection.CreateTable(); + } + protected override void StartupTasks() + { + base.StartupTasks(); deletePending(); } From c73e139954e42c03d627b22ef6924ecead8140df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Aug 2017 10:16:48 +0900 Subject: [PATCH 53/72] Add "migration" Also simplify initial migration for BeatmapStore by just nuking everything. --- osu.Game/Beatmaps/BeatmapStore.cs | 13 ++++------- osu.Game/IO/FileStore.cs | 36 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapStore.cs b/osu.Game/Beatmaps/BeatmapStore.cs index d1c33d1151..97cfdcf31b 100644 --- a/osu.Game/Beatmaps/BeatmapStore.cs +++ b/osu.Game/Beatmaps/BeatmapStore.cs @@ -21,7 +21,7 @@ namespace osu.Game.Beatmaps /// The current version of this store. Used for migrations (see ). /// The initial version is 1. /// - protected override int StoreVersion => 1; + protected override int StoreVersion => 2; public BeatmapStore(SQLiteConnection connection) : base(connection) @@ -74,14 +74,9 @@ namespace osu.Game.Beatmaps switch (currentVersion) { case 1: - // initialising from a version before we had versioning (or a fresh install). - - // force adding of Protected column (not automatically migrated). - Connection.MigrateTable(); - - // remove all existing beatmaps. - foreach (var b in Connection.GetAllWithChildren(null, true)) - Connection.Delete(b, true); + case 2: + // cannot migrate; breaking underlying changes. + Reset(); break; } } diff --git a/osu.Game/IO/FileStore.cs b/osu.Game/IO/FileStore.cs index e35382ea8c..94c9697922 100644 --- a/osu.Game/IO/FileStore.cs +++ b/osu.Game/IO/FileStore.cs @@ -23,6 +23,8 @@ namespace osu.Game.IO public readonly ResourceStore Store; + protected override int StoreVersion => 2; + public FileStore(SQLiteConnection connection, Storage storage) : base(connection, storage) { Store = new NamespacedResourceStore(new StorageBackedResourceStore(storage), prefix); @@ -35,7 +37,19 @@ namespace osu.Game.IO protected override void Prepare(bool reset = false) { if (reset) + { + try + { + foreach (var f in Query()) + Storage.Delete(Path.Combine(prefix, f.Hash)); + } + catch + { + // we don't want to ever crash as a result of a reset operation. + } + Connection.DropTable(); + } Connection.CreateTable(); } @@ -46,6 +60,28 @@ namespace osu.Game.IO deletePending(); } + /// + /// Perform migrations between two store versions. + /// + /// The current store version. This will be zero on a fresh database initialisation. + /// The target version which we are migrating to (equal to the current ). + protected override void PerformMigration(int currentVersion, int targetVersion) + { + base.PerformMigration(currentVersion, targetVersion); + + while (currentVersion++ < targetVersion) + { + switch (currentVersion) + { + case 1: + case 2: + // cannot migrate; breaking underlying changes. + Reset(); + break; + } + } + } + public FileInfo Add(Stream data) { string hash = data.ComputeSHA2Hash(); From 821f65c381ac2bcb9a41589df3b781285ca3e2fd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Aug 2017 10:20:28 +0900 Subject: [PATCH 54/72] Actually delete files --- osu.Game/IO/FileStore.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/IO/FileStore.cs b/osu.Game/IO/FileStore.cs index 94c9697922..191c97e272 100644 --- a/osu.Game/IO/FileStore.cs +++ b/osu.Game/IO/FileStore.cs @@ -41,7 +41,7 @@ namespace osu.Game.IO try { foreach (var f in Query()) - Storage.Delete(Path.Combine(prefix, f.Hash)); + Storage.Delete(Path.Combine(prefix, f.StoragePath)); } catch { @@ -150,7 +150,7 @@ namespace osu.Game.IO try { Connection.Delete(f); - Storage.Delete(Path.Combine(prefix, f.Hash)); + Storage.Delete(Path.Combine(prefix, f.StoragePath)); } catch (Exception e) { From 9d630e446eec6205e773064a2d2d17a1d5059535 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Aug 2017 10:57:46 +0900 Subject: [PATCH 55/72] Use new storage methods to reset FileStore Guarantees that backing files are cleaned up correctly. Also handles lingering "beatmaps" directory from older builds. --- osu.Game/IO/FileStore.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/osu.Game/IO/FileStore.cs b/osu.Game/IO/FileStore.cs index 191c97e272..e55af2e23a 100644 --- a/osu.Game/IO/FileStore.cs +++ b/osu.Game/IO/FileStore.cs @@ -38,15 +38,12 @@ namespace osu.Game.IO { if (reset) { - try - { - foreach (var f in Query()) - Storage.Delete(Path.Combine(prefix, f.StoragePath)); - } - catch - { - // we don't want to ever crash as a result of a reset operation. - } + // in earlier versions we stored beatmaps as solid archives, but not any more. + if (Storage.ExistsDirectory("beatmaps")) + Storage.DeleteDirectory("beatmaps"); + + if (Storage.ExistsDirectory(prefix)) + Storage.DeleteDirectory(prefix); Connection.DropTable(); } From 9db4caafba5eca07b59a75d803be17e91cdfb16b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Aug 2017 11:05:33 +0900 Subject: [PATCH 56/72] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 5a9ca94fc3..2204764944 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 5a9ca94fc31bc796b45572eb3d0b27b46556c586 +Subproject commit 2204764944ff693e857649253547054cc91764a0 From bb3a8a29eacc2b2643c91d84a41ffad8582c6938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Park=20=28=EB=B0=95=EC=83=81=ED=9D=AC=29?= Date: Tue, 1 Aug 2017 11:31:11 +0900 Subject: [PATCH 57/72] Hide Notification when playing osu Hide Notification Overlay when playing osu --- osu.Game/OsuGame.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 4082ed4ecd..a70a7b7d97 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -334,6 +334,7 @@ namespace osu.Game direct.State = Visibility.Hidden; social.State = Visibility.Hidden; userProfile.State = Visibility.Hidden; + notificationOverlay.State = Visibility.Hidden; } else { From 941f3f0934cbe6ec40b7da05f01242489caf8a83 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Aug 2017 15:12:12 +0900 Subject: [PATCH 58/72] Tidy up osu-stable import process Now can locate any osu-stable installation using registry lookup (with ample fallbacks). Also uses a much more controlled access method via StableStorage. --- osu.Desktop/OsuGameDesktop.cs | 52 +++++++++++++++++++++++++++++ osu.Game/Beatmaps/BeatmapManager.cs | 18 ++++++---- osu.Game/OsuGame.cs | 4 +++ 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index bd5c6c6790..f1427d2861 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.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.Game; using System.Linq; using System.Windows.Forms; @@ -11,6 +12,7 @@ using System.Reflection; using System.Drawing; using System.IO; using System.Threading.Tasks; +using Microsoft.Win32; using osu.Framework.Graphics.Containers; using osu.Game.Screens.Menu; @@ -30,6 +32,56 @@ namespace osu.Desktop }; } + public override Storage GetStorageForStableInstall() + { + try + { + return new StableStorage(); + } + catch + { + return null; + } + } + + /// + /// A method of accessing an osu-stable install in a controlled fashion. + /// + private class StableStorage : DesktopStorage + { + protected override string LocateBasePath() + { + string stableInstallPath; + + try + { + using (RegistryKey key = Registry.ClassesRoot.OpenSubKey("osu")) + stableInstallPath = key?.OpenSubKey(@"shell\open\command")?.GetValue(String.Empty).ToString().Split('"')[1].Replace("osu!.exe", ""); + + if (Directory.Exists(stableInstallPath)) + return stableInstallPath; + } + catch + { + } + + stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!", "Songs"); + if (Directory.Exists(stableInstallPath)) + return stableInstallPath; + + stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".osu", "Songs"); + if (Directory.Exists(stableInstallPath)) + return stableInstallPath; + + return null; + } + + public StableStorage() + : base(string.Empty) + { + } + } + protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 5cc2a2a430..6059db0a36 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -59,6 +59,11 @@ namespace osu.Game.Beatmaps /// public Action PostNotification { private get; set; } + /// + /// Set a storage with access to an osu-stable install for import purposes. + /// + public Func GetStableStorage { private get; set; } + public BeatmapManager(Storage storage, FileStore files, SQLiteConnection connection, RulesetStore rulesets, IIpcHost importHost = null) { beatmaps = new BeatmapStore(connection); @@ -451,19 +456,20 @@ namespace osu.Game.Beatmaps } } + /// + /// This is a temporary method and will likely be replaced by a full-fledged (and more correctly placed) migration process in the future. + /// public void ImportFromStable() { - string stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!", "Songs"); - if (!Directory.Exists(stableInstallPath)) - stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".osu", "Songs"); + var stable = GetStableStorage?.Invoke(); - if (!Directory.Exists(stableInstallPath)) + if (stable == null) { - Logger.Log("Couldn't find an osu!stable installation!", LoggingTarget.Information, LogLevel.Error); + Logger.Log("No osu!stable installation available!", LoggingTarget.Information, LogLevel.Error); return; } - Import(Directory.GetDirectories(stableInstallPath)); + Import(stable.GetDirectories("Songs")); } public void DeleteAll() diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index a70a7b7d97..8d8c5cf26e 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -20,6 +20,7 @@ using osu.Game.Screens.Menu; using OpenTK; using System.Linq; using System.Threading.Tasks; +using osu.Framework.Platform; using osu.Framework.Threading; using osu.Game.Graphics; using osu.Game.Rulesets.Scoring; @@ -47,6 +48,8 @@ namespace osu.Game private UserProfileOverlay userProfile; + public virtual Storage GetStorageForStableInstall() => null; + private Intro intro { get @@ -151,6 +154,7 @@ namespace osu.Game // hook up notifications to components. BeatmapManager.PostNotification = n => notificationOverlay?.Post(n); + BeatmapManager.GetStableStorage = GetStorageForStableInstall; AddRange(new Drawable[] { new VolumeControlReceptor From e7e822ecd57c9211fa9c749569e6064eb1a922ca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Aug 2017 16:37:43 +0900 Subject: [PATCH 59/72] Fix StableStorage having "Songs" in the path twice --- osu.Desktop/OsuGameDesktop.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index f1427d2861..88c8a206c8 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -51,6 +51,8 @@ namespace osu.Desktop { protected override string LocateBasePath() { + Func checkExists = p => Directory.Exists(Path.Combine(p, "Songs")); + string stableInstallPath; try @@ -58,19 +60,19 @@ namespace osu.Desktop using (RegistryKey key = Registry.ClassesRoot.OpenSubKey("osu")) stableInstallPath = key?.OpenSubKey(@"shell\open\command")?.GetValue(String.Empty).ToString().Split('"')[1].Replace("osu!.exe", ""); - if (Directory.Exists(stableInstallPath)) + if (checkExists(stableInstallPath)) return stableInstallPath; } catch { } - stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!", "Songs"); - if (Directory.Exists(stableInstallPath)) + stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!"); + if (checkExists(stableInstallPath)) return stableInstallPath; - stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".osu", "Songs"); - if (Directory.Exists(stableInstallPath)) + stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".osu"); + if (checkExists(stableInstallPath)) return stableInstallPath; return null; From 3b1166d1e665594d0cc24f8b3d1ef010928ec70f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Aug 2017 17:37:21 +0900 Subject: [PATCH 60/72] Optimise file lookups and other database operations FirstOrDefault when called on a TableQuery with a predicate doesn't use table indices --- osu.Game/Beatmaps/BeatmapManager.cs | 4 ++-- osu.Game/Database/DatabaseBackedStore.cs | 2 +- osu.Game/IO/FileStore.cs | 12 +++++------- osu.Game/Rulesets/RulesetStore.cs | 2 +- osu.sln.DotSettings | 2 +- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 6059db0a36..105c8d9623 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -174,7 +174,7 @@ namespace osu.Game.Beatmaps if (!beatmaps.Delete(beatmapSet)) return; if (!beatmapSet.Protected) - files.Dereference(beatmapSet.Files.Select(f => f.FileInfo)); + files.Dereference(beatmapSet.Files.Select(f => f.FileInfo).ToArray()); } /// @@ -188,7 +188,7 @@ namespace osu.Game.Beatmaps if (!beatmaps.Undelete(beatmapSet)) return; if (!beatmapSet.Protected) - files.Reference(beatmapSet.Files.Select(f => f.FileInfo)); + files.Reference(beatmapSet.Files.Select(f => f.FileInfo).ToArray()); } /// diff --git a/osu.Game/Database/DatabaseBackedStore.cs b/osu.Game/Database/DatabaseBackedStore.cs index e3afd9688a..d8e2e35bd7 100644 --- a/osu.Game/Database/DatabaseBackedStore.cs +++ b/osu.Game/Database/DatabaseBackedStore.cs @@ -41,7 +41,7 @@ namespace osu.Game.Database { var storeName = GetType().Name; - var reportedVersion = Connection.Table().FirstOrDefault(s => s.StoreName == storeName) ?? new StoreVersion + var reportedVersion = Connection.Table().Where(s => s.StoreName == storeName).FirstOrDefault() ?? new StoreVersion { StoreName = storeName, Version = 0 diff --git a/osu.Game/IO/FileStore.cs b/osu.Game/IO/FileStore.cs index e55af2e23a..8097f1f3a3 100644 --- a/osu.Game/IO/FileStore.cs +++ b/osu.Game/IO/FileStore.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; using System.IO; using System.Linq; using osu.Framework.Extensions; @@ -83,10 +82,9 @@ namespace osu.Game.IO { string hash = data.ComputeSHA2Hash(); - var info = new FileInfo { Hash = hash }; - - var existing = Connection.Table().FirstOrDefault(f => f.Hash == info.Hash); + var existing = Connection.Table().Where(f => f.Hash == hash).FirstOrDefault(); + var info = existing ?? new FileInfo { Hash = hash }; if (existing != null) { info = existing; @@ -106,11 +104,11 @@ namespace osu.Game.IO Connection.Insert(info); } - Reference(new[] { info }); + Reference(info); return info; } - public void Reference(IEnumerable files) + public void Reference(params FileInfo[] files) { Connection.RunInTransaction(() => { @@ -125,7 +123,7 @@ namespace osu.Game.IO }); } - public void Dereference(IEnumerable files) + public void Dereference(params FileInfo[] files) { Connection.RunInTransaction(() => { diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index 88aee2bffc..1564df1366 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -62,7 +62,7 @@ namespace osu.Game.Rulesets { var us = createRulesetInfo(r); - var existing = Query().FirstOrDefault(ri => ri.InstantiationInfo == us.InstantiationInfo); + var existing = Query().Where(ri => ri.InstantiationInfo == us.InstantiationInfo).FirstOrDefault(); if (existing == null) Connection.Insert(us); diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index e3eae96ca8..06d160ad31 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -115,7 +115,7 @@ WARNING WARNING WARNING - WARNING + HINT WARNING WARNING WARNING From 6eb960010f9086057dcb600131d7f770b363ec89 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Aug 2017 17:58:21 +0900 Subject: [PATCH 61/72] Speed up startup cleanup operations. --- osu.Game/Beatmaps/BeatmapStore.cs | 19 +++---------------- osu.Game/IO/FileStore.cs | 21 ++++++++++++--------- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapStore.cs b/osu.Game/Beatmaps/BeatmapStore.cs index 97cfdcf31b..2ec9a7d759 100644 --- a/osu.Game/Beatmaps/BeatmapStore.cs +++ b/osu.Game/Beatmaps/BeatmapStore.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using osu.Framework.Logging; using osu.Game.Database; using SQLite.Net; using SQLiteNetExtensions.Extensions; @@ -130,23 +129,11 @@ namespace osu.Game.Beatmaps private void cleanupPendingDeletions() { - foreach (var b in QueryAndPopulate(b => b.DeletePending && !b.Protected)) + Connection.RunInTransaction(() => { - try - { - // many-to-many join table entries are not automatically tidied. - Connection.Table().Delete(f => f.BeatmapSetInfoID == b.ID); + foreach (var b in QueryAndPopulate(b => b.DeletePending && !b.Protected)) Connection.Delete(b, true); - } - catch (Exception e) - { - Logger.Error(e, $@"Could not delete beatmap {b}"); - } - } - - //this is required because sqlite migrations don't work, initially inserting nulls into this field. - //see https://github.com/praeclarum/sqlite-net/issues/326 - Connection.Query("UPDATE BeatmapSetInfo SET DeletePending = 0 WHERE DeletePending IS NULL"); + }); } } } diff --git a/osu.Game/IO/FileStore.cs b/osu.Game/IO/FileStore.cs index 8097f1f3a3..1011fa3236 100644 --- a/osu.Game/IO/FileStore.cs +++ b/osu.Game/IO/FileStore.cs @@ -140,18 +140,21 @@ namespace osu.Game.IO private void deletePending() { - foreach (var f in QueryAndPopulate(f => f.ReferenceCount < 1)) + Connection.RunInTransaction(() => { - try + foreach (var f in Query(f => f.ReferenceCount < 1)) { - Connection.Delete(f); - Storage.Delete(Path.Combine(prefix, f.StoragePath)); + try + { + Storage.Delete(Path.Combine(prefix, f.StoragePath)); + Connection.Delete(f); + } + catch (Exception e) + { + Logger.Error(e, $@"Could not delete beatmap {f}"); + } } - catch (Exception e) - { - Logger.Error(e, $@"Could not delete beatmap {f}"); - } - } + }); } } } \ No newline at end of file From 4d8e5898fd9494a219e57b74284242f80f1f971d Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Tue, 1 Aug 2017 17:28:18 +0200 Subject: [PATCH 62/72] Updates according to the framework and formatting --- osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs | 8 ++++---- osu.Game/Graphics/UserInterface/IconButton.cs | 2 +- osu.Game/Overlays/Music/PlaylistOverlay.cs | 3 --- osu.Game/Overlays/MusicController.cs | 2 +- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs b/osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs index 346c826d5e..292e31de75 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseMusicController.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 osu.Framework.Testing; +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; using osu.Framework.Timing; using osu.Game; using osu.Game.Beatmaps; using osu.Game.Overlays; -using osu.Framework.Allocation; -using osu.Framework.Configuration; -using osu.Framework.Graphics.Containers; namespace osu.Desktop.VisualTests.Tests { diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 110a955780..d58a1b2742 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -81,7 +81,7 @@ namespace osu.Game.Graphics.UserInterface hover.Colour = colours.Yellow.Opacity(0.6f); flashColour = colours.Yellow; - Enabled.ValueChanged += newEnabled => FadeColour(newEnabled ? Color4.White : colours.Gray9, 200, EasingTypes.OutQuint); + Enabled.ValueChanged += newEnabled => this.FadeColour(newEnabled ? Color4.White : colours.Gray9, 200, Easing.OutQuint); } protected override bool OnHover(InputState state) diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 5bbaa1b1ae..942633b35e 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; -using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Input; using osu.Framework.Graphics; @@ -15,8 +14,6 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using OpenTK; using OpenTK.Graphics; -using osu.Framework.Input; -using osu.Framework.Graphics.Shapes; namespace osu.Game.Overlays.Music { diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index d53641ec78..d970089942 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -12,6 +12,7 @@ using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.UserInterface; @@ -23,7 +24,6 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Music; using osu.Game.Graphics.UserInterface; -using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Containers; namespace osu.Game.Overlays From 256daeaf68b4334c11313155bbb8e2a395e33456 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Aug 2017 11:56:29 +0900 Subject: [PATCH 63/72] Rename variable --- osu.Game/Graphics/UserInterface/IconButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index d58a1b2742..c073486713 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -81,7 +81,7 @@ namespace osu.Game.Graphics.UserInterface hover.Colour = colours.Yellow.Opacity(0.6f); flashColour = colours.Yellow; - Enabled.ValueChanged += newEnabled => this.FadeColour(newEnabled ? Color4.White : colours.Gray9, 200, Easing.OutQuint); + Enabled.ValueChanged += enabled => this.FadeColour(enabled ? Color4.White : colours.Gray9, 200, Easing.OutQuint); } protected override bool OnHover(InputState state) From 7cb87c7145129a58fd9d2102b5f27faeb30d2441 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Aug 2017 14:18:35 +0900 Subject: [PATCH 64/72] Run each import in a single transaction Improves performance substantially. --- osu.Game/Beatmaps/BeatmapManager.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 105c8d9623..bbb6c975d0 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -47,6 +47,8 @@ namespace osu.Game.Beatmaps private readonly FileStore files; + private readonly SQLiteConnection connection; + private readonly RulesetStore rulesets; private readonly BeatmapStore beatmaps; @@ -72,6 +74,7 @@ namespace osu.Game.Beatmaps this.storage = storage; this.files = files; + this.connection = connection; this.rulesets = rulesets; if (importHost != null) @@ -141,13 +144,13 @@ namespace osu.Game.Beatmaps /// The beatmap to be imported. public BeatmapSetInfo Import(ArchiveReader archiveReader) { + BeatmapSetInfo set = null; + // let's only allow one concurrent import at a time for now. lock (importLock) - { - BeatmapSetInfo set = importToStorage(archiveReader); - Import(set); - return set; - } + connection.RunInTransaction(() => Import(set = importToStorage(archiveReader))); + + return set; } /// From 2c1767e496c518d4c1e2019893c79d2e3700e64b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Aug 2017 16:37:20 +0900 Subject: [PATCH 65/72] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 2204764944..96daf2053a 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 2204764944ff693e857649253547054cc91764a0 +Subproject commit 96daf2053a8a19fe221fef2557674ca5bee808fb From 79724e80181bc94d3f4aab2da3d1c1adeb072da8 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Wed, 2 Aug 2017 16:05:09 +0200 Subject: [PATCH 66/72] Fix OsuLegacyDecoder's parser being NULL if no ruleset was specified --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 4c540fa8cf..e1e1e40f37 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -456,6 +456,11 @@ namespace osu.Game.Beatmaps.Formats handleColours(beatmap, line, ref hasCustomColours); break; case Section.HitObjects: + + // If the ruleset wasn't specified, assume the osu!standard ruleset. + if(parser == null) + parser = new Rulesets.Objects.Legacy.Osu.ConvertHitObjectParser(); + var obj = parser.Parse(line); if (obj != null) From be3c7ec5f81643a8c4e82f56e012e37138a7def0 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Wed, 2 Aug 2017 16:17:33 +0200 Subject: [PATCH 67/72] Added missing space --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index e1e1e40f37..433c23284f 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -458,7 +458,7 @@ namespace osu.Game.Beatmaps.Formats case Section.HitObjects: // If the ruleset wasn't specified, assume the osu!standard ruleset. - if(parser == null) + if (parser == null) parser = new Rulesets.Objects.Legacy.Osu.ConvertHitObjectParser(); var obj = parser.Parse(line); From 0d9ea97828c4cf49252087c388ba3548d6ff70a9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Aug 2017 14:36:21 +0900 Subject: [PATCH 68/72] Allow Rulesets to create a non-FontAwesome icon This also - Renames TextAwesome to SpriteIcon. - Removes the default size of "20" from SpriteIcon (now defaults to the underlying texture size). --- .../Tests/TestCaseTextAwesome.cs | 4 +- osu.Desktop/Overlays/VersionManager.cs | 4 +- osu.Game.Rulesets.Catch/CatchRuleset.cs | 3 +- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 5 +- .../Objects/Drawables/DrawableSpinner.cs | 7 +- .../Objects/Drawables/Pieces/SliderBouncer.cs | 7 +- osu.Game.Rulesets.Osu/OsuRuleset.cs | 3 +- .../Drawables/Pieces/SwellSymbolPiece.cs | 6 +- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 3 +- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 17 ++--- .../Containers/ConstrainedIconContainer.cs | 46 ++++++++++++ .../{TextAwesome.cs => SpriteIcon.cs} | 72 +++++++++++++++++-- .../UserInterface/BreadcrumbControl.cs | 6 +- osu.Game/Graphics/UserInterface/IconButton.cs | 8 +-- .../UserInterface/LoadingAnimation.cs | 6 +- .../Graphics/UserInterface/OsuDropdown.cs | 14 ++-- .../Graphics/UserInterface/OsuTabControl.cs | 4 +- .../UserInterface/OsuTabControlCheckbox.cs | 6 +- .../Graphics/UserInterface/SearchTextBox.cs | 5 +- .../Graphics/UserInterface/StarCounter.cs | 6 +- .../Graphics/UserInterface/TwoLayerButton.cs | 6 +- osu.Game/Online/Multiplayer/GameType.cs | 15 ++-- osu.Game/Overlays/Chat/ChannelListItem.cs | 10 +-- osu.Game/Overlays/Chat/ChatTabControl.cs | 12 ++-- osu.Game/Overlays/Dialog/PopupDialog.cs | 10 +-- osu.Game/Overlays/Direct/DirectListPanel.cs | 7 +- osu.Game/Overlays/Direct/DirectPanel.cs | 4 +- osu.Game/Overlays/Direct/FilterControl.cs | 16 +++-- .../Overlays/Music/CollectionsDropdown.cs | 2 +- osu.Game/Overlays/Music/PlaylistItem.cs | 10 +-- .../Overlays/Notifications/Notification.cs | 4 +- .../Notifications/SimpleNotification.cs | 7 +- osu.Game/Overlays/Profile/ProfileHeader.cs | 4 +- .../SearchableList/DisplayStyleControl.cs | 7 +- .../SearchableList/SearchableListHeader.cs | 4 +- .../SearchableList/SlimEnumDropdown.cs | 3 +- .../Sections/General/LoginSettings.cs | 8 +-- osu.Game/Overlays/Settings/SettingsFooter.cs | 11 +-- osu.Game/Overlays/Settings/SidebarButton.cs | 8 +-- osu.Game/Overlays/Toolbar/ToolbarButton.cs | 26 +++++-- .../Overlays/Toolbar/ToolbarChatButton.cs | 2 +- .../Overlays/Toolbar/ToolbarModeButton.cs | 13 ++-- osu.Game/Rulesets/Ruleset.cs | 3 +- osu.Game/Rulesets/UI/ModIcon.cs | 13 ++-- osu.Game/Screens/Menu/Button.cs | 6 +- osu.Game/Screens/Menu/Disclaimer.cs | 6 +- osu.Game/Screens/Play/SkipButton.cs | 6 +- osu.Game/Screens/Ranking/ResultModeButton.cs | 4 +- osu.Game/Screens/ScreenWhiteBox.cs | 6 +- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 8 +-- osu.Game/Screens/Select/FilterControl.cs | 2 +- .../Select/Leaderboards/LeaderboardScore.cs | 14 ++-- .../Select/Options/BeatmapOptionsButton.cs | 6 +- osu.Game/Users/UserPanel.cs | 6 +- osu.Game/osu.Game.csproj | 3 +- 55 files changed, 317 insertions(+), 187 deletions(-) create mode 100644 osu.Game/Graphics/Containers/ConstrainedIconContainer.cs rename osu.Game/Graphics/{TextAwesome.cs => SpriteIcon.cs} (90%) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTextAwesome.cs b/osu.Desktop.VisualTests/Tests/TestCaseTextAwesome.cs index 2824c0416f..504b59f007 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseTextAwesome.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseTextAwesome.cs @@ -31,10 +31,10 @@ namespace osu.Desktop.VisualTests.Tests int i = 50; foreach (FontAwesome fa in Enum.GetValues(typeof(FontAwesome))) { - flow.Add(new TextAwesome + flow.Add(new SpriteIcon { Icon = fa, - TextSize = 60, + Size = new Vector2(60), Colour = new Color4( Math.Max(0.5f, RNG.NextSingle()), Math.Max(0.5f, RNG.NextSingle()), diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index 6983c51c7d..18fa43ab5c 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -209,13 +209,13 @@ namespace osu.Desktop.Overlays RelativeSizeAxes = Axes.Both, Colour = ColourInfo.GradientVertical(colours.YellowDark, colours.Yellow) }, - new TextAwesome + new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, Icon = FontAwesome.fa_upload, Colour = Color4.White, - TextSize = 20 + Size = new Vector2(20), } }); } diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index df212f7df7..ee29f970bb 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -10,6 +10,7 @@ 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.Catch.Scoring; using osu.Game.Rulesets.Scoring; @@ -85,7 +86,7 @@ namespace osu.Game.Rulesets.Catch public override string Description => "osu!catch"; - public override FontAwesome Icon => FontAwesome.fa_osu_fruits_o; + public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o }; public override IEnumerable CreateGameplayKeys() => new KeyCounter[] { diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 8be3870ebe..0349427784 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -2,13 +2,14 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Game.Beatmaps; -using osu.Game.Graphics; using osu.Game.Rulesets.Mania.Mods; using osu.Game.Rulesets.Mania.UI; 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.Graphics; using osu.Game.Rulesets.Mania.Scoring; using osu.Game.Rulesets.Scoring; @@ -106,7 +107,7 @@ namespace osu.Game.Rulesets.Mania public override string Description => "osu!mania"; - public override FontAwesome Icon => FontAwesome.fa_osu_mania_o; + public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o }; public override IEnumerable CreateGameplayKeys() => new KeyCounter[] { /* Todo: Should be keymod specific */ }; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 2aae1bb24e..4a0b8422f1 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly CirclePiece circle; private readonly GlowPiece glow; - private readonly TextAwesome symbol; + private readonly SpriteIcon symbol; private readonly Color4 baseColour = OsuColour.FromHex(@"002c3c"); private readonly Color4 fillColour = OsuColour.FromHex(@"005b7c"); @@ -64,12 +64,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Anchor = Anchor.Centre, }, new RingPiece(), - symbol = new TextAwesome + symbol = new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, - UseFullGlyphHeight = true, - TextSize = 48, + Size = new Vector2(48), Icon = FontAwesome.fa_asterisk, Shadow = false, }, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs index 10d14b5485..942f166241 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs @@ -4,6 +4,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; +using OpenTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { @@ -11,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { private readonly Slider slider; private readonly bool isEnd; - private readonly TextAwesome icon; + private readonly SpriteIcon icon; public SliderBouncer(Slider slider, bool isEnd) { @@ -24,12 +25,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Children = new Drawable[] { - icon = new TextAwesome + icon = new SpriteIcon { Icon = FontAwesome.fa_eercast, Anchor = Anchor.Centre, Origin = Anchor.Centre, - TextSize = 48, + Size = new Vector2(48), } }; } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 8e8e186d40..da32b49262 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -13,6 +13,7 @@ using osu.Game.Rulesets.UI; using osu.Game.Screens.Play; using System.Collections.Generic; using System.Linq; +using osu.Framework.Graphics; using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Scoring; using osu.Game.Overlays.Settings; @@ -104,7 +105,7 @@ namespace osu.Game.Rulesets.Osu } } - public override FontAwesome Icon => FontAwesome.fa_osu_osu_o; + 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/Objects/Drawables/Pieces/SwellSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs index 0f703837a9..5a9ee36021 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs @@ -3,20 +3,20 @@ using osu.Framework.Graphics; using osu.Game.Graphics; +using OpenTK; namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces { /// /// The symbol used for swell pieces. /// - public class SwellSymbolPiece : TextAwesome + public class SwellSymbolPiece : SpriteIcon { public SwellSymbolPiece() { Anchor = Anchor.Centre; Origin = Anchor.Centre; - UseFullGlyphHeight = true; - TextSize = CirclePiece.SYMBOL_INNER_SIZE; + Size = new Vector2(CirclePiece.SYMBOL_INNER_SIZE); Icon = FontAwesome.fa_asterisk; Shadow = false; } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 303d936fb9..27b4cffbaf 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -10,6 +10,7 @@ using osu.Game.Rulesets.Taiko.UI; 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.Rulesets.Taiko.Scoring; @@ -85,7 +86,7 @@ namespace osu.Game.Rulesets.Taiko public override string Description => "osu!taiko"; - public override FontAwesome Icon => FontAwesome.fa_osu_taiko_o; + public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o }; public override IEnumerable CreateGameplayKeys() => new KeyCounter[] { diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index f61380bfb8..42db025a40 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -4,8 +4,8 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using OpenTK; -using OpenTK.Graphics; namespace osu.Game.Beatmaps.Drawables { @@ -22,23 +22,20 @@ namespace osu.Game.Beatmaps.Drawables [BackgroundDependencyLoader] private void load() { - Children = new[] + Children = new Drawable[] { - new TextAwesome + new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, - TextSize = Size.X, + RelativeSizeAxes = Axes.Both, Colour = AccentColour, Icon = FontAwesome.fa_circle }, - new TextAwesome + new ConstrainedIconContainer { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - TextSize = Size.X, - Colour = Color4.White, - Icon = beatmap.Ruleset.CreateInstance().Icon + RelativeSizeAxes = Axes.Both, + Icon = beatmap.Ruleset.CreateInstance().CreateIcon() } }; } diff --git a/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs b/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs new file mode 100644 index 0000000000..135786e1c5 --- /dev/null +++ b/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs @@ -0,0 +1,46 @@ +// 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 OpenTK; + +namespace osu.Game.Graphics.Containers +{ + /// + /// Display an icon that is constrained to a physical region on screen. + /// + public class ConstrainedIconContainer : Container + { + public Drawable Icon + { + get + { + return InternalChild; + } + + set + { + InternalChild = value; + } + } + + protected override void Update() + { + base.Update(); + if (InternalChildren.Count > 0 && InternalChild.DrawSize.X > 0) + { + var fitScale = Math.Min(DrawSize.X / InternalChild.DrawSize.X, DrawSize.Y / InternalChild.DrawSize.Y); + InternalChild.Scale = new Vector2(fitScale); + InternalChild.Anchor = Anchor.Centre; + InternalChild.Origin = Anchor.Centre; + } + } + + public ConstrainedIconContainer() + { + Masking = true; + } + } +} diff --git a/osu.Game/Graphics/TextAwesome.cs b/osu.Game/Graphics/SpriteIcon.cs similarity index 90% rename from osu.Game/Graphics/TextAwesome.cs rename to osu.Game/Graphics/SpriteIcon.cs index 69b0217444..7f717cac3c 100644 --- a/osu.Game/Graphics/TextAwesome.cs +++ b/osu.Game/Graphics/SpriteIcon.cs @@ -1,13 +1,76 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Graphics.Sprites; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics; +using osu.Framework.IO.Stores; +using OpenTK; +using OpenTK.Graphics; namespace osu.Game.Graphics { - public class TextAwesome : OsuSpriteText + public class SpriteIcon : CompositeDrawable { - //public override FontFace FontFace => (int)Icon < 0xf000 ? FontFace.OsuFont : FontFace.FontAwesome; + private readonly Sprite spriteShadow; + private readonly Sprite spriteMain; + + public SpriteIcon() + { + InternalChildren = new[] + { + spriteShadow = new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit, + Position = new Vector2(0, 0.06f), + Colour = new Color4(0f, 0f, 0f, 0.2f), + Alpha = 0 + }, + spriteMain = new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit + }, + }; + } + + private FontStore store; + + [BackgroundDependencyLoader] + private void load(FontStore store) + { + this.store = store; + updateTexture(); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + if (Size.X == 0) throw new System.Exception("size required"); + } + + private void updateTexture() + { + var texture = store?.Get(((char)icon).ToString()); + + spriteMain.Texture = texture; + spriteShadow.Texture = texture; + + if (Size == Vector2.Zero) + Size = new Vector2(texture?.DisplayWidth ?? 0, texture?.DisplayHeight ?? 0); + } + + public bool Shadow + { + get { return spriteShadow.IsPresent; } + set { spriteShadow.Alpha = value ? 1 : 0; } + } private FontAwesome icon; @@ -23,7 +86,8 @@ namespace osu.Game.Graphics if (icon == value) return; icon = value; - Text = ((char)icon).ToString(); + if (IsLoaded) + updateTexture(); } } } diff --git a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs index f61192a1a6..b3e53280fb 100644 --- a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs @@ -35,7 +35,7 @@ namespace osu.Game.Graphics.UserInterface private class BreadcrumbTabItem : OsuTabItem, IStateful { - public readonly TextAwesome Chevron; + public readonly SpriteIcon Chevron; //don't allow clicking between transitions and don't make the chevron clickable public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => Alpha == 1f && Text.ReceiveMouseInputAt(screenSpacePos); @@ -69,11 +69,11 @@ namespace osu.Game.Graphics.UserInterface { Text.TextSize = 16; Padding = new MarginPadding { Right = padding + 8 }; //padding + chevron width - Add(Chevron = new TextAwesome + Add(Chevron = new SpriteIcon { Anchor = Anchor.CentreRight, Origin = Anchor.CentreLeft, - TextSize = 12, + Size = new Vector2(12), Icon = FontAwesome.fa_chevron_right, Margin = new MarginPadding { Left = padding }, Alpha = 0f, diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index c073486713..1808dc4b6c 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -15,7 +15,7 @@ namespace osu.Game.Graphics.UserInterface { public class IconButton : OsuClickableContainer { - private readonly TextAwesome icon; + private readonly SpriteIcon icon; private readonly Box hover; private readonly Container content; @@ -47,7 +47,7 @@ namespace osu.Game.Graphics.UserInterface { Origin = Anchor.Centre, Anchor = Anchor.Centre, - Size = new Vector2 (button_size), + Size = new Vector2(button_size), CornerRadius = 5, Masking = true, @@ -64,11 +64,11 @@ namespace osu.Game.Graphics.UserInterface RelativeSizeAxes = Axes.Both, Alpha = 0, }, - icon = new TextAwesome + icon = new SpriteIcon { Origin = Anchor.Centre, Anchor = Anchor.Centre, - TextSize = 18, + Size = new Vector2(18), } } } diff --git a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs index 56ee47a7e6..eb8ff5be86 100644 --- a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs +++ b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs @@ -9,7 +9,7 @@ namespace osu.Game.Graphics.UserInterface { public class LoadingAnimation : VisibilityContainer { - private readonly TextAwesome spinner; + private readonly SpriteIcon spinner; public LoadingAnimation() { @@ -20,9 +20,9 @@ namespace osu.Game.Graphics.UserInterface Children = new Drawable[] { - spinner = new TextAwesome + spinner = new SpriteIcon { - TextSize = 20, + Size = new Vector2(20), Anchor = Anchor.Centre, Origin = Anchor.Centre, Icon = FontAwesome.fa_spinner diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index 6dadd63ac4..f5a4219707 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.Sprites; +using OpenTK; namespace osu.Game.Graphics.UserInterface { @@ -60,14 +61,13 @@ namespace osu.Game.Graphics.UserInterface AutoSizeAxes = Axes.Y, Children = new Drawable[] { - Chevron = new TextAwesome + Chevron = new SpriteIcon { AlwaysPresent = true, Icon = FontAwesome.fa_chevron_right, - UseFullGlyphHeight = false, Colour = Color4.Black, Alpha = 0.5f, - TextSize = 8, + Size = new Vector2(8), Margin = new MarginPadding { Left = 3, Right = 3 }, Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, @@ -84,7 +84,7 @@ namespace osu.Game.Graphics.UserInterface private Color4? accentColour; - protected readonly TextAwesome Chevron; + protected readonly SpriteIcon Chevron; protected readonly OsuSpriteText Label; protected override void FormatForeground(bool hover = false) @@ -123,7 +123,7 @@ namespace osu.Game.Graphics.UserInterface set { Text.Text = value; } } - protected readonly TextAwesome Icon; + protected readonly SpriteIcon Icon; private Color4? accentColour; public virtual Color4 AccentColour @@ -152,13 +152,13 @@ namespace osu.Game.Graphics.UserInterface Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, }, - Icon = new TextAwesome + Icon = new SpriteIcon { Icon = FontAwesome.fa_chevron_down, Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Margin = new MarginPadding { Right = 4 }, - TextSize = 20 + Size = new Vector2(20), } }; } diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 8c16c048ea..5ad412965c 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -209,10 +209,10 @@ namespace osu.Game.Graphics.UserInterface Foreground.Children = new Drawable[] { - new TextAwesome + new SpriteIcon { Icon = FontAwesome.fa_ellipsis_h, - TextSize = 14, + Size = new Vector2(14), Origin = Anchor.Centre, Anchor = Anchor.Centre, } diff --git a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs index 57a87dc74b..a0d48e5ebe 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs @@ -21,7 +21,7 @@ namespace osu.Game.Graphics.UserInterface { private readonly Box box; private readonly SpriteText text; - private readonly TextAwesome icon; + private readonly SpriteIcon icon; private Color4? accentColour; public Color4 AccentColour @@ -99,9 +99,9 @@ namespace osu.Game.Graphics.UserInterface TextSize = 14, Font = @"Exo2.0-Bold", }, - icon = new TextAwesome + icon = new SpriteIcon { - TextSize = 14, + Size = new Vector2(14), Icon = FontAwesome.fa_circle_o, Shadow = true, }, diff --git a/osu.Game/Graphics/UserInterface/SearchTextBox.cs b/osu.Game/Graphics/UserInterface/SearchTextBox.cs index 0d852e4276..f39cdf5d24 100644 --- a/osu.Game/Graphics/UserInterface/SearchTextBox.cs +++ b/osu.Game/Graphics/UserInterface/SearchTextBox.cs @@ -3,6 +3,7 @@ using osu.Framework.Graphics; using osu.Framework.Input; +using OpenTK; using OpenTK.Input; namespace osu.Game.Graphics.UserInterface @@ -19,13 +20,13 @@ namespace osu.Game.Graphics.UserInterface Height = 35; AddRange(new Drawable[] { - new TextAwesome + new SpriteIcon { Icon = FontAwesome.fa_search, Origin = Anchor.CentreRight, Anchor = Anchor.CentreRight, Margin = new MarginPadding { Right = 10 }, - TextSize = 20 + Size = new Vector2(20), } }); diff --git a/osu.Game/Graphics/UserInterface/StarCounter.cs b/osu.Game/Graphics/UserInterface/StarCounter.cs index 6c5204fed4..e581d19d54 100644 --- a/osu.Game/Graphics/UserInterface/StarCounter.cs +++ b/osu.Game/Graphics/UserInterface/StarCounter.cs @@ -142,16 +142,16 @@ namespace osu.Game.Graphics.UserInterface private class Star : Container { - public readonly TextAwesome Icon; + public readonly SpriteIcon Icon; public Star() { Size = new Vector2(star_size); Children = new[] { - Icon = new TextAwesome + Icon = new SpriteIcon { - TextSize = star_size, + Size = new Vector2(star_size), Icon = FontAwesome.fa_star, Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs index f290f4fadd..f17b307826 100644 --- a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs +++ b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs @@ -215,7 +215,7 @@ namespace osu.Game.Graphics.UserInterface { private const double beat_in_time = 60; - private readonly TextAwesome icon; + private readonly SpriteIcon icon; public FontAwesome Icon { set { icon.Icon = value; } } @@ -226,11 +226,11 @@ namespace osu.Game.Graphics.UserInterface Children = new Drawable[] { - icon = new TextAwesome + icon = new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, - TextSize = 25 + Size = new Vector2(25), } }; } diff --git a/osu.Game/Online/Multiplayer/GameType.cs b/osu.Game/Online/Multiplayer/GameType.cs index 22e2ffac31..c94b409d1b 100644 --- a/osu.Game/Online/Multiplayer/GameType.cs +++ b/osu.Game/Online/Multiplayer/GameType.cs @@ -21,15 +21,14 @@ namespace osu.Game.Online.Multiplayer public override string Name => "Tag"; public override Drawable GetIcon(OsuColour colours, float size) { - return new TextAwesome + return new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, Icon = FontAwesome.fa_refresh, - TextSize = size, + Size = new Vector2(size), Colour = colours.Blue, Shadow = false, - UseFullGlyphHeight = false, }; } } @@ -61,21 +60,19 @@ namespace osu.Game.Online.Multiplayer Spacing = new Vector2(2f), Children = new[] { - new TextAwesome + new SpriteIcon { Icon = FontAwesome.fa_refresh, - TextSize = size * 0.75f, + Size = new Vector2(size * 0.75f), Colour = colours.Blue, Shadow = false, - UseFullGlyphHeight = false, }, - new TextAwesome + new SpriteIcon { Icon = FontAwesome.fa_refresh, - TextSize = size * 0.75f, + Size = new Vector2(size * 0.75f), Colour = colours.Pink, Shadow = false, - UseFullGlyphHeight = false, }, }, }; diff --git a/osu.Game/Overlays/Chat/ChannelListItem.cs b/osu.Game/Overlays/Chat/ChannelListItem.cs index 791377187b..f43154ea20 100644 --- a/osu.Game/Overlays/Chat/ChannelListItem.cs +++ b/osu.Game/Overlays/Chat/ChannelListItem.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Chat private readonly Bindable joinedBind = new Bindable(); private readonly OsuSpriteText name; private readonly OsuSpriteText topic; - private readonly TextAwesome joinedCheckmark; + private readonly SpriteIcon joinedCheckmark; private Color4 joinedColour; private Color4 topicColour; @@ -68,12 +68,12 @@ namespace osu.Game.Overlays.Chat { Children = new[] { - joinedCheckmark = new TextAwesome + joinedCheckmark = new SpriteIcon { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Icon = FontAwesome.fa_check_circle, - TextSize = text_size, + Size = new Vector2(text_size), Shadow = false, Margin = new MarginPadding { Right = 10f }, Alpha = 0f, @@ -121,10 +121,10 @@ namespace osu.Game.Overlays.Chat Spacing = new Vector2(3f, 0f), Children = new Drawable[] { - new TextAwesome + new SpriteIcon { Icon = FontAwesome.fa_user, - TextSize = text_size - 2, + Size = new Vector2(text_size - 2), Shadow = false, Margin = new MarginPadding { Top = 1 }, }, diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index c3c930eba0..4ff9169877 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -35,13 +35,13 @@ namespace osu.Game.Overlays.Chat TabContainer.Spacing = new Vector2(-shear_width, 0); TabContainer.Masking = false; - AddInternal(new TextAwesome + AddInternal(new SpriteIcon { Icon = FontAwesome.fa_comments, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - TextSize = 20, - Padding = new MarginPadding(10), + Size = new Vector2(20), + Margin = new MarginPadding(10), }); AddTabItem(selectorTab = new ChannelTabItem.ChannelSelectorTabItem(new Channel { Name = "+" })); @@ -72,7 +72,7 @@ namespace osu.Game.Overlays.Chat private readonly SpriteText textBold; private readonly Box box; private readonly Box highlightBox; - private readonly TextAwesome icon; + private readonly SpriteIcon icon; private void updateState() { @@ -176,7 +176,7 @@ namespace osu.Game.Overlays.Chat RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - icon = new TextAwesome + icon = new SpriteIcon { Icon = FontAwesome.fa_hashtag, Anchor = Anchor.CentreLeft, @@ -184,7 +184,7 @@ namespace osu.Game.Overlays.Chat Colour = Color4.Black, X = -10, Alpha = 0.2f, - TextSize = ChatOverlay.TAB_AREA_HEIGHT, + Size = new Vector2(ChatOverlay.TAB_AREA_HEIGHT), }, text = new OsuSpriteText { diff --git a/osu.Game/Overlays/Dialog/PopupDialog.cs b/osu.Game/Overlays/Dialog/PopupDialog.cs index 97aae2f49c..9b19b8150e 100644 --- a/osu.Game/Overlays/Dialog/PopupDialog.cs +++ b/osu.Game/Overlays/Dialog/PopupDialog.cs @@ -30,14 +30,14 @@ namespace osu.Game.Overlays.Dialog private readonly Container content; private readonly Container ring; private readonly FillFlowContainer buttonsContainer; - private readonly TextAwesome iconText; + private readonly SpriteIcon icon; private readonly SpriteText header; private readonly SpriteText body; public FontAwesome Icon { - get { return iconText.Icon; } - set { iconText.Icon = value; } + get { return icon.Icon; } + set { icon.Icon = value; } } public string HeaderText @@ -205,12 +205,12 @@ namespace osu.Game.Overlays.Dialog RelativeSizeAxes = Axes.Both, Colour = Color4.Black.Opacity(0), }, - iconText = new TextAwesome + icon = new SpriteIcon { Origin = Anchor.Centre, Anchor = Anchor.Centre, Icon = FontAwesome.fa_close, - TextSize = 50, + Size = new Vector2(50), }, }, }, diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index b9063a5c82..5b45fc7725 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -152,18 +152,17 @@ namespace osu.Game.Overlays.Direct private class DownloadButton : OsuClickableContainer { - private readonly TextAwesome icon; + private readonly SpriteIcon icon; public DownloadButton() { Children = new Drawable[] { - icon = new TextAwesome + icon = new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, - UseFullGlyphHeight = false, - TextSize = 30, + Size = new Vector2(30), Icon = FontAwesome.fa_osu_chevron_down_o, }, }; diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 75619d9ba4..2f048b0e3d 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -75,11 +75,11 @@ namespace osu.Game.Overlays.Direct { Font = @"Exo2.0-SemiBoldItalic", }, - new TextAwesome + new SpriteIcon { Icon = icon, Shadow = true, - TextSize = 14, + Size = new Vector2(14), Margin = new MarginPadding { Top = 1 }, }, }; diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index 4f815f220c..28d26d0641 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -47,7 +47,11 @@ namespace osu.Game.Overlays.Direct private class RulesetToggleButton : OsuClickableContainer { - private readonly TextAwesome icon; + private Drawable icon + { + get { return iconContainer.Icon; } + set { iconContainer.Icon = value; } + } private RulesetInfo ruleset; public RulesetInfo Ruleset @@ -56,15 +60,17 @@ namespace osu.Game.Overlays.Direct set { ruleset = value; - icon.Icon = Ruleset.CreateInstance().Icon; + icon = Ruleset.CreateInstance().CreateIcon(); } } private readonly Bindable bindable; + private readonly ConstrainedIconContainer iconContainer; + private void Bindable_ValueChanged(RulesetInfo obj) { - icon.FadeTo(Ruleset.ID == obj?.ID ? 1f : 0.5f, 100); + iconContainer.FadeTo(Ruleset.ID == obj?.ID ? 1f : 0.5f, 100); } public RulesetToggleButton(Bindable bindable, RulesetInfo ruleset) @@ -74,11 +80,11 @@ namespace osu.Game.Overlays.Direct Children = new[] { - icon = new TextAwesome + iconContainer = new ConstrainedIconContainer { Origin = Anchor.TopLeft, Anchor = Anchor.TopLeft, - TextSize = 32, + Size = new Vector2(32), } }; diff --git a/osu.Game/Overlays/Music/CollectionsDropdown.cs b/osu.Game/Overlays/Music/CollectionsDropdown.cs index f6016fd1db..0c0a636be8 100644 --- a/osu.Game/Overlays/Music/CollectionsDropdown.cs +++ b/osu.Game/Overlays/Music/CollectionsDropdown.cs @@ -36,7 +36,7 @@ namespace osu.Game.Overlays.Music { CornerRadius = 5; Height = 30; - Icon.TextSize = 14; + Icon.Size = new Vector2(14); Icon.Margin = new MarginPadding(0); Foreground.Padding = new MarginPadding { Top = 4, Bottom = 4, Left = 10, Right = 10 }; EdgeEffect = new EdgeEffectParameters diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 1e3e48b17a..4145a8d1f0 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -12,6 +12,7 @@ using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using OpenTK; namespace osu.Game.Overlays.Music { @@ -22,7 +23,7 @@ namespace osu.Game.Overlays.Music private Color4 hoverColour; private Color4 artistColour; - private TextAwesome handle; + private SpriteIcon handle; private TextFlowContainer text; private IEnumerable titleSprites; private UnicodeBindableString titleBind; @@ -67,16 +68,15 @@ namespace osu.Game.Overlays.Music Children = new Drawable[] { - handle = new TextAwesome + handle = new SpriteIcon { Anchor = Anchor.TopLeft, Origin = Anchor.TopLeft, - TextSize = 12, + Size = new Vector2(12), Colour = colours.Gray5, Icon = FontAwesome.fa_bars, Alpha = 0f, - Margin = new MarginPadding { Left = 5 }, - Padding = new MarginPadding { Top = 2 }, + Margin = new MarginPadding { Left = 5, Top = 2 }, }, text = new OsuTextFlowContainer { diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index 49b2823531..14446a468c 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -165,12 +165,12 @@ namespace osu.Game.Overlays.Notifications Children = new[] { - new TextAwesome + new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, Icon = FontAwesome.fa_times_circle, - TextSize = 20 + Size = new Vector2(20), } }; } diff --git a/osu.Game/Overlays/Notifications/SimpleNotification.cs b/osu.Game/Overlays/Notifications/SimpleNotification.cs index 44e6d92aef..e10cc26546 100644 --- a/osu.Game/Overlays/Notifications/SimpleNotification.cs +++ b/osu.Game/Overlays/Notifications/SimpleNotification.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using OpenTK; namespace osu.Game.Overlays.Notifications { @@ -36,7 +37,7 @@ namespace osu.Game.Overlays.Notifications } private readonly SpriteText textDrawable; - private readonly TextAwesome iconDrawable; + private readonly SpriteIcon iconDrawable; protected Box IconBackgound; @@ -49,12 +50,12 @@ namespace osu.Game.Overlays.Notifications RelativeSizeAxes = Axes.Both, Colour = ColourInfo.GradientVertical(OsuColour.Gray(0.2f), OsuColour.Gray(0.6f)) }, - iconDrawable = new TextAwesome + iconDrawable = new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, Icon = icon, - TextSize = 20 + Size = new Vector2(20), } }); diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 93044315cc..77a3449b9c 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -110,12 +110,12 @@ namespace osu.Game.Overlays.Profile Alpha = 0, AlwaysPresent = true }, - new TextAwesome + new SpriteIcon { Icon = FontAwesome.fa_heart, Anchor = Anchor.Centre, Origin = Anchor.Centre, - TextSize = 12 + Size = new Vector2(12), } } }, diff --git a/osu.Game/Overlays/SearchableList/DisplayStyleControl.cs b/osu.Game/Overlays/SearchableList/DisplayStyleControl.cs index 7157861632..9fa266c5fe 100644 --- a/osu.Game/Overlays/SearchableList/DisplayStyleControl.cs +++ b/osu.Game/Overlays/SearchableList/DisplayStyleControl.cs @@ -55,7 +55,7 @@ namespace osu.Game.Overlays.SearchableList private class DisplayStyleToggleButton : OsuClickableContainer { - private readonly TextAwesome icon; + private readonly SpriteIcon icon; private readonly PanelDisplayStyle style; private readonly Bindable bindable; @@ -67,13 +67,12 @@ namespace osu.Game.Overlays.SearchableList Children = new Drawable[] { - this.icon = new TextAwesome + this.icon = new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, Icon = icon, - TextSize = 18, - UseFullGlyphHeight = false, + Size = new Vector2(18), Alpha = 0.5f, }, }; diff --git a/osu.Game/Overlays/SearchableList/SearchableListHeader.cs b/osu.Game/Overlays/SearchableList/SearchableListHeader.cs index af99a39cc4..4239a123b8 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListHeader.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListHeader.cs @@ -55,9 +55,9 @@ namespace osu.Game.Overlays.SearchableList Spacing = new Vector2(10f, 0f), Children = new[] { - new TextAwesome + new SpriteIcon { - TextSize = 25, + Size = new Vector2(25), Icon = Icon, }, CreateHeaderText(), diff --git a/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs b/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs index e2eec0214f..38e3e44911 100644 --- a/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs +++ b/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs @@ -6,6 +6,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; +using OpenTK; namespace osu.Game.Overlays.SearchableList { @@ -19,7 +20,7 @@ namespace osu.Game.Overlays.SearchableList public SlimDropdownHeader() { Height = 25; - Icon.TextSize = 16; + Icon.Size = new Vector2(16); Foreground.Padding = new MarginPadding { Top = 4, Bottom = 4, Left = 8, Right = 4 }; } diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index 6268a9753a..d07f156673 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -286,7 +286,7 @@ namespace osu.Game.Overlays.Settings.Sections.General { public const float LABEL_LEFT_MARGIN = 20; - private readonly TextAwesome statusIcon; + private readonly SpriteIcon statusIcon; public Color4 StatusColour { set @@ -308,15 +308,15 @@ namespace osu.Game.Overlays.Settings.Sections.General Radius = 4, }; - Icon.TextSize = 14; + Icon.Size = new Vector2(14); Icon.Margin = new MarginPadding(0); - Foreground.Add(statusIcon = new TextAwesome + Foreground.Add(statusIcon = new SpriteIcon { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Icon = FontAwesome.fa_circle_o, - TextSize = 14, + Size = new Vector2(14), }); Text.Margin = new MarginPadding { Left = LABEL_LEFT_MARGIN }; diff --git a/osu.Game/Overlays/Settings/SettingsFooter.cs b/osu.Game/Overlays/Settings/SettingsFooter.cs index 6c25b146a1..aef9f071db 100644 --- a/osu.Game/Overlays/Settings/SettingsFooter.cs +++ b/osu.Game/Overlays/Settings/SettingsFooter.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets; using OpenTK; @@ -27,12 +28,14 @@ namespace osu.Game.Overlays.Settings foreach (var ruleset in rulesets.AllRulesets) { - modes.Add(new TextAwesome + var icon = new ConstrainedIconContainer { - Icon = ruleset.CreateInstance().Icon, + Icon = ruleset.CreateInstance().CreateIcon(), Colour = Color4.Gray, - TextSize = 20 - }); + Size = new Vector2(20), + }; + + modes.Add(icon); } Children = new Drawable[] diff --git a/osu.Game/Overlays/Settings/SidebarButton.cs b/osu.Game/Overlays/Settings/SidebarButton.cs index 309216dd91..7af7363dda 100644 --- a/osu.Game/Overlays/Settings/SidebarButton.cs +++ b/osu.Game/Overlays/Settings/SidebarButton.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Settings { public class SidebarButton : Container { - private readonly TextAwesome drawableIcon; + private readonly SpriteIcon drawableIcon; private readonly SpriteText headerText; private readonly Box backgroundBox; private readonly Box selectionIndicator; @@ -77,7 +77,7 @@ namespace osu.Game.Overlays.Settings Width = Sidebar.DEFAULT_WIDTH, RelativeSizeAxes = Axes.Y, Colour = OsuColour.Gray(0.6f), - Children = new[] + Children = new Drawable[] { headerText = new OsuSpriteText { @@ -85,11 +85,11 @@ namespace osu.Game.Overlays.Settings Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, }, - drawableIcon = new TextAwesome + drawableIcon = new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, - TextSize = 20 + Size = new Vector2(20), }, } }, diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index b5e832d381..f2df2721d3 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -20,10 +20,21 @@ namespace osu.Game.Overlays.Toolbar { public const float WIDTH = Toolbar.HEIGHT * 1.4f; + public void SetIcon(Drawable icon) + { + IconContainer.Icon = icon; + IconContainer.Show(); + } + + public void SetIcon(FontAwesome icon) => SetIcon(new SpriteIcon + { + Size = new Vector2(20), + Icon = icon + }); + public FontAwesome Icon { - get { return DrawableIcon.Icon; } - set { DrawableIcon.Icon = value; } + set { SetIcon(value); } } public string Text @@ -55,7 +66,7 @@ namespace osu.Game.Overlays.Toolbar protected virtual Anchor TooltipAnchor => Anchor.TopLeft; - protected TextAwesome DrawableIcon; + protected ConstrainedIconContainer IconContainer; protected SpriteText DrawableText; protected Box HoverBackground; private readonly FillFlowContainer tooltipContainer; @@ -88,11 +99,12 @@ namespace osu.Game.Overlays.Toolbar AutoSizeAxes = Axes.X, Children = new Drawable[] { - DrawableIcon = new TextAwesome + IconContainer = new ConstrainedIconContainer { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - TextSize = 20 + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Size = new Vector2(20), + Alpha = 0, }, DrawableText = new OsuSpriteText { diff --git a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs index 39909b8d5b..2e2786851c 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs @@ -10,7 +10,7 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarChatButton() { - Icon = FontAwesome.fa_comments; + SetIcon(FontAwesome.fa_comments); } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarModeButton.cs index 2c50897e1f..b615cd3303 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeButton.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Toolbar TooltipMain = rInstance.Description; TooltipSub = $"Play some {rInstance.Description}"; - Icon = rInstance.Icon; + SetIcon(rInstance.CreateIcon()); } } @@ -31,9 +31,8 @@ namespace osu.Game.Overlays.Toolbar { if (value) { - DrawableIcon.Colour = Color4.White; - DrawableIcon.Masking = true; - DrawableIcon.EdgeEffect = new EdgeEffectParameters + IconContainer.Colour = Color4.White; + IconContainer.EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Colour = new Color4(255, 194, 224, 100), @@ -43,8 +42,8 @@ namespace osu.Game.Overlays.Toolbar } else { - DrawableIcon.Masking = false; - DrawableIcon.Colour = new Color4(255, 194, 224, 255); + IconContainer.Colour = new Color4(255, 194, 224, 255); + IconContainer.EdgeEffect = new EdgeEffectParameters(); } } } @@ -52,7 +51,7 @@ namespace osu.Game.Overlays.Toolbar protected override void LoadComplete() { base.LoadComplete(); - DrawableIcon.TextSize *= 1.4f; + IconContainer.Scale *= 1.4f; } } } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 3dbb39d894..c5a9155da5 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -7,6 +7,7 @@ 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; @@ -31,7 +32,7 @@ namespace osu.Game.Rulesets public abstract ScoreProcessor CreateScoreProcessor(); - public virtual FontAwesome Icon => FontAwesome.fa_question_circle; + public virtual Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_question_circle }; public abstract string Description { get; } diff --git a/osu.Game/Rulesets/UI/ModIcon.cs b/osu.Game/Rulesets/UI/ModIcon.cs index b23028098f..03705c19e6 100644 --- a/osu.Game/Rulesets/UI/ModIcon.cs +++ b/osu.Game/Rulesets/UI/ModIcon.cs @@ -8,13 +8,14 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; +using OpenTK; namespace osu.Game.Rulesets.UI { public class ModIcon : Container { - private readonly TextAwesome modIcon; - private readonly TextAwesome background; + private readonly SpriteIcon modIcon; + private readonly SpriteIcon background; private const float icon_size = 80; @@ -34,20 +35,20 @@ namespace osu.Game.Rulesets.UI Children = new Drawable[] { - background = new TextAwesome + background = new SpriteIcon { Origin = Anchor.Centre, Anchor = Anchor.Centre, - TextSize = icon_size, + Size = new Vector2(icon_size), Icon = FontAwesome.fa_osu_mod_bg, Shadow = true, }, - modIcon = new TextAwesome + modIcon = new SpriteIcon { Origin = Anchor.Centre, Anchor = Anchor.Centre, Colour = OsuColour.Gray(84), - TextSize = icon_size - 35, + Size = new Vector2(icon_size - 35), Icon = mod.Icon }, }; diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index e55c4ef4fe..0898c079ce 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Menu private readonly Container iconText; private readonly Container box; private readonly Box boxHoverLayer; - private readonly TextAwesome icon; + private readonly SpriteIcon icon; private readonly string sampleName; private readonly Action clickAction; private readonly Key triggerKey; @@ -95,12 +95,12 @@ namespace osu.Game.Screens.Menu Origin = Anchor.Centre, Children = new Drawable[] { - icon = new TextAwesome + icon = new SpriteIcon { Shadow = true, Anchor = Anchor.Centre, Origin = Anchor.Centre, - TextSize = 30, + Size = new Vector2(30), Position = new Vector2(0, 0), Icon = symbol }, diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index 6a176898a2..1ac5823ec4 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -15,7 +15,7 @@ namespace osu.Game.Screens.Menu internal class Disclaimer : OsuScreen { private Intro intro; - private readonly TextAwesome icon; + private readonly SpriteIcon icon; private Color4 iconColour; internal override bool ShowOverlays => false; @@ -37,12 +37,12 @@ namespace osu.Game.Screens.Menu Spacing = new Vector2(0, 2), Children = new Drawable[] { - icon = new TextAwesome + icon = new SpriteIcon { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Icon = FontAwesome.fa_warning, - TextSize = 30, + Size = new Vector2(30), }, new OsuSpriteText { diff --git a/osu.Game/Screens/Play/SkipButton.cs b/osu.Game/Screens/Play/SkipButton.cs index b2d5abe71a..a67cf4e5ea 100644 --- a/osu.Game/Screens/Play/SkipButton.cs +++ b/osu.Game/Screens/Play/SkipButton.cs @@ -227,9 +227,9 @@ namespace osu.Game.Screens.Play Direction = FillDirection.Horizontal, Children = new[] { - new TextAwesome { Icon = FontAwesome.fa_chevron_right }, - new TextAwesome { Icon = FontAwesome.fa_chevron_right }, - new TextAwesome { Icon = FontAwesome.fa_chevron_right }, + new SpriteIcon { Icon = FontAwesome.fa_chevron_right }, + new SpriteIcon { Icon = FontAwesome.fa_chevron_right }, + new SpriteIcon { Icon = FontAwesome.fa_chevron_right }, } }, new OsuSpriteText diff --git a/osu.Game/Screens/Ranking/ResultModeButton.cs b/osu.Game/Screens/Ranking/ResultModeButton.cs index 50be5c8d00..d38611c45a 100644 --- a/osu.Game/Screens/Ranking/ResultModeButton.cs +++ b/osu.Game/Screens/Ranking/ResultModeButton.cs @@ -78,14 +78,14 @@ namespace osu.Game.Screens.Ranking RelativeSizeAxes = Axes.Both, Colour = Color4.Transparent, }, - new TextAwesome + new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, Shadow = false, Colour = OsuColour.Gray(0.95f), Icon = icon, - TextSize = 20, + Size = new Vector2(20), } } } diff --git a/osu.Game/Screens/ScreenWhiteBox.cs b/osu.Game/Screens/ScreenWhiteBox.cs index 5596f345d5..408dbd8f16 100644 --- a/osu.Game/Screens/ScreenWhiteBox.cs +++ b/osu.Game/Screens/ScreenWhiteBox.cs @@ -108,14 +108,14 @@ namespace osu.Game.Screens Anchor = Anchor.Centre, Origin = Anchor.Centre, Direction = FillDirection.Vertical, - Children = new[] + Children = new Drawable[] { - new TextAwesome + new SpriteIcon { Icon = FontAwesome.fa_universal_access, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - TextSize = 50, + Size = new Vector2(50), }, new OsuSpriteText { diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 385492980f..1fb9c707f0 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -247,21 +247,21 @@ namespace osu.Game.Screens.Select AutoSizeAxes = Axes.Both; Children = new Drawable[] { - new TextAwesome + new SpriteIcon { Icon = FontAwesome.fa_square, Origin = Anchor.Centre, Colour = new Color4(68, 17, 136, 255), Rotation = 45, - TextSize = 20 + Size = new Vector2(20), }, - new TextAwesome + new SpriteIcon { Icon = statistic.Icon, Origin = Anchor.Centre, Colour = new Color4(255, 221, 85, 255), Scale = new Vector2(0.8f), - TextSize = 20 + Size = new Vector2(20), }, new OsuSpriteText { diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index c406e7c44d..838e6f7123 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -121,7 +121,7 @@ namespace osu.Game.Screens.Select //{ // Font = @"Exo2.0-Bold", // Text = "Sort results by", - // TextSize = 14, + // Size = 14, // Margin = new MarginPadding // { // Top = 5, diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs index 39c948f8d3..ac3b0b5c3b 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs @@ -334,25 +334,23 @@ namespace osu.Game.Screens.Select.Leaderboards Children = new[] { - new TextAwesome + new SpriteIcon { Origin = Anchor.Centre, Anchor = Anchor.Centre, Icon = FontAwesome.fa_osu_mod_bg, Colour = colour, Shadow = true, - TextSize = 30, - UseFullGlyphHeight = false, + Size = new Vector2(30), }, - new TextAwesome + new SpriteIcon { Origin = Anchor.Centre, Anchor = Anchor.Centre, Icon = icon, Colour = OsuColour.Gray(84), - TextSize = 18, + Size = new Vector2(18), Position = new Vector2(0f, 2f), - UseFullGlyphHeight = false, }, }; } @@ -369,7 +367,7 @@ namespace osu.Game.Screens.Select.Leaderboards Children = new Drawable[] { - new TextAwesome + new SpriteIcon { Origin = Anchor.Centre, Icon = FontAwesome.fa_square, @@ -377,7 +375,7 @@ namespace osu.Game.Screens.Select.Leaderboards Rotation = 45, Shadow = true, }, - new TextAwesome + new SpriteIcon { Origin = Anchor.Centre, Icon = icon, diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs index ab02e8678f..306e7fb3dc 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs @@ -21,7 +21,7 @@ namespace osu.Game.Screens.Select.Options private readonly Box background; private readonly Box flash; - private readonly TextAwesome iconText; + private readonly SpriteIcon iconText; private readonly OsuSpriteText firstLine; private readonly OsuSpriteText secondLine; private readonly Container box; @@ -134,11 +134,11 @@ namespace osu.Game.Screens.Select.Options Direction = FillDirection.Vertical, Children = new Drawable[] { - iconText = new TextAwesome + iconText = new SpriteIcon { Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, - TextSize = 30, + Size = new Vector2(30), Shadow = true, Icon = FontAwesome.fa_close, Margin = new MarginPadding diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index cd9ca582fc..89bd4b68d2 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -142,15 +142,15 @@ namespace osu.Game.Users Origin = Anchor.Centre, AutoSizeAxes = Axes.Both, Spacing = new Vector2(5f, 0f), - Children = new[] + Children = new Drawable[] { - new TextAwesome + new SpriteIcon { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Icon = FontAwesome.fa_circle_o, Shadow = true, - TextSize = 14, + Size = new Vector2(14), }, statusMessage = new OsuSpriteText { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8b462b5287..3f475a34c8 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -116,6 +116,7 @@ + @@ -349,7 +350,7 @@ - + From c7f5b83e9e992c07d21527584eb0396543b9ed5f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Aug 2017 15:45:59 +0900 Subject: [PATCH 69/72] Derive from CompositeDrawable instead We need to expose EdgeEffect as it's used in places. --- .../Graphics/Containers/ConstrainedIconContainer.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs b/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs index 135786e1c5..546d3bb6e3 100644 --- a/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs +++ b/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs @@ -11,7 +11,7 @@ namespace osu.Game.Graphics.Containers /// /// Display an icon that is constrained to a physical region on screen. /// - public class ConstrainedIconContainer : Container + public class ConstrainedIconContainer : CompositeDrawable { public Drawable Icon { @@ -26,6 +26,17 @@ namespace osu.Game.Graphics.Containers } } + /// + /// Determines an edge effect of this . + /// Edge effects are e.g. glow or a shadow. + /// Only has an effect when is true. + /// + public new EdgeEffectParameters EdgeEffect + { + get { return base.EdgeEffect; } + set { base.EdgeEffect = value; } + } + protected override void Update() { base.Update(); From bb032508bd0c6802b53bd8c50617f0791ea9bd19 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Aug 2017 15:47:26 +0900 Subject: [PATCH 70/72] Add comment explaining why we use scale --- osu.Game/Graphics/Containers/ConstrainedIconContainer.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs b/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs index 546d3bb6e3..0f07080d55 100644 --- a/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs +++ b/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs @@ -42,6 +42,11 @@ namespace osu.Game.Graphics.Containers base.Update(); if (InternalChildren.Count > 0 && InternalChild.DrawSize.X > 0) { + // We're modifying scale here for a few reasons + // - Guarantees correctness if BorderWidth is being used + // - If we were to use RelativeSize/FillMode, we'd need to set the Icon's RelativeSizeAxes directly. + // We can't do this because we would need access to AutoSizeAxes to set it to none. + // Other issues come up along the way too, so it's not a good solution. var fitScale = Math.Min(DrawSize.X / InternalChild.DrawSize.X, DrawSize.Y / InternalChild.DrawSize.Y); InternalChild.Scale = new Vector2(fitScale); InternalChild.Anchor = Anchor.Centre; From 91f3d8deb44b425d632cf0299fd4087f15e5f9c0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Aug 2017 15:48:06 +0900 Subject: [PATCH 71/72] Improve class xmldoc --- osu.Game/Graphics/Containers/ConstrainedIconContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs b/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs index 0f07080d55..dd2a265a0f 100644 --- a/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs +++ b/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs @@ -9,7 +9,7 @@ using OpenTK; namespace osu.Game.Graphics.Containers { /// - /// Display an icon that is constrained to a physical region on screen. + /// Display an icon that is forced to scale to the size of this container. /// public class ConstrainedIconContainer : CompositeDrawable { From a5a5c1a31534cd457d2dd04fabb20ab404bcafe5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Aug 2017 15:50:59 +0900 Subject: [PATCH 72/72] Remove debug code --- osu.Game/Graphics/SpriteIcon.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/osu.Game/Graphics/SpriteIcon.cs b/osu.Game/Graphics/SpriteIcon.cs index 7f717cac3c..345c6e7639 100644 --- a/osu.Game/Graphics/SpriteIcon.cs +++ b/osu.Game/Graphics/SpriteIcon.cs @@ -49,12 +49,6 @@ namespace osu.Game.Graphics updateTexture(); } - protected override void LoadComplete() - { - base.LoadComplete(); - if (Size.X == 0) throw new System.Exception("size required"); - } - private void updateTexture() { var texture = store?.Get(((char)icon).ToString());