diff --git a/osu-resources b/osu-resources index 4f9ed4e703..f85c594c18 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit 4f9ed4e703777ede98737c7e2af31efa4694c395 +Subproject commit f85c594c182db2b01233e29ca52639b7baa00402 diff --git a/osu.Game.Modes.Osu/UI/OsuPlayfield.cs b/osu.Game.Modes.Osu/UI/OsuPlayfield.cs index 7f7ec2d161..5caaaafb13 100644 --- a/osu.Game.Modes.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Modes.Osu/UI/OsuPlayfield.cs @@ -12,7 +12,6 @@ using System.Linq; using osu.Game.Graphics.Cursor; using osu.Game.Modes.Osu.Judgements; -using OpenTK.Graphics; namespace osu.Game.Modes.Osu.UI { @@ -63,7 +62,7 @@ public OsuPlayfield() : base(512) protected override void LoadComplete() { base.LoadComplete(); - AddInternal(new OsuCursorContainer { Colour = Color4.LightYellow }); + AddInternal(new GameplayCursor()); } public override void Add(DrawableHitObject h) diff --git a/osu.Game/Graphics/Cursor/GameplayCursor.cs b/osu.Game/Graphics/Cursor/GameplayCursor.cs new file mode 100644 index 0000000000..a544a8e1bb --- /dev/null +++ b/osu.Game/Graphics/Cursor/GameplayCursor.cs @@ -0,0 +1,131 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Transforms; +using osu.Framework.Input; +using osu.Game.Configuration; +using System; + +namespace osu.Game.Graphics.Cursor +{ + public class GameplayCursor : CursorContainer + { + protected override Drawable CreateCursor() => new OsuCursor(); + + public GameplayCursor() + { + Add(new CursorTrail { Depth = 1 }); + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + ActiveCursor.Scale = new Vector2(1); + ActiveCursor.ScaleTo(1.2f, 100, EasingTypes.OutQuad); + return base.OnMouseDown(state, args); + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + if (!state.Mouse.HasMainButtonPressed) + ActiveCursor.ScaleTo(1, 200, EasingTypes.OutQuad); + return base.OnMouseUp(state, args); + } + + public class OsuCursor : Container + { + private Container cursorContainer; + private Bindable cursorScale; + + public OsuCursor() + { + Origin = Anchor.Centre; + Size = new Vector2(42); + } + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + cursorScale = config.GetBindable(OsuConfig.CursorSize); + + Children = new Drawable[] + { + cursorContainer = new CircularContainer + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Scale = new Vector2((float)cursorScale), + Masking = true, + BorderThickness = Size.X / 6, + BorderColour = Color4.White, + EdgeEffect = new EdgeEffect + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Pink.Opacity(0.5f), + Radius = 5, + }, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true, + }, + new CircularContainer + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Masking = true, + BorderThickness = Size.X / 3, + BorderColour = Color4.White.Opacity(0.5f), + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true, + }, + }, + }, + new CircularContainer + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Scale = new Vector2(0.1f), + Masking = true, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + }, + }, + }, + } + }, + }; + + cursorScale.ValueChanged += scaleChanged; + } + + private void scaleChanged(object sender, EventArgs e) + { + cursorContainer.Scale = new Vector2((float)cursorScale); + } + } + } +} diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs new file mode 100644 index 0000000000..1447fa9417 --- /dev/null +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -0,0 +1,121 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input; +using osu.Game.Configuration; +using System; +using osu.Framework.Graphics.Textures; +using osu.Framework.Graphics.Transforms; + +namespace osu.Game.Graphics.Cursor +{ + public class MenuCursor : CursorContainer + { + protected override Drawable CreateCursor() => new Cursor(); + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + ActiveCursor.Scale = new Vector2(1); + ActiveCursor.ScaleTo(0.90f, 800, EasingTypes.OutQuint); + + ((Cursor)ActiveCursor).AdditiveLayer.Alpha = 0; + ((Cursor)ActiveCursor).AdditiveLayer.FadeInFromZero(800, EasingTypes.OutQuint); + return base.OnMouseDown(state, args); + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + if (!state.Mouse.HasMainButtonPressed) + { + ((Cursor)ActiveCursor).AdditiveLayer.FadeOut(500, EasingTypes.OutQuint); + ActiveCursor.RotateTo(0, 200, EasingTypes.OutQuint); + ActiveCursor.ScaleTo(1, 500, EasingTypes.OutElastic); + } + + return base.OnMouseUp(state, args); + } + + protected override bool OnClick(InputState state) + { + ((Cursor)ActiveCursor).AdditiveLayer.FadeOutFromOne(500, EasingTypes.OutQuint); + + return base.OnClick(state); + } + + protected override bool OnDragStart(InputState state) + { + ActiveCursor.RotateTo(-30, 600, EasingTypes.OutElastic); + return base.OnDragStart(state); + } + + protected override void PopIn() + { + ActiveCursor.FadeTo(1, 250, EasingTypes.OutQuint); + ActiveCursor.ScaleTo(1, 1000, EasingTypes.OutElastic); + } + + protected override void PopOut() + { + ActiveCursor.FadeTo(0, 1400, EasingTypes.OutQuint); + ActiveCursor.ScaleTo(1.1f, 100, EasingTypes.Out); + ActiveCursor.Delay(100); + ActiveCursor.ScaleTo(0, 500, EasingTypes.In); + } + + public class Cursor : Container + { + private Container cursorContainer; + private Bindable cursorScale; + + public Sprite AdditiveLayer; + + public Cursor() + { + Size = new Vector2(42); + } + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config, TextureStore textures, OsuColour colour) + { + cursorScale = config.GetBindable(OsuConfig.CursorSize); + + Children = new Drawable[] + { + cursorContainer = new Container + { + Size = new Vector2(32), + Children = new Drawable[] + { + new Sprite + { + FillMode = FillMode.Fit, + Texture = textures.Get(@"Cursor/menu-cursor"), + }, + AdditiveLayer = new Sprite + { + FillMode = FillMode.Fit, + BlendingMode = BlendingMode.Additive, + Colour = colour.Pink, + Alpha = 0, + Texture = textures.Get(@"Cursor/menu-cursor-additive"), + }, + } + } + }; + cursorScale.ValueChanged += scaleChanged; + } + + private void scaleChanged(object sender, EventArgs e) + { + cursorContainer.Scale = new Vector2((float)cursorScale); + } + } + } +} diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 8aa3a63d26..9bd2ef9f75 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -220,7 +220,7 @@ protected override void LoadComplete() } }; - Cursor.Alpha = 0; + Cursor.State = Visibility.Hidden; } private bool globalHotkeyPressed(InputState state, KeyDownEventArgs args) @@ -264,10 +264,20 @@ private bool globalHotkeyPressed(InputState state, KeyDownEventArgs args) private Container overlayContent; + private OsuScreen currentScreen; + private void screenChanged(Screen newScreen) { + currentScreen = newScreen as OsuScreen; + + if (currentScreen == null) + { + Exit(); + return; + } + //central game mode change logic. - if ((newScreen as OsuScreen)?.ShowOverlays != true) + if (!currentScreen.ShowOverlays) { Toolbar.State = Visibility.Hidden; musicController.State = Visibility.Hidden; @@ -278,13 +288,7 @@ private void screenChanged(Screen newScreen) Toolbar.State = Visibility.Visible; } - if (newScreen is MainMenu) - Cursor.FadeIn(100); - ScreenChanged?.Invoke(newScreen); - - if (newScreen == null) - Exit(); } protected override bool OnExiting() @@ -308,6 +312,8 @@ protected override void UpdateAfterChildren() if (intro?.ChildScreen != null) intro.ChildScreen.Padding = new MarginPadding { Top = Toolbar.Position.Y + Toolbar.DrawHeight }; + + Cursor.State = currentScreen == null || currentScreen.HasLocalCursorDisplayed ? Visibility.Hidden : Visibility.Visible; } private void screenAdded(Screen newScreen) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 50c8aab5ef..f454956de7 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -8,7 +8,6 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Framework.IO.Stores; using osu.Framework.Platform; using osu.Game.Beatmaps; @@ -38,7 +37,7 @@ public class OsuGameBase : Framework.Game, IOnlineComponent private RatioAdjust ratioContainer; - protected CursorContainer Cursor; + protected MenuCursor Cursor; public readonly Bindable Beatmap = new Bindable(); @@ -137,7 +136,7 @@ protected override void LoadComplete() { Children = new[] { - Cursor = new OsuCursorContainer { Depth = float.MinValue } + Cursor = new MenuCursor { Depth = float.MinValue } } }); } diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index 58e86bd069..6ae237f66c 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -21,6 +21,8 @@ internal class Disclaimer : OsuScreen internal override bool ShowOverlays => false; + internal override bool HasLocalCursorDisplayed => false; + public Disclaimer() { ValidForResume = false; diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index 6d0cd4d821..6965707bcc 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -28,6 +28,8 @@ public class Intro : OsuScreen private SampleChannel seeya; private Track bgm; + internal override bool HasLocalCursorDisplayed => true; + internal override bool ShowOverlays => false; protected override BackgroundScreen CreateBackground() => new BackgroundScreenEmpty(); diff --git a/osu.Game/Screens/OsuGameScreen.cs b/osu.Game/Screens/OsuGameScreen.cs index 871d3a6780..736f9f96ae 100644 --- a/osu.Game/Screens/OsuGameScreen.cs +++ b/osu.Game/Screens/OsuGameScreen.cs @@ -24,6 +24,8 @@ public abstract class OsuScreen : Screen protected new OsuGameBase Game => base.Game as OsuGameBase; + internal virtual bool HasLocalCursorDisplayed => false; + private readonly Bindable beatmap = new Bindable(); public WorkingBeatmap Beatmap diff --git a/osu.Game/Screens/Play/PauseOverlay.cs b/osu.Game/Screens/Play/PauseOverlay.cs index b862adcd53..1cc6f9cf02 100644 --- a/osu.Game/Screens/Play/PauseOverlay.cs +++ b/osu.Game/Screens/Play/PauseOverlay.cs @@ -78,6 +78,8 @@ public int Retries // Don't let mouse down events through the overlay or people can click circles while paused. protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => true; + protected override bool OnMouseMove(InputState state) => true; + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { if (args.Key == Key.Escape) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 674a741d8c..bd54e6e263 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -32,6 +32,10 @@ public class Player : OsuScreen internal override bool ShowOverlays => false; + internal override bool HasLocalCursorDisplayed => !hasReplayLoaded && !IsPaused; + + private bool hasReplayLoaded => hitRenderer.InputManager.ReplayInputHandler != null; + public BeatmapInfo BeatmapInfo; public bool IsPaused { get; private set; } @@ -304,7 +308,7 @@ protected override bool OnExiting(Screen next) { if (pauseOverlay == null) return false; - if (hitRenderer.InputManager.ReplayInputHandler != null) + if (hasReplayLoaded) return false; if (pauseOverlay.State != Visibility.Visible && !canPause) return true; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 80d5c906e0..8b0a5fd307 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -79,6 +79,7 @@ + @@ -221,7 +222,7 @@ - +