diff --git a/osu-framework b/osu-framework index eb6362eaf1..f155804739 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit eb6362eaf1317b0fa27b2c9e559bd9a0f1ce357c +Subproject commit f155804739b8bf6e8e04cbdbadca88618d325a32 diff --git a/osu.Game.Tests/Visual/TestCaseWaveContainer.cs b/osu.Game.Tests/Visual/TestCaseWaveContainer.cs new file mode 100644 index 0000000000..2163d7c3aa --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseWaveContainer.cs @@ -0,0 +1,54 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Tests.Visual +{ + [TestFixture] + public class TestCaseWaveContainer : OsuTestCase + { + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + WaveContainer container; + Add(container = new WaveContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(400), + FirstWaveColour = colours.Red, + SecondWaveColour = colours.Green, + ThirdWaveColour = colours.Blue, + FourthWaveColour = colours.Pink, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.5f), + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + TextSize = 20, + Text = @"Wave Container", + }, + }, + }); + + AddStep(@"show", container.Show); + AddStep(@"hide", container.Hide); + } + } +} diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 5ff3ddbe05..c7f555ff0f 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -84,6 +84,7 @@ namespace osu.Game.Configuration Set(OsuSetting.Version, string.Empty); Set(OsuSetting.ScreenshotFormat, ScreenshotFormat.Jpg); + Set(OsuSetting.ScreenshotCaptureMenuCursor, false); } public OsuConfigManager(Storage storage) : base(storage) @@ -128,6 +129,7 @@ namespace osu.Game.Configuration ShowConvertedBeatmaps, SpeedChangeVisualisation, Skin, - ScreenshotFormat + ScreenshotFormat, + ScreenshotCaptureMenuCursor } } diff --git a/osu.Game/Graphics/Containers/WaveContainer.cs b/osu.Game/Graphics/Containers/WaveContainer.cs new file mode 100644 index 0000000000..82432c6ee7 --- /dev/null +++ b/osu.Game/Graphics/Containers/WaveContainer.cs @@ -0,0 +1,167 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using OpenTK.Graphics; + +namespace osu.Game.Graphics.Containers +{ + public class WaveContainer : VisibilityContainer + { + public const float APPEAR_DURATION = 800; + public const float DISAPPEAR_DURATION = 500; + + private const Easing easing_show = Easing.OutSine; + private const Easing easing_hide = Easing.InSine; + + private readonly Wave firstWave; + private readonly Wave secondWave; + private readonly Wave thirdWave; + private readonly Wave fourthWave; + + private readonly Container wavesContainer; + private readonly Container contentContainer; + + protected override Container Content => contentContainer; + + public Color4 FirstWaveColour + { + get => firstWave.Colour; + set => firstWave.Colour = value; + } + + public Color4 SecondWaveColour + { + get => secondWave.Colour; + set => secondWave.Colour = value; + } + + public Color4 ThirdWaveColour + { + get => thirdWave.Colour; + set => thirdWave.Colour = value; + } + + public Color4 FourthWaveColour + { + get => fourthWave.Colour; + set => fourthWave.Colour = value; + } + + public WaveContainer() + { + Masking = true; + + AddInternal(wavesContainer = new Container + { + RelativeSizeAxes = Axes.X, + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Masking = true, + Children = new[] + { + firstWave = new Wave + { + Rotation = 13, + FinalPosition = -930, + }, + secondWave = new Wave + { + Origin = Anchor.TopRight, + Anchor = Anchor.TopRight, + Rotation = -7, + FinalPosition = -560, + }, + thirdWave = new Wave + { + Rotation = 4, + FinalPosition = -390, + }, + fourthWave = new Wave + { + Origin = Anchor.TopRight, + Anchor = Anchor.TopRight, + Rotation = -2, + FinalPosition = -220, + }, + }, + }); + + AddInternal(contentContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + }); + } + + protected override void PopIn() + { + foreach (var w in wavesContainer.Children) + w.State = Visibility.Visible; + + this.FadeIn(100, Easing.OutQuint); + contentContainer.MoveToY(0, APPEAR_DURATION, Easing.OutQuint); + + this.FadeIn(100, Easing.OutQuint); + } + + protected override void PopOut() + { + this.FadeOut(DISAPPEAR_DURATION, Easing.InQuint); + contentContainer.MoveToY(DrawHeight * 2f, DISAPPEAR_DURATION, Easing.In); + + foreach (var w in wavesContainer.Children) + w.State = Visibility.Hidden; + + this.FadeOut(DISAPPEAR_DURATION, Easing.InQuint); + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + // This is done as an optimization, such that invisible parts of the waves + // are masked away, and thus do not consume fill rate. + wavesContainer.Height = Math.Max(0, DrawHeight - (contentContainer.DrawHeight - contentContainer.Y)); + } + + private class Wave : VisibilityContainer + { + public float FinalPosition; + + protected override bool StartHidden => true; + + public Wave() + { + RelativeSizeAxes = Axes.X; + Width = 1.5f; + Masking = true; + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(50), + Radius = 20f, + }; + + Child = new Box { RelativeSizeAxes = Axes.Both }; + } + + protected override void Update() + { + base.Update(); + + // We can not use RelativeSizeAxes for Height, because the height + // of our parent diminishes as the content moves up. + Height = Parent.Parent.DrawSize.Y * 1.5f; + } + + protected override void PopIn() => this.MoveToY(FinalPosition, APPEAR_DURATION, easing_show); + protected override void PopOut() => this.MoveToY(Parent.Parent.DrawSize.Y, DISAPPEAR_DURATION, easing_hide); + } + } +} diff --git a/osu.Game/Graphics/Cursor/CursorOverrideContainer.cs b/osu.Game/Graphics/Cursor/CursorOverrideContainer.cs index 81ae3198c7..1e56cb6052 100644 --- a/osu.Game/Graphics/Cursor/CursorOverrideContainer.cs +++ b/osu.Game/Graphics/Cursor/CursorOverrideContainer.cs @@ -20,7 +20,7 @@ namespace osu.Game.Graphics.Cursor /// /// Whether any cursors can be displayed. /// - public bool CanShowCursor = true; + internal bool CanShowCursor = true; public CursorContainer Cursor { get; } public bool ProvidingUserCursor => true; diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 34d815ec14..5f57fb76b0 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -12,12 +12,16 @@ using osu.Framework.Input; using osu.Game.Configuration; using System; using System.Diagnostics; +using JetBrains.Annotations; using osu.Framework.Graphics.Textures; namespace osu.Game.Graphics.Cursor { public class MenuCursor : CursorContainer { + private readonly IBindable screenshotCursorVisibility = new Bindable(true); + public override bool IsPresent => screenshotCursorVisibility.Value && base.IsPresent; + protected override Drawable CreateCursor() => new Cursor(); private Bindable cursorRotate; @@ -25,6 +29,15 @@ namespace osu.Game.Graphics.Cursor private bool startRotation; + [BackgroundDependencyLoader(true)] + private void load([NotNull] OsuConfigManager config, [CanBeNull] ScreenshotManager screenshotManager) + { + cursorRotate = config.GetBindable(OsuSetting.CursorRotation); + + if (screenshotManager != null) + screenshotCursorVisibility.BindTo(screenshotManager.CursorVisibility); + } + protected override bool OnMouseMove(InputState state) { if (cursorRotate && dragging) @@ -104,12 +117,6 @@ namespace osu.Game.Graphics.Cursor ActiveCursor.ScaleTo(0.6f, 250, Easing.In); } - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - cursorRotate = config.GetBindable(OsuSetting.CursorRotation); - } - public class Cursor : Container { private Container cursorContainer; diff --git a/osu.Game/Graphics/ScreenshotManager.cs b/osu.Game/Graphics/ScreenshotManager.cs index 5e0b9c9340..90580c50df 100644 --- a/osu.Game/Graphics/ScreenshotManager.cs +++ b/osu.Game/Graphics/ScreenshotManager.cs @@ -4,6 +4,8 @@ using System; using System.Drawing.Imaging; using System.IO; +using System.Threading; +using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -12,6 +14,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Framework.Platform; +using osu.Framework.Threading; using osu.Game.Configuration; using osu.Game.Input.Bindings; using osu.Game.Overlays; @@ -21,7 +24,17 @@ namespace osu.Game.Graphics { public class ScreenshotManager : Container, IKeyBindingHandler, IHandleGlobalInput { + private readonly BindableBool cursorVisibility = new BindableBool(true); + + /// + /// Changed when screenshots are being or have finished being taken, to control whether cursors should be visible. + /// If cursors should not be visible, cursors have 3 frames to hide themselves. + /// + public IBindable CursorVisibility => cursorVisibility; + private Bindable screenshotFormat; + private Bindable captureMenuCursor; + private GameHost host; private Storage storage; private NotificationOverlay notificationOverlay; @@ -36,6 +49,7 @@ namespace osu.Game.Graphics this.notificationOverlay = notificationOverlay; screenshotFormat = config.GetBindable(OsuSetting.ScreenshotFormat); + captureMenuCursor = config.GetBindable(OsuSetting.ScreenshotCaptureMenuCursor); shutter = audio.Sample.Get("UI/shutter"); } @@ -55,10 +69,31 @@ namespace osu.Game.Graphics public bool OnReleased(GlobalAction action) => false; - public async void TakeScreenshotAsync() + private volatile int screenShotTasks; + + public async Task TakeScreenshotAsync() => await Task.Run(async () => { + Interlocked.Increment(ref screenShotTasks); + + if (!captureMenuCursor.Value) + { + cursorVisibility.Value = false; + + // We need to wait for at most 3 draw nodes to be drawn, following which we can be assured at least one DrawNode has been generated/drawn with the set value + const int frames_to_wait = 3; + + int framesWaited = 0; + ScheduledDelegate waitDelegate = host.DrawThread.Scheduler.AddDelayed(() => framesWaited++, 0, true); + while (framesWaited < frames_to_wait) + Thread.Sleep(10); + + waitDelegate.Cancel(); + } + using (var bitmap = await host.TakeScreenshotAsync()) { + Interlocked.Decrement(ref screenShotTasks); + var fileName = getFileName(); if (fileName == null) return; @@ -86,6 +121,14 @@ namespace osu.Game.Graphics } }); } + }); + + protected override void Update() + { + base.Update(); + + if (cursorVisibility == false && Interlocked.CompareExchange(ref screenShotTasks, 0, 0) == 0) + cursorVisibility.Value = true; } private string getFileName() diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 2d65d6738d..941e49e87e 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -60,6 +60,8 @@ namespace osu.Game private BeatmapSetOverlay beatmapSetOverlay; + private ScreenshotManager screenshotManager; + public virtual Storage GetStorageForStableInstall() => null; private Intro intro @@ -200,6 +202,9 @@ namespace osu.Game protected override void LoadComplete() { + // this needs to be cached before base.LoadComplete as it is used by CursorOverrideContainer. + dependencies.Cache(screenshotManager = new ScreenshotManager()); + base.LoadComplete(); // The next time this is updated is in UpdateAfterChildren, which occurs too late and results @@ -243,7 +248,8 @@ namespace osu.Game loadComponentSingleFile(volume = new VolumeOverlay(), overlayContent.Add); loadComponentSingleFile(onscreenDisplay = new OnScreenDisplay(), Add); - loadComponentSingleFile(new ScreenshotManager(), Add); + + loadComponentSingleFile(screenshotManager, Add); //overlay elements loadComponentSingleFile(direct = new DirectOverlay { Depth = -1 }, mainContent.Add); diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 93e10751d9..d2cf0a6ef1 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -40,10 +40,10 @@ namespace osu.Game.Overlays public BeatmapSetOverlay() { - FirstWaveColour = OsuColour.Gray(0.4f); - SecondWaveColour = OsuColour.Gray(0.3f); - ThirdWaveColour = OsuColour.Gray(0.2f); - FourthWaveColour = OsuColour.Gray(0.1f); + Waves.FirstWaveColour = OsuColour.Gray(0.4f); + Waves.SecondWaveColour = OsuColour.Gray(0.3f); + Waves.ThirdWaveColour = OsuColour.Gray(0.2f); + Waves.FourthWaveColour = OsuColour.Gray(0.1f); Anchor = Anchor.TopCentre; Origin = Anchor.TopCentre; @@ -123,14 +123,14 @@ namespace osu.Game.Overlays protected override void PopIn() { base.PopIn(); - FadeEdgeEffectTo(0.25f, APPEAR_DURATION, Easing.In); + FadeEdgeEffectTo(0.25f, WaveContainer.APPEAR_DURATION, Easing.In); } protected override void PopOut() { base.PopOut(); header.Details.StopPreview(); - FadeEdgeEffectTo(0, DISAPPEAR_DURATION, Easing.Out); + FadeEdgeEffectTo(0, WaveContainer.DISAPPEAR_DURATION, Easing.Out); } protected override bool OnClick(InputState state) diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index 9f36d5acb7..44e24d8157 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -173,8 +173,9 @@ namespace osu.Game.Overlays.Direct if (trackLoader != d) return; Preview = d?.Preview; - Playing.TriggerChange(); + updatePreviewTrack(Playing); loading = false; + Add(trackLoader); }); } diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 6c9433836a..ddc7ed3737 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -89,10 +89,10 @@ namespace osu.Game.Overlays // osu!direct colours are not part of the standard palette - FirstWaveColour = OsuColour.FromHex(@"19b0e2"); - SecondWaveColour = OsuColour.FromHex(@"2280a2"); - ThirdWaveColour = OsuColour.FromHex(@"005774"); - FourthWaveColour = OsuColour.FromHex(@"003a4e"); + Waves.FirstWaveColour = OsuColour.FromHex(@"19b0e2"); + Waves.SecondWaveColour = OsuColour.FromHex(@"2280a2"); + Waves.ThirdWaveColour = OsuColour.FromHex(@"005774"); + Waves.FourthWaveColour = OsuColour.FromHex(@"003a4e"); ScrollFlow.Children = new Drawable[] { diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 48c38c467e..632c00d1fd 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -18,6 +18,7 @@ using System.Linq; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics.Containers; using osu.Game.Rulesets; using osu.Game.Graphics.UserInterface; @@ -113,14 +114,14 @@ namespace osu.Game.Overlays.Mods { base.PopOut(); - footerContainer.MoveToX(footerContainer.DrawSize.X, DISAPPEAR_DURATION, Easing.InSine); - footerContainer.FadeOut(DISAPPEAR_DURATION, Easing.InSine); + footerContainer.MoveToX(footerContainer.DrawSize.X, WaveContainer.DISAPPEAR_DURATION, Easing.InSine); + footerContainer.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.InSine); foreach (ModSection section in ModSectionsContainer.Children) { - section.ButtonsContainer.TransformSpacingTo(new Vector2(100f, 0f), DISAPPEAR_DURATION, Easing.InSine); - section.ButtonsContainer.MoveToX(100f, DISAPPEAR_DURATION, Easing.InSine); - section.ButtonsContainer.FadeOut(DISAPPEAR_DURATION, Easing.InSine); + section.ButtonsContainer.TransformSpacingTo(new Vector2(100f, 0f), WaveContainer.DISAPPEAR_DURATION, Easing.InSine); + section.ButtonsContainer.MoveToX(100f, WaveContainer.DISAPPEAR_DURATION, Easing.InSine); + section.ButtonsContainer.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.InSine); } } @@ -128,14 +129,14 @@ namespace osu.Game.Overlays.Mods { base.PopIn(); - footerContainer.MoveToX(0, APPEAR_DURATION, Easing.OutQuint); - footerContainer.FadeIn(APPEAR_DURATION, Easing.OutQuint); + footerContainer.MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint); + footerContainer.FadeIn(WaveContainer.APPEAR_DURATION, Easing.OutQuint); foreach (ModSection section in ModSectionsContainer.Children) { - section.ButtonsContainer.TransformSpacingTo(new Vector2(50f, 0f), APPEAR_DURATION, Easing.OutQuint); - section.ButtonsContainer.MoveToX(0, APPEAR_DURATION, Easing.OutQuint); - section.ButtonsContainer.FadeIn(APPEAR_DURATION, Easing.OutQuint); + section.ButtonsContainer.TransformSpacingTo(new Vector2(50f, 0f), WaveContainer.APPEAR_DURATION, Easing.OutQuint); + section.ButtonsContainer.MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint); + section.ButtonsContainer.FadeIn(WaveContainer.APPEAR_DURATION, Easing.OutQuint); } } @@ -181,14 +182,12 @@ namespace osu.Game.Overlays.Mods public ModSelectOverlay() { - FirstWaveColour = OsuColour.FromHex(@"19b0e2"); - SecondWaveColour = OsuColour.FromHex(@"2280a2"); - ThirdWaveColour = OsuColour.FromHex(@"005774"); - FourthWaveColour = OsuColour.FromHex(@"003a4e"); + Waves.FirstWaveColour = OsuColour.FromHex(@"19b0e2"); + Waves.SecondWaveColour = OsuColour.FromHex(@"2280a2"); + Waves.ThirdWaveColour = OsuColour.FromHex(@"005774"); + Waves.FourthWaveColour = OsuColour.FromHex(@"003a4e"); Height = 510; - Content.RelativeSizeAxes = Axes.X; - Content.AutoSizeAxes = Axes.Y; Children = new Drawable[] { new Container diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index 842a13f8da..3fec9d8697 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using OpenTK; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -19,6 +20,8 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps private DirectPanel currentlyPlaying; + public event Action BeganPlayingPreview; + public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, string header, string missing = "None... yet.") : base(user, header, missing) { @@ -56,17 +59,25 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps panel.PreviewPlaying.ValueChanged += isPlaying => { - if (!isPlaying) return; + StopPlayingPreview(); - if (currentlyPlaying != null && currentlyPlaying != panel) - currentlyPlaying.PreviewPlaying.Value = false; - - currentlyPlaying = panel; + if (isPlaying) + { + BeganPlayingPreview?.Invoke(this); + currentlyPlaying = panel; + } }; } }; Api.Queue(req); } + + public void StopPlayingPreview() + { + if (currentlyPlaying == null) return; + currentlyPlaying.PreviewPlaying.Value = false; + currentlyPlaying = null; + } } } diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs index 367d096c16..92abd20f93 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Linq; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Profile.Sections.Beatmaps; @@ -21,6 +22,15 @@ namespace osu.Game.Overlays.Profile.Sections new PaginatedBeatmapContainer(BeatmapSetType.Unranked, User, "Pending Beatmaps"), new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, User, "Graveyarded Beatmaps"), }; + + foreach (var paginatedBeatmapContainer in Children.OfType()) + { + paginatedBeatmapContainer.BeganPlayingPreview += _ => + { + foreach (var bc in Children.OfType()) + bc.StopPlayingPreview(); + }; + } } } } diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs index a78cb29468..54049bfb1f 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs @@ -30,6 +30,11 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics { LabelText = "Screenshot format", Bindable = config.GetBindable(OsuSetting.ScreenshotFormat) + }, + new SettingsCheckbox + { + LabelText = "Show menu cursor in screenshots", + Bindable = config.GetBindable(OsuSetting.ScreenshotCaptureMenuCursor) } }; } diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index d224d4c92d..222035ab65 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -48,10 +48,10 @@ namespace osu.Game.Overlays public SocialOverlay() { - FirstWaveColour = OsuColour.FromHex(@"cb5fa0"); - SecondWaveColour = OsuColour.FromHex(@"b04384"); - ThirdWaveColour = OsuColour.FromHex(@"9b2b6e"); - FourthWaveColour = OsuColour.FromHex(@"6d214d"); + Waves.FirstWaveColour = OsuColour.FromHex(@"cb5fa0"); + Waves.SecondWaveColour = OsuColour.FromHex(@"b04384"); + Waves.ThirdWaveColour = OsuColour.FromHex(@"9b2b6e"); + Waves.FourthWaveColour = OsuColour.FromHex(@"6d214d"); Add(loading = new LoadingAnimation()); diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index c6e8c60f92..a4dd0c9ec3 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -35,10 +35,10 @@ namespace osu.Game.Overlays public UserProfileOverlay() { - FirstWaveColour = OsuColour.Gray(0.4f); - SecondWaveColour = OsuColour.Gray(0.3f); - ThirdWaveColour = OsuColour.Gray(0.2f); - FourthWaveColour = OsuColour.Gray(0.1f); + Waves.FirstWaveColour = OsuColour.Gray(0.4f); + Waves.SecondWaveColour = OsuColour.Gray(0.3f); + Waves.ThirdWaveColour = OsuColour.Gray(0.2f); + Waves.FourthWaveColour = OsuColour.Gray(0.1f); RelativeSizeAxes = Axes.Both; RelativePositionAxes = Axes.Both; @@ -64,13 +64,13 @@ namespace osu.Game.Overlays protected override void PopIn() { base.PopIn(); - FadeEdgeEffectTo(0.5f, APPEAR_DURATION, Easing.In); + FadeEdgeEffectTo(0.5f, WaveContainer.APPEAR_DURATION, Easing.In); } protected override void PopOut() { base.PopOut(); - FadeEdgeEffectTo(0, DISAPPEAR_DURATION, Easing.Out); + FadeEdgeEffectTo(0, WaveContainer.DISAPPEAR_DURATION, Easing.Out); } public void ShowUser(long userId) diff --git a/osu.Game/Overlays/WaveOverlayContainer.cs b/osu.Game/Overlays/WaveOverlayContainer.cs index 6a083a77e5..97f52d88f7 100644 --- a/osu.Game/Overlays/WaveOverlayContainer.cs +++ b/osu.Game/Overlays/WaveOverlayContainer.cs @@ -1,203 +1,37 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK.Graphics; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; -using System; -using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Containers; namespace osu.Game.Overlays { public abstract class WaveOverlayContainer : OsuFocusedOverlayContainer { - protected const float APPEAR_DURATION = 800; - protected const float DISAPPEAR_DURATION = 500; - - private const Easing easing_show = Easing.OutSine; - private const Easing easing_hide = Easing.InSine; - - private readonly Wave firstWave; - private readonly Wave secondWave; - private readonly Wave thirdWave; - private readonly Wave fourthWave; - - private readonly Container wavesContainer; - - private readonly Container contentContainer; + protected readonly WaveContainer Waves; protected override bool BlockPassThroughKeyboard => true; - - protected override Container Content => contentContainer; - - protected Color4 FirstWaveColour - { - get - { - return firstWave.Colour; - } - set - { - if (firstWave.Colour == value) return; - firstWave.Colour = value; - } - } - - protected Color4 SecondWaveColour - { - get - { - return secondWave.Colour; - } - set - { - if (secondWave.Colour == value) return; - secondWave.Colour = value; - } - } - - protected Color4 ThirdWaveColour - { - get - { - return thirdWave.Colour; - } - set - { - if (thirdWave.Colour == value) return; - thirdWave.Colour = value; - } - } - - protected Color4 FourthWaveColour - { - get - { - return fourthWave.Colour; - } - set - { - if (fourthWave.Colour == value) return; - fourthWave.Colour = value; - } - } + protected override Container Content => Waves; protected WaveOverlayContainer() { - Masking = true; - - AddInternal(wavesContainer = new Container - { - RelativeSizeAxes = Axes.X, - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Masking = true, - Children = new[] - { - firstWave = new Wave - { - Rotation = 13, - FinalPosition = -930, - }, - secondWave = new Wave - { - Origin = Anchor.TopRight, - Anchor = Anchor.TopRight, - Rotation = -7, - FinalPosition = -560, - }, - thirdWave = new Wave - { - Rotation = 4, - FinalPosition = -390, - }, - fourthWave = new Wave - { - Origin = Anchor.TopRight, - Anchor = Anchor.TopRight, - Rotation = -2, - FinalPosition = -220, - }, - }, - }); - - AddInternal(contentContainer = new Container + AddInternal(Waves = new WaveContainer { RelativeSizeAxes = Axes.Both, - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, }); } protected override void PopIn() { base.PopIn(); - - foreach (var w in wavesContainer.Children) - w.State = Visibility.Visible; - - this.FadeIn(100, Easing.OutQuint); - contentContainer.MoveToY(0, APPEAR_DURATION, Easing.OutQuint); - - this.FadeIn(100, Easing.OutQuint); + Waves.Show(); } protected override void PopOut() { base.PopOut(); - - this.FadeOut(DISAPPEAR_DURATION, Easing.InQuint); - contentContainer.MoveToY(DrawHeight * 2f, DISAPPEAR_DURATION, Easing.In); - - foreach (var w in wavesContainer.Children) - w.State = Visibility.Hidden; - - this.FadeOut(DISAPPEAR_DURATION, Easing.InQuint); - } - - protected override void UpdateAfterChildren() - { - base.UpdateAfterChildren(); - - // This is done as an optimization, such that invisible parts of the waves - // are masked away, and thus do not consume fill rate. - wavesContainer.Height = Math.Max(0, DrawHeight - (contentContainer.DrawHeight - contentContainer.Y)); - } - - private class Wave : VisibilityContainer - { - public float FinalPosition; - - protected override bool StartHidden => true; - - public Wave() - { - RelativeSizeAxes = Axes.X; - Width = 1.5f; - Masking = true; - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(50), - Radius = 20f, - }; - - Child = new Box { RelativeSizeAxes = Axes.Both }; - } - - protected override void Update() - { - base.Update(); - - // We can not use RelativeSizeAxes for Height, because the height - // of our parent diminishes as the content moves up. - Height = Parent.Parent.DrawSize.Y * 1.5f; - } - - protected override void PopIn() => this.MoveToY(FinalPosition, APPEAR_DURATION, easing_show); - protected override void PopOut() => this.MoveToY(Parent.Parent.DrawSize.Y, DISAPPEAR_DURATION, easing_hide); + Waves.Hide(); } } }