mirror of
https://github.com/ppy/osu.git
synced 2025-02-21 21:32:55 +08:00
Rework preview tracks to reduce usage complexities
This commit is contained in:
parent
ab2889da1f
commit
b2066c5d73
16
osu.Game/Audio/IPreviewTrackOwner.cs
Normal file
16
osu.Game/Audio/IPreviewTrackOwner.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Audio
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for objects that can own <see cref="IPreviewTrack"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <see cref="IPreviewTrackOwner"/>s can cancel the currently playing <see cref="PreviewTrack"/> through the
|
||||||
|
/// global <see cref="PreviewTrackManager"/> if they're the owner of the playing <see cref="PreviewTrack"/>.
|
||||||
|
/// </remarks>
|
||||||
|
public interface IPreviewTrackOwner
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -5,49 +5,87 @@ using System;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Threading;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
|
|
||||||
namespace osu.Game.Audio
|
namespace osu.Game.Audio
|
||||||
{
|
{
|
||||||
public class PreviewTrack : Component
|
public abstract class PreviewTrack : Component
|
||||||
{
|
{
|
||||||
public Track Track { get; private set; }
|
|
||||||
private readonly OverlayContainer owner;
|
|
||||||
|
|
||||||
private readonly BeatmapSetInfo beatmapSetInfo;
|
|
||||||
|
|
||||||
public event Action Stopped;
|
public event Action Stopped;
|
||||||
public event Action Started;
|
public event Action Started;
|
||||||
|
|
||||||
public PreviewTrack(BeatmapSetInfo beatmapSetInfo, OverlayContainer owner)
|
private Track track;
|
||||||
{
|
private bool wasPlaying;
|
||||||
this.beatmapSetInfo = beatmapSetInfo;
|
|
||||||
this.owner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(PreviewTrackManager previewTrackManager)
|
private void load()
|
||||||
{
|
{
|
||||||
Track = previewTrackManager.Get(this, beatmapSetInfo);
|
track = GetTrack();
|
||||||
}
|
|
||||||
|
|
||||||
public void Start()
|
if (track != null)
|
||||||
{
|
track.Looping = false;
|
||||||
Track.Restart();
|
|
||||||
Started?.Invoke();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stop preview playback
|
/// Length of the track.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="source">An <see cref="OverlayContainer"/> which is probably the owner of this <see cref="PreviewTrack"/></param>
|
public double Length => track?.Length ?? 0;
|
||||||
public void Stop(OverlayContainer source = null)
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current track time.
|
||||||
|
/// </summary>
|
||||||
|
public double CurrentTime => track?.CurrentTime ?? 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the track is loaded.
|
||||||
|
/// </summary>
|
||||||
|
public bool TrackLoaded => track?.IsLoaded ?? false;
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
{
|
{
|
||||||
if (source != null && owner != source)
|
base.Update();
|
||||||
|
|
||||||
|
// Todo: Track currently doesn't signal its completion, so we have to handle it manually
|
||||||
|
if (track != null && wasPlaying && track.HasCompleted)
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScheduledDelegate startDelegate;
|
||||||
|
|
||||||
|
public void Start() => startDelegate = Schedule(() =>
|
||||||
|
{
|
||||||
|
if (!IsLoaded)
|
||||||
return;
|
return;
|
||||||
Track.Stop();
|
|
||||||
|
if (track == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (wasPlaying)
|
||||||
|
return;
|
||||||
|
wasPlaying = true;
|
||||||
|
|
||||||
|
track.Restart();
|
||||||
|
Started?.Invoke();
|
||||||
|
});
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
startDelegate?.Cancel();
|
||||||
|
|
||||||
|
if (!IsLoaded)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (track == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!wasPlaying)
|
||||||
|
return;
|
||||||
|
wasPlaying = false;
|
||||||
|
|
||||||
|
track.Stop();
|
||||||
Stopped?.Invoke();
|
Stopped?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract Track GetTrack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,17 +13,17 @@ namespace osu.Game.Audio
|
|||||||
{
|
{
|
||||||
public class PreviewTrackManager : Component
|
public class PreviewTrackManager : Component
|
||||||
{
|
{
|
||||||
|
private readonly BindableDouble muteBindable = new BindableDouble();
|
||||||
|
|
||||||
private AudioManager audio;
|
private AudioManager audio;
|
||||||
private TrackManager trackManager;
|
private TrackManager trackManager;
|
||||||
private BindableDouble muteBindable;
|
|
||||||
|
|
||||||
public PreviewTrack CurrentTrack { get; private set; }
|
private TrackManagerPreviewTrack current;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(AudioManager audio, FrameworkConfigManager config)
|
private void load(AudioManager audio, FrameworkConfigManager config)
|
||||||
{
|
{
|
||||||
trackManager = new TrackManager(new OnlineStore());
|
trackManager = new TrackManager(new OnlineStore());
|
||||||
muteBindable = new BindableDouble();
|
|
||||||
|
|
||||||
this.audio = audio;
|
this.audio = audio;
|
||||||
audio.AddItem(trackManager);
|
audio.AddItem(trackManager);
|
||||||
@ -31,30 +31,55 @@ namespace osu.Game.Audio
|
|||||||
config.BindWith(FrameworkSetting.VolumeMusic, trackManager.Volume);
|
config.BindWith(FrameworkSetting.VolumeMusic, trackManager.Volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
public PreviewTrack Get(BeatmapSetInfo beatmapSetInfo)
|
||||||
{
|
{
|
||||||
if (CurrentTrack?.Track.HasCompleted ?? false)
|
var track = new TrackManagerPreviewTrack(beatmapSetInfo, trackManager);
|
||||||
CurrentTrack.Stop();
|
|
||||||
|
|
||||||
base.Update();
|
track.Started += () =>
|
||||||
}
|
|
||||||
|
|
||||||
public Track Get(PreviewTrack previewTrack, BeatmapSetInfo beatmapSetInfo)
|
|
||||||
{
|
|
||||||
previewTrack.Started += () =>
|
|
||||||
{
|
{
|
||||||
CurrentTrack?.Stop();
|
current?.Stop();
|
||||||
CurrentTrack = previewTrack;
|
current = track;
|
||||||
audio.Track.AddAdjustment(AdjustableProperty.Volume, muteBindable);
|
audio.Track.AddAdjustment(AdjustableProperty.Volume, muteBindable);
|
||||||
};
|
};
|
||||||
|
|
||||||
previewTrack.Stopped += () =>
|
track.Stopped += () =>
|
||||||
{
|
{
|
||||||
CurrentTrack = null;
|
current = null;
|
||||||
audio.Track.RemoveAdjustment(AdjustableProperty.Volume, muteBindable);
|
audio.Track.RemoveAdjustment(AdjustableProperty.Volume, muteBindable);
|
||||||
};
|
};
|
||||||
|
|
||||||
return trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo?.OnlineBeatmapSetID}.mp3");
|
return track;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop(IPreviewTrackOwner source)
|
||||||
|
{
|
||||||
|
if (current?.Owner != source)
|
||||||
|
return;
|
||||||
|
|
||||||
|
current?.Stop();
|
||||||
|
current = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TrackManagerPreviewTrack : PreviewTrack
|
||||||
|
{
|
||||||
|
public IPreviewTrackOwner Owner { get; private set; }
|
||||||
|
|
||||||
|
private readonly BeatmapSetInfo beatmapSetInfo;
|
||||||
|
private readonly TrackManager trackManager;
|
||||||
|
|
||||||
|
public TrackManagerPreviewTrack(BeatmapSetInfo beatmapSetInfo, TrackManager trackManager)
|
||||||
|
{
|
||||||
|
this.beatmapSetInfo = beatmapSetInfo;
|
||||||
|
this.trackManager = trackManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(IPreviewTrackOwner owner)
|
||||||
|
{
|
||||||
|
Owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Track GetTrack() => trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo?.OnlineBeatmapSetID}.mp3");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,20 +8,32 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Game.Audio;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.Containers
|
namespace osu.Game.Graphics.Containers
|
||||||
{
|
{
|
||||||
public class OsuFocusedOverlayContainer : FocusedOverlayContainer
|
public class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner
|
||||||
{
|
{
|
||||||
private SampleChannel samplePopIn;
|
private SampleChannel samplePopIn;
|
||||||
private SampleChannel samplePopOut;
|
private SampleChannel samplePopOut;
|
||||||
|
|
||||||
|
private PreviewTrackManager previewTrackManager;
|
||||||
|
|
||||||
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
|
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||||
private void load(OsuGame osuGame, AudioManager audio)
|
|
||||||
{
|
{
|
||||||
|
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||||
|
dependencies.CacheAs<IPreviewTrackOwner>(this);
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader(true)]
|
||||||
|
private void load(OsuGame osuGame, AudioManager audio, PreviewTrackManager previewTrackManager)
|
||||||
|
{
|
||||||
|
this.previewTrackManager = previewTrackManager;
|
||||||
|
|
||||||
if (osuGame != null)
|
if (osuGame != null)
|
||||||
OverlayActivationMode.BindTo(osuGame.OverlayActivationMode);
|
OverlayActivationMode.BindTo(osuGame.OverlayActivationMode);
|
||||||
|
|
||||||
@ -66,5 +78,11 @@ namespace osu.Game.Graphics.Containers
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void PopOut()
|
||||||
|
{
|
||||||
|
base.PopOut();
|
||||||
|
previewTrackManager.Stop(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
|
|||||||
if (Playing.Value && preview != null)
|
if (Playing.Value && preview != null)
|
||||||
{
|
{
|
||||||
// prevent negative (potential infinite) width if a track without length was loaded
|
// prevent negative (potential infinite) width if a track without length was loaded
|
||||||
progress.Width = preview.Track.Length > 0 ? (float)(preview.Track.CurrentTime / preview.Track.Length) : 0f;
|
progress.Width = preview.Length > 0 ? (float)(preview.CurrentTime / preview.Length) : 0f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
progress.Width = 0;
|
progress.Width = 0;
|
||||||
|
@ -8,7 +8,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Game.Audio;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
@ -38,7 +37,6 @@ namespace osu.Game.Overlays
|
|||||||
private readonly ScrollContainer scroll;
|
private readonly ScrollContainer scroll;
|
||||||
|
|
||||||
private BeatmapSetInfo beatmapSet;
|
private BeatmapSetInfo beatmapSet;
|
||||||
private PreviewTrackManager previewTrackManager;
|
|
||||||
|
|
||||||
public BeatmapSetInfo BeatmapSet
|
public BeatmapSetInfo BeatmapSet
|
||||||
{
|
{
|
||||||
@ -111,11 +109,10 @@ namespace osu.Game.Overlays
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(APIAccess api, RulesetStore rulesets, PreviewTrackManager previewTrackManager)
|
private void load(APIAccess api, RulesetStore rulesets)
|
||||||
{
|
{
|
||||||
this.api = api;
|
this.api = api;
|
||||||
this.rulesets = rulesets;
|
this.rulesets = rulesets;
|
||||||
this.previewTrackManager = previewTrackManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopIn()
|
protected override void PopIn()
|
||||||
@ -127,8 +124,6 @@ namespace osu.Game.Overlays
|
|||||||
protected override void PopOut()
|
protected override void PopOut()
|
||||||
{
|
{
|
||||||
base.PopOut();
|
base.PopOut();
|
||||||
previewTrackManager.CurrentTrack?.Stop(this);
|
|
||||||
|
|
||||||
FadeEdgeEffectTo(0, WaveContainer.DISAPPEAR_DURATION, Easing.Out).OnComplete(_ => BeatmapSet = null);
|
FadeEdgeEffectTo(0, WaveContainer.DISAPPEAR_DURATION, Easing.Out).OnComplete(_ => BeatmapSet = null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,9 +113,9 @@ namespace osu.Game.Overlays.Direct
|
|||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
if (PreviewPlaying && Preview != null && Preview.Track.IsLoaded)
|
if (PreviewPlaying && Preview != null && Preview.TrackLoaded)
|
||||||
{
|
{
|
||||||
PreviewBar.Width = (float)(Preview.Track.CurrentTime / Preview.Track.Length);
|
PreviewBar.Width = (float)(Preview.CurrentTime / Preview.Length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,21 +29,14 @@ namespace osu.Game.Overlays.Direct
|
|||||||
if (value == beatmapSet) return;
|
if (value == beatmapSet) return;
|
||||||
beatmapSet = value;
|
beatmapSet = value;
|
||||||
|
|
||||||
Preview?.Stop(parentOverlayContainer);
|
if (Preview != null)
|
||||||
|
{
|
||||||
|
Preview.Stop();
|
||||||
|
RemoveInternal(Preview);
|
||||||
|
Preview = null;
|
||||||
|
}
|
||||||
|
|
||||||
Playing.Value = false;
|
Playing.Value = false;
|
||||||
Preview = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private OverlayContainer parentOverlayContainer
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var d = Parent;
|
|
||||||
while (!(d is OverlayContainer))
|
|
||||||
d = d.Parent;
|
|
||||||
|
|
||||||
return (OverlayContainer)d;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,9 +82,13 @@ namespace osu.Game.Overlays.Direct
|
|||||||
Playing.ValueChanged += playingStateChanged;
|
Playing.ValueChanged += playingStateChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PreviewTrackManager previewTrackManager;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colour)
|
private void load(OsuColour colour, PreviewTrackManager previewTrackManager)
|
||||||
{
|
{
|
||||||
|
this.previewTrackManager = previewTrackManager;
|
||||||
|
|
||||||
hoverColour = colour.Yellow;
|
hoverColour = colour.Yellow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,15 +100,18 @@ namespace osu.Game.Overlays.Direct
|
|||||||
{
|
{
|
||||||
loading = true;
|
loading = true;
|
||||||
|
|
||||||
LoadComponentAsync(
|
Preview = previewTrackManager.Get(beatmapSet);
|
||||||
Preview = new PreviewTrack(beatmapSet, parentOverlayContainer),
|
Preview.Started += () => Playing.Value = true;
|
||||||
t =>
|
Preview.Stopped += () => Playing.Value = false;
|
||||||
{
|
|
||||||
Preview.Started += () => Playing.Value = true;
|
LoadComponentAsync(Preview, t =>
|
||||||
Preview.Stopped += () => Playing.Value = false;
|
{
|
||||||
Preview.Start();
|
AddInternal(t);
|
||||||
loading = false;
|
|
||||||
});
|
Preview.Start();
|
||||||
|
|
||||||
|
loading = false;
|
||||||
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
if (Header.Tabs.Current.Value == DirectTab.Search && (Filter.Search.Text == string.Empty || currentQuery == string.Empty)) return;
|
if (Header.Tabs.Current.Value == DirectTab.Search && (Filter.Search.Text == string.Empty || currentQuery == string.Empty)) return;
|
||||||
|
|
||||||
previewTrackManager.CurrentTrack?.Stop(this);
|
previewTrackManager.Stop(this);
|
||||||
|
|
||||||
getSetsRequest = new SearchBeatmapSetsRequest(currentQuery.Value ?? string.Empty,
|
getSetsRequest = new SearchBeatmapSetsRequest(currentQuery.Value ?? string.Empty,
|
||||||
((FilterControl)Filter).Ruleset.Value,
|
((FilterControl)Filter).Ruleset.Value,
|
||||||
@ -289,12 +289,6 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
private int distinctCount(List<string> list) => list.Distinct().ToArray().Length;
|
private int distinctCount(List<string> list) => list.Distinct().ToArray().Length;
|
||||||
|
|
||||||
protected override void PopOut()
|
|
||||||
{
|
|
||||||
previewTrackManager.CurrentTrack?.Stop(this);
|
|
||||||
base.PopOut();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ResultCounts
|
public class ResultCounts
|
||||||
{
|
{
|
||||||
public readonly int Artists;
|
public readonly int Artists;
|
||||||
|
@ -8,7 +8,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Game.Audio;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
@ -31,7 +30,6 @@ namespace osu.Game.Overlays
|
|||||||
protected ProfileHeader Header;
|
protected ProfileHeader Header;
|
||||||
private SectionsContainer<ProfileSection> sectionsContainer;
|
private SectionsContainer<ProfileSection> sectionsContainer;
|
||||||
private ProfileTabControl tabs;
|
private ProfileTabControl tabs;
|
||||||
private PreviewTrackManager previewTrackManager;
|
|
||||||
|
|
||||||
public const float CONTENT_X_MARGIN = 50;
|
public const float CONTENT_X_MARGIN = 50;
|
||||||
|
|
||||||
@ -58,10 +56,9 @@ namespace osu.Game.Overlays
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(APIAccess api, PreviewTrackManager previewTrackManager)
|
private void load(APIAccess api)
|
||||||
{
|
{
|
||||||
this.api = api;
|
this.api = api;
|
||||||
this.previewTrackManager = previewTrackManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopIn()
|
protected override void PopIn()
|
||||||
@ -73,7 +70,6 @@ namespace osu.Game.Overlays
|
|||||||
protected override void PopOut()
|
protected override void PopOut()
|
||||||
{
|
{
|
||||||
base.PopOut();
|
base.PopOut();
|
||||||
previewTrackManager.CurrentTrack?.Stop(this);
|
|
||||||
FadeEdgeEffectTo(0, WaveContainer.DISAPPEAR_DURATION, Easing.Out);
|
FadeEdgeEffectTo(0, WaveContainer.DISAPPEAR_DURATION, Easing.Out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user