From 4e4a779d6827d76323702fad328c451c3e3fb000 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Thu, 14 May 2020 17:40:43 +0900
Subject: [PATCH] Improve overall UI

---
 .../Sections/General/UpdateSettings.cs        |  10 +-
 .../Sections/Maintenance/GeneralSettings.cs   |   7 --
 .../Maintenance/MigrationRunScreen.cs         |  29 ++++-
 .../Maintenance/MigrationSelectScreen.cs      | 105 +++++++++++++++---
 4 files changed, 123 insertions(+), 28 deletions(-)

diff --git a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs
index 188c9c05ef..b5d07ee7b1 100644
--- a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs
@@ -4,7 +4,9 @@
 using osu.Framework;
 using osu.Framework.Allocation;
 using osu.Framework.Platform;
+using osu.Framework.Screens;
 using osu.Game.Configuration;
+using osu.Game.Overlays.Settings.Sections.Maintenance;
 
 namespace osu.Game.Overlays.Settings.Sections.General
 {
@@ -13,7 +15,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
         protected override string Header => "Updates";
 
         [BackgroundDependencyLoader]
-        private void load(Storage storage, OsuConfigManager config)
+        private void load(Storage storage, OsuConfigManager config, OsuGame game)
         {
             Add(new SettingsEnumDropdown<ReleaseStream>
             {
@@ -28,6 +30,12 @@ namespace osu.Game.Overlays.Settings.Sections.General
                     Text = "Open osu! folder",
                     Action = storage.OpenInNativeExplorer,
                 });
+
+                Add(new SettingsButton
+                {
+                    Text = "Change folder location...",
+                    Action = () => game.PerformFromScreen(menu => menu.Push(new MigrationSelectScreen()))
+                });
             }
         }
     }
diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs
index 8bdeadae5c..1dd079a8ab 100644
--- a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs
@@ -5,7 +5,6 @@ using System.Linq;
 using System.Threading.Tasks;
 using osu.Framework.Allocation;
 using osu.Framework.Graphics;
-using osu.Framework.Screens;
 using osu.Game.Beatmaps;
 using osu.Game.Graphics.UserInterface;
 using osu.Game.Scoring;
@@ -29,12 +28,6 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
         [BackgroundDependencyLoader]
         private void load(BeatmapManager beatmaps, ScoreManager scores, SkinManager skins, DialogOverlay dialogOverlay, OsuGame game)
         {
-            Add(importBeatmapsButton = new SettingsButton
-            {
-                Text = "Migrate storage to new location",
-                Action = () => game.PerformFromScreen(menu => menu.Push(new MigrationSelectScreen()))
-            });
-
             if (beatmaps.SupportsImportFromStable)
             {
                 Add(importBeatmapsButton = new SettingsButton
diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs
index 76f01dc4b9..b29cd0d630 100644
--- a/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs
+++ b/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs
@@ -12,6 +12,7 @@ using osu.Game.Graphics;
 using osu.Game.Graphics.Sprites;
 using osu.Game.Graphics.UserInterface;
 using osu.Game.Screens;
+using osuTK;
 
 namespace osu.Game.Overlays.Settings.Sections.Maintenance
 {
@@ -28,6 +29,8 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
 
         public override bool DisallowExternalBeatmapRulesetChanges => true;
 
+        public override bool HideOverlaysOnEnter => true;
+
         private Task migrationTask;
 
         public MigrationRunScreen(DirectoryInfo destination)
@@ -47,6 +50,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
                     Direction = FillDirection.Vertical,
                     Anchor = Anchor.Centre,
                     Origin = Anchor.Centre,
+                    Spacing = new Vector2(10),
                     Children = new Drawable[]
                     {
                         new OsuSpriteText
@@ -54,12 +58,26 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
                             Anchor = Anchor.Centre,
                             Origin = Anchor.Centre,
                             Text = "Migration in progress",
-                            Font = OsuFont.Default.With(size: 48)
+                            Font = OsuFont.Default.With(size: 40)
+                        },
+                        new OsuSpriteText
+                        {
+                            Anchor = Anchor.Centre,
+                            Origin = Anchor.Centre,
+                            Text = "This could take a few minutes depending on the speed of your disk(s).",
+                            Font = OsuFont.Default.With(size: 30)
                         },
                         new LoadingSpinner(true)
                         {
                             State = { Value = Visibility.Visible }
-                        }
+                        },
+                        new OsuSpriteText
+                        {
+                            Anchor = Anchor.Centre,
+                            Origin = Anchor.Centre,
+                            Text = "Please avoid interacting with the game!",
+                            Font = OsuFont.Default.With(size: 30)
+                        },
                     }
                 },
             };
@@ -76,6 +94,13 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
                                 });
         }
 
+        public override void OnEntering(IScreen last)
+        {
+            base.OnEntering(last);
+
+            this.FadeOut().Delay(250).Then().FadeIn(250);
+        }
+
         public override bool OnExiting(IScreen next)
         {
             // block until migration is finished
diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationSelectScreen.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationSelectScreen.cs
index d1c2f6d6ee..c1aa7f095c 100644
--- a/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationSelectScreen.cs
+++ b/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationSelectScreen.cs
@@ -1,13 +1,21 @@
 // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
 // See the LICENCE file in the repository root for full licence text.
 
+using System;
+using System.IO;
 using osu.Framework.Allocation;
 using osu.Framework.Graphics;
 using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Shapes;
+using osu.Framework.Logging;
+using osu.Framework.Platform;
 using osu.Framework.Screens;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Sprites;
 using osu.Game.Graphics.UserInterface;
 using osu.Game.Graphics.UserInterfaceV2;
 using osu.Game.Screens;
+using osuTK;
 
 namespace osu.Game.Overlays.Settings.Sections.Maintenance
 {
@@ -15,40 +23,101 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
     {
         private DirectorySelector directorySelector;
 
+        public override bool AllowExternalScreenChange => false;
+
+        public override bool DisallowExternalBeatmapRulesetChanges => true;
+
+        public override bool HideOverlaysOnEnter => true;
+
         [BackgroundDependencyLoader]
-        private void load()
+        private void load(OsuGame game, Storage storage, OsuColour colours)
         {
-            InternalChild = new GridContainer
+            game.Toolbar.Hide();
+
+            // begin selection in the parent directory of the current storage location
+            var initialPath = new DirectoryInfo(storage.GetFullPath(string.Empty)).Parent?.FullName;
+
+            InternalChild = new Container
             {
+                Masking = true,
+                CornerRadius = 10,
                 RelativeSizeAxes = Axes.Both,
-                RowDimensions = new[]
+                Anchor = Anchor.Centre,
+                Origin = Anchor.Centre,
+                Size = new Vector2(0.5f, 0.8f),
+                Children = new Drawable[]
                 {
-                    new Dimension(GridSizeMode.Relative, 0.8f),
-                    new Dimension(),
-                },
-                Content = new[]
-                {
-                    new Drawable[] { directorySelector = new DirectorySelector { RelativeSizeAxes = Axes.Both } },
-                    new Drawable[]
+                    new Box
                     {
-                        new OsuButton
+                        Colour = colours.GreySeafoamDark,
+                        RelativeSizeAxes = Axes.Both,
+                    },
+                    new GridContainer
+                    {
+                        RelativeSizeAxes = Axes.Both,
+                        RowDimensions = new[]
                         {
-                            Anchor = Anchor.Centre,
-                            Origin = Anchor.Centre,
-                            Width = 300,
-                            Text = "Start",
-                            Action = start
+                            new Dimension(),
+                            new Dimension(GridSizeMode.Relative, 0.8f),
+                            new Dimension(),
                         },
+                        Content = new[]
+                        {
+                            new Drawable[]
+                            {
+                                new OsuSpriteText
+                                {
+                                    Anchor = Anchor.Centre,
+                                    Origin = Anchor.Centre,
+                                    Text = "Please select a new location",
+                                    Font = OsuFont.Default.With(size: 40)
+                                },
+                            },
+                            new Drawable[]
+                            {
+                                directorySelector = new DirectorySelector(initialPath)
+                                {
+                                    RelativeSizeAxes = Axes.Both,
+                                }
+                            },
+                            new Drawable[]
+                            {
+                                new TriangleButton
+                                {
+                                    Anchor = Anchor.Centre,
+                                    Origin = Anchor.Centre,
+                                    Width = 300,
+                                    Text = "Begin folder migration",
+                                    Action = start
+                                },
+                            }
+                        }
                     }
                 }
             };
         }
 
+        public override void OnSuspending(IScreen next)
+        {
+            base.OnSuspending(next);
+
+            this.FadeOut(250);
+        }
+
         private void start()
         {
             var target = directorySelector.CurrentDirectory.Value;
-            if (target.GetDirectories().Length > 0 || target.GetFiles().Length > 0)
-                target = target.CreateSubdirectory("osu-lazer");
+
+            try
+            {
+                if (target.GetDirectories().Length > 0 || target.GetFiles().Length > 0)
+                    target = target.CreateSubdirectory("osu-lazer");
+            }
+            catch (Exception e)
+            {
+                Logger.Log($"Error during migration: {e?.Message}", level: LogLevel.Error);
+                return;
+            }
 
             ValidForResume = false;
             this.Push(new MigrationRunScreen(target));