1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 12:23:22 +08:00

Combine all loading animation implementations

This commit is contained in:
Dean Herbert 2020-02-21 15:31:40 +09:00
parent e18d736e4a
commit 623b78d675
15 changed files with 185 additions and 225 deletions

View File

@ -8,7 +8,6 @@ using osu.Game.Overlays.Rankings.Tables;
using osu.Framework.Graphics;
using osu.Game.Online.API.Requests;
using osu.Game.Rulesets;
using osu.Game.Graphics.UserInterface;
using System.Threading;
using osu.Game.Online.API;
using osu.Game.Rulesets.Osu;
@ -16,6 +15,7 @@ using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Taiko;
using osu.Game.Rulesets.Catch;
using osu.Framework.Allocation;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
namespace osu.Game.Tests.Visual.Online
@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual.Online
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green);
private readonly BasicScrollContainer scrollFlow;
private readonly DimmedLoadingLayer loading;
private readonly LoadingLayer loading;
private CancellationTokenSource cancellationToken;
private APIRequest request;
@ -56,7 +56,7 @@ namespace osu.Game.Tests.Visual.Online
RelativeSizeAxes = Axes.Both,
Width = 0.8f,
},
loading = new DimmedLoadingLayer(),
loading = new LoadingLayer(),
};
}

View File

@ -12,8 +12,8 @@ using osu.Game.Rulesets.Mania;
using osu.Game.Users;
using osu.Framework.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Taiko;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Taiko;
namespace osu.Game.Tests.Visual.Online
{
@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.Online
private readonly Bindable<User> user = new Bindable<User>();
private GetUserRequest request;
private readonly DimmedLoadingLayer loading;
private readonly LoadingLayer loading;
public TestSceneUserRequest()
{
@ -40,10 +40,7 @@ namespace osu.Game.Tests.Visual.Online
{
User = { BindTarget = user }
},
loading = new DimmedLoadingLayer
{
Alpha = 0
}
loading = new LoadingLayer()
}
});
}

View File

@ -1,6 +1,8 @@
// 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.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -12,10 +14,12 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.UserInterface
{
public class TestSceneProcessingOverlay : OsuTestScene
public class TestSceneLoadingLayer : OsuTestScene
{
private Drawable dimContent;
private ProcessingOverlay overlay;
private LoadingLayer overlay;
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(LoadingAnimation) };
[SetUp]
public void SetUp() => Schedule(() =>
@ -49,7 +53,7 @@ namespace osu.Game.Tests.Visual.UserInterface
new TriangleButton { Text = "puush me", Width = 200, Action = () => { } },
}
},
overlay = new ProcessingOverlay(dimContent),
overlay = new LoadingLayer(dimContent),
}
},
};

View File

@ -1,58 +0,0 @@
// 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 osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Extensions.Color4Extensions;
using osuTK;
using osu.Framework.Input.Events;
namespace osu.Game.Graphics.UserInterface
{
public class DimmedLoadingLayer : OverlayContainer
{
private const float transition_duration = 250;
private readonly LoadingAnimation loading;
public DimmedLoadingLayer(float dimAmount = 0.5f, float iconScale = 1f)
{
RelativeSizeAxes = Axes.Both;
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(dimAmount),
},
loading = new LoadingAnimation { Scale = new Vector2(iconScale) },
};
}
protected override void PopIn()
{
this.FadeIn(transition_duration, Easing.OutQuint);
loading.Show();
}
protected override void PopOut()
{
this.FadeOut(transition_duration, Easing.OutQuint);
loading.Hide();
}
protected override bool Handle(UIEvent e)
{
switch (e)
{
// blocking scroll can cause weird behaviour when this layer is used within a ScrollContainer.
case ScrollEvent _:
return false;
}
return base.Handle(e);
}
}
}

View File

@ -3,6 +3,7 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osuTK;
using osuTK.Graphics;
@ -15,36 +16,47 @@ namespace osu.Game.Graphics.UserInterface
public class LoadingAnimation : VisibilityContainer
{
private readonly SpriteIcon spinner;
private readonly SpriteIcon spinnerShadow;
private const float spin_duration = 600;
private const float transition_duration = 200;
protected Container MainContents;
public LoadingAnimation()
protected const float TRANSITION_DURATION = 500;
private const float spin_duration = 900;
/// <summary>
/// Constuct a new loading spinner.
/// </summary>
/// <param name="withBox"></param>
public LoadingAnimation(bool withBox = false)
{
Size = new Vector2(20);
Size = new Vector2(60);
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Children = new Drawable[]
Child = MainContents = new Container
{
spinnerShadow = new SpriteIcon
RelativeSizeAxes = Axes.Both,
Masking = true,
CornerRadius = 20,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Children = new Drawable[]
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Position = new Vector2(1, 1),
Colour = Color4.Black,
Alpha = 0.4f,
Icon = FontAwesome.Solid.CircleNotch
},
spinner = new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Icon = FontAwesome.Solid.CircleNotch
new Box
{
Colour = Color4.Black,
RelativeSizeAxes = Axes.Both,
Alpha = withBox ? 0.7f : 0
},
spinner = new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(withBox ? 0.6f : 1),
RelativeSizeAxes = Axes.Both,
Icon = FontAwesome.Solid.CircleNotch
}
}
};
}
@ -53,12 +65,42 @@ namespace osu.Game.Graphics.UserInterface
{
base.LoadComplete();
spinner.Spin(spin_duration, RotationDirection.Clockwise);
spinnerShadow.Spin(spin_duration, RotationDirection.Clockwise);
rotate();
}
protected override void PopIn() => this.FadeIn(transition_duration * 2, Easing.OutQuint);
protected override void Update()
{
base.Update();
protected override void PopOut() => this.FadeOut(transition_duration, Easing.OutQuint);
MainContents.CornerRadius = MainContents.DrawWidth / 4;
}
protected override void PopIn()
{
if (Alpha < 0.5f)
// reset animation if the user can't see us.
rotate();
MainContents.ScaleTo(1, TRANSITION_DURATION, Easing.OutQuint);
this.FadeIn(TRANSITION_DURATION * 2, Easing.OutQuint);
}
protected override void PopOut()
{
MainContents.ScaleTo(0.8f, TRANSITION_DURATION / 2, Easing.In);
this.FadeOut(TRANSITION_DURATION, Easing.OutQuint);
}
private void rotate()
{
spinner.Spin(spin_duration * 4, RotationDirection.Clockwise);
MainContents.RotateTo(0).Then()
.RotateTo(90, spin_duration, Easing.InOutQuart).Then()
.RotateTo(180, spin_duration, Easing.InOutQuart).Then()
.RotateTo(270, spin_duration, Easing.InOutQuart).Then()
.RotateTo(360, spin_duration, Easing.InOutQuart).Then()
.Loop();
}
}
}

View File

@ -0,0 +1,74 @@
// 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 osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
/// <summary>
/// An overlay that will show a loading overlay and completely block input to an area.
/// Also optionally dims target elements.
/// Useful for disabling all elements in a form and showing we are waiting on a response, for instance.
/// </summary>
public class LoadingLayer : LoadingAnimation
{
private readonly Drawable dimTarget;
public LoadingLayer(Drawable dimTarget = null, bool withBox = true)
: base(withBox)
{
RelativeSizeAxes = Axes.Both;
Size = new Vector2(1);
this.dimTarget = dimTarget;
MainContents.RelativeSizeAxes = Axes.None;
}
protected override bool Handle(UIEvent e)
{
switch (e)
{
// blocking scroll can cause weird behaviour when this layer is used within a ScrollContainer.
case ScrollEvent _:
return false;
}
return true;
}
protected override void PopIn()
{
dimTarget?.FadeColour(OsuColour.Gray(0.5f), TRANSITION_DURATION, Easing.OutQuint);
base.PopIn();
}
protected override void PopOut()
{
dimTarget?.FadeColour(Color4.White, TRANSITION_DURATION, Easing.OutQuint);
base.PopOut();
}
protected override void Update()
{
base.Update();
MainContents.Size = new Vector2(Math.Min(DrawWidth, DrawHeight) * 0.25f);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (State.Value == Visibility.Visible)
{
// ensure we don't leave the target in a bad state.
dimTarget?.FadeColour(Color4.White, TRANSITION_DURATION, Easing.OutQuint);
}
}
}
}

View File

@ -1,88 +0,0 @@
// 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 osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
/// <summary>
/// An overlay that will show a loading overlay and completely block input to an area.
/// Also optionally dims target elements.
/// Useful for disabling all elements in a form and showing we are waiting on a response, for instance.
/// </summary>
public class ProcessingOverlay : VisibilityContainer
{
private readonly Drawable dimTarget;
private Container loadingBox;
private const float transition_duration = 600;
public ProcessingOverlay(Drawable dimTarget = null)
{
this.dimTarget = dimTarget;
RelativeSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader]
private void load()
{
InternalChildren = new Drawable[]
{
loadingBox = new Container
{
Size = new Vector2(80),
Scale = new Vector2(0.8f),
Masking = true,
CornerRadius = 15,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Children = new Drawable[]
{
new Box
{
Colour = Color4.Black,
RelativeSizeAxes = Axes.Both,
},
new LoadingAnimation { State = { Value = Visibility.Visible } }
}
},
};
}
protected override bool Handle(UIEvent e) => true;
protected override void PopIn()
{
this.FadeIn(transition_duration, Easing.OutQuint);
loadingBox.ScaleTo(1, transition_duration, Easing.OutElastic);
dimTarget?.FadeColour(OsuColour.Gray(0.5f), transition_duration, Easing.OutQuint);
}
protected override void PopOut()
{
this.FadeOut(transition_duration, Easing.OutQuint);
loadingBox.ScaleTo(0.8f, transition_duration / 2, Easing.In);
dimTarget?.FadeColour(Color4.White, transition_duration, Easing.OutQuint);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (State.Value == Visibility.Visible)
{
// ensure we don't leave the target in a bad state.
dimTarget?.FadeColour(Color4.White, transition_duration, Easing.OutQuint);
}
}
}
}

View File

@ -40,7 +40,7 @@ namespace osu.Game.Overlays.AccountCreation
private IEnumerable<Drawable> characterCheckText;
private OsuTextBox[] textboxes;
private ProcessingOverlay processingOverlay;
private LoadingLayer loadingLayer;
[Resolved]
private GameHost host { get; set; }
@ -124,7 +124,7 @@ namespace osu.Game.Overlays.AccountCreation
},
},
},
processingOverlay = new ProcessingOverlay(mainContent)
loadingLayer = new LoadingLayer(mainContent)
};
textboxes = new[] { usernameTextBox, emailTextBox, passwordTextBox };
@ -144,7 +144,7 @@ namespace osu.Game.Overlays.AccountCreation
public override void OnEntering(IScreen last)
{
base.OnEntering(last);
processingOverlay.Hide();
loadingLayer.Hide();
if (host?.OnScreenKeyboardOverlapsGameWindow != true)
focusNextTextbox();
@ -162,7 +162,7 @@ namespace osu.Game.Overlays.AccountCreation
emailAddressDescription.ClearErrors();
passwordDescription.ClearErrors();
processingOverlay.Show();
loadingLayer.Show();
Task.Run(() =>
{
@ -195,7 +195,7 @@ namespace osu.Game.Overlays.AccountCreation
}
registerShake.Shake();
processingOverlay.Hide();
loadingLayer.Hide();
return;
}

View File

@ -5,7 +5,6 @@ using System.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
@ -25,7 +24,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
private readonly BindableBool favourited = new BindableBool();
private PostBeatmapFavouriteRequest request;
private DimmedLoadingLayer loading;
private LoadingLayer loading;
private readonly Bindable<User> localUser = new Bindable<User>();
@ -54,14 +53,11 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
Size = new Vector2(18),
Shadow = false,
},
loading = new DimmedLoadingLayer(0.8f, 0.5f),
loading = new LoadingLayer(icon, false),
});
Action = () =>
{
if (loading.State.Value == Visibility.Visible)
return;
// guaranteed by disabled state above.
Debug.Assert(BeatmapSet.Value.OnlineBeatmapSetID != null);

View File

@ -5,7 +5,6 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.UserInterface;
using osuTK;
using System.Linq;
using osu.Game.Online.API.Requests.Responses;
@ -13,6 +12,7 @@ using osu.Game.Beatmaps;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Framework.Bindables;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
using osu.Game.Screens.Select.Leaderboards;
using osu.Game.Users;
@ -31,7 +31,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
private readonly Box background;
private readonly ScoreTable scoreTable;
private readonly FillFlowContainer topScoresContainer;
private readonly DimmedLoadingLayer loading;
private readonly LoadingLayer loading;
private readonly LeaderboardModSelector modSelector;
private readonly NoScoresPlaceholder noScoresPlaceholder;
private readonly FillFlowContainer content;
@ -160,16 +160,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
}
}
},
new Container
{
RelativeSizeAxes = Axes.Both,
Masking = true,
CornerRadius = 5,
Child = loading = new DimmedLoadingLayer(iconScale: 0.8f)
{
Alpha = 0,
},
}
loading = new LoadingLayer()
}
}
}

View File

@ -37,7 +37,7 @@ namespace osu.Game.Overlays.Rankings
private SpotlightSelector selector;
private Container content;
private DimmedLoadingLayer loading;
private LoadingLayer loading;
[BackgroundDependencyLoader]
private void load()
@ -67,7 +67,7 @@ namespace osu.Game.Overlays.Rankings
AutoSizeAxes = Axes.Y,
Margin = new MarginPadding { Vertical = 10 }
},
loading = new DimmedLoadingLayer()
loading = new LoadingLayer(content)
}
}
}

View File

@ -9,9 +9,9 @@ using osu.Framework.Graphics.Shapes;
using osu.Game.Overlays.Rankings;
using osu.Game.Users;
using osu.Game.Rulesets;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using System.Threading;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API.Requests;
using osu.Game.Overlays.Rankings.Tables;
@ -27,7 +27,7 @@ namespace osu.Game.Overlays
private readonly BasicScrollContainer scrollFlow;
private readonly Container contentContainer;
private readonly DimmedLoadingLayer loading;
private readonly LoadingLayer loading;
private readonly Box background;
private readonly RankingsOverlayHeader header;
@ -77,7 +77,7 @@ namespace osu.Game.Overlays
RelativeSizeAxes = Axes.X,
Margin = new MarginPadding { Bottom = 10 }
},
loading = new DimmedLoadingLayer(),
loading = new LoadingLayer(contentContainer),
}
}
}

View File

@ -23,7 +23,7 @@ namespace osu.Game.Screens.Multi.Lounge
protected readonly FilterControl Filter;
private readonly Container content;
private readonly ProcessingOverlay processingOverlay;
private readonly LoadingLayer loadingLayer;
[Resolved]
private Bindable<Room> currentRoom { get; set; }
@ -58,7 +58,7 @@ namespace osu.Game.Screens.Multi.Lounge
Child = new RoomsContainer { JoinRequested = joinRequested }
},
},
processingOverlay = new ProcessingOverlay(searchContainer),
loadingLayer = new LoadingLayer(searchContainer),
}
},
new RoomInspector
@ -126,12 +126,12 @@ namespace osu.Game.Screens.Multi.Lounge
private void joinRequested(Room room)
{
processingOverlay.Show();
loadingLayer.Show();
RoomManager?.JoinRoom(room, r =>
{
Open(room);
processingOverlay.Hide();
}, _ => processingOverlay.Hide());
loadingLayer.Hide();
}, _ => loadingLayer.Hide());
}
/// <summary>

View File

@ -67,7 +67,7 @@ namespace osu.Game.Screens.Multi.Match.Components
public OsuSpriteText ErrorText;
private OsuSpriteText typeLabel;
private ProcessingOverlay processingOverlay;
private LoadingLayer loadingLayer;
private DrawableRoomPlaylist playlist;
[Resolved(CanBeNull = true)]
@ -307,7 +307,7 @@ namespace osu.Game.Screens.Multi.Match.Components
},
}
},
processingOverlay = new ProcessingOverlay(dimContent)
loadingLayer = new LoadingLayer(dimContent)
};
TypePicker.Current.BindValueChanged(type => typeLabel.Text = type.NewValue?.Name ?? string.Empty, true);
@ -346,19 +346,19 @@ namespace osu.Game.Screens.Multi.Match.Components
manager?.CreateRoom(currentRoom.Value, onSuccess, onError);
processingOverlay.Show();
loadingLayer.Show();
}
private void hideError() => ErrorText.FadeOut(50);
private void onSuccess(Room room) => processingOverlay.Hide();
private void onSuccess(Room room) => loadingLayer.Hide();
private void onError(string text)
{
ErrorText.Text = text;
ErrorText.FadeIn(50);
processingOverlay.Hide();
loadingLayer.Hide();
}
}

View File

@ -7,7 +7,6 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using System.Linq;
using osu.Game.Online.API;
using osu.Framework.Threading;
@ -17,6 +16,7 @@ using osu.Game.Screens.Select.Details;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API.Requests;
using osu.Game.Rulesets;
@ -35,7 +35,7 @@ namespace osu.Game.Screens.Select
private readonly MetadataSection description, source, tags;
private readonly Container failRetryContainer;
private readonly FailRetryGraph failRetryGraph;
private readonly DimmedLoadingLayer loading;
private readonly LoadingLayer loading;
[Resolved]
private IAPIProvider api { get; set; }
@ -63,6 +63,8 @@ namespace osu.Game.Screens.Select
public BeatmapDetails()
{
Container content;
Children = new Drawable[]
{
new Box
@ -70,7 +72,7 @@ namespace osu.Game.Screens.Select
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(0.5f),
},
new Container
content = new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Horizontal = spacing },
@ -157,7 +159,7 @@ namespace osu.Game.Screens.Select
},
},
},
loading = new DimmedLoadingLayer(),
loading = new LoadingLayer(content),
};
}