From 5787b435869b5b6bd6d1e3f950a8ae0b804e7c04 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 27 Jan 2017 19:14:44 +0900 Subject: [PATCH 1/3] wip --- osu.Game/Graphics/UserInterface/SkipButton.cs | 53 +++++++++++++++++++ osu.Game/Screens/Play/Player.cs | 3 +- osu.Game/osu.Game.csproj | 1 + 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Graphics/UserInterface/SkipButton.cs diff --git a/osu.Game/Graphics/UserInterface/SkipButton.cs b/osu.Game/Graphics/UserInterface/SkipButton.cs new file mode 100644 index 0000000000..856506d306 --- /dev/null +++ b/osu.Game/Graphics/UserInterface/SkipButton.cs @@ -0,0 +1,53 @@ +using System; +using OpenTK.Graphics; +using OpenTK.Input; +using osu.Framework.Graphics; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input; +using osu.Framework.Timing; + +namespace osu.Game.Graphics.UserInterface +{ + class SkipButton : Button + { + private IAdjustableClock sourceClock; + private double time; + public SkipButton(IAdjustableClock clock, double time) + { + Height = 60; + Width = 100; + Text = "skip"; + Colour = new Color4(238, 51, 153, 255); + Action = skip; + sourceClock = clock; + this.time = time; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Delay(time - 3000, true); + Content.FadeOut(250); + } + + private void skip() + { + sourceClock.Seek(time - 3000); + FadeOut(250); + } + + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + switch (args.Key) + { + case Key.Space: + if(sourceClock.CurrentTime + 3000 < time) + skip(); + return true; + } + + return base.OnKeyDown(state, args); + } + } +} diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d6594dd2be..9ec00c3215 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -12,7 +12,6 @@ using osu.Framework.Platform; using osu.Framework.Timing; using osu.Game.Database; using osu.Game.Modes; -using osu.Game.Modes.Objects; using osu.Game.Modes.Objects.Drawables; using osu.Game.Screens.Backgrounds; using OpenTK.Input; @@ -24,6 +23,7 @@ using osu.Game.Screens.Ranking; using osu.Game.Configuration; using osu.Framework.Configuration; using System; +using osu.Game.Graphics.UserInterface; using OpenTK.Graphics; namespace osu.Game.Screens.Play @@ -119,6 +119,7 @@ namespace osu.Game.Screens.Play } }, scoreOverlay, + new SkipButton(sourceClock, beatmap.HitObjects.First().StartTime) }; } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index a90fa2a8cb..c19af7f784 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -67,6 +67,7 @@ + From 420e61fa97df8e1a4b22b36678fddacdb872706f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 27 Jan 2017 21:08:36 +0900 Subject: [PATCH 2/3] TwoLayerButton --- .../Tests/TestCaseTwoLayerButton.cs | 27 ++ .../osu.Desktop.VisualTests.csproj | 1 + osu.Game/Graphics/UserInterface/BackButton.cs | 241 +++++++++++++----- osu.Game/Graphics/UserInterface/SkipButton.cs | 53 ---- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/osu.Game.csproj | 1 - 6 files changed, 205 insertions(+), 120 deletions(-) create mode 100644 osu.Desktop.VisualTests/Tests/TestCaseTwoLayerButton.cs delete mode 100644 osu.Game/Graphics/UserInterface/SkipButton.cs diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTwoLayerButton.cs b/osu.Desktop.VisualTests/Tests/TestCaseTwoLayerButton.cs new file mode 100644 index 0000000000..eded8cbeb0 --- /dev/null +++ b/osu.Desktop.VisualTests/Tests/TestCaseTwoLayerButton.cs @@ -0,0 +1,27 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.GameModes.Testing; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Screens.Menu; +using OpenTK.Graphics; + +namespace osu.Desktop.VisualTests.Tests +{ + class TestCaseTwoLayerButton : TestCase + { + public override string Name => @"TwoLayerButton"; + public override string Description => @"Back and skip and what not"; + + public override void Reset() + { + base.Reset(); + + Add(new BackButton()); + Add(new SkipButton()); + + } + } +} diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 70dd0fee46..7d03a16e42 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -183,6 +183,7 @@ + diff --git a/osu.Game/Graphics/UserInterface/BackButton.cs b/osu.Game/Graphics/UserInterface/BackButton.cs index d246b421a2..4a7dfdae93 100644 --- a/osu.Game/Graphics/UserInterface/BackButton.cs +++ b/osu.Game/Graphics/UserInterface/BackButton.cs @@ -9,34 +9,195 @@ using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Transformations; using osu.Framework.Input; namespace osu.Game.Graphics.UserInterface { - // Basic back button as it was on stable (kinda). No skinning possible for now - public class BackButton : ClickableContainer + public class BackButton : TwoLayerButton + { + public BackButton() + { + Text = @"Back"; + Icon = FontAwesome.fa_osu_left_o; + Anchor = Anchor.BottomLeft; + Origin = Anchor.BottomLeft; + } + + [BackgroundDependencyLoader] + private void load(AudioManager audio, OsuColour colours) + { + ActivationSound = audio.Sample.Get(@"Menu/menuback"); + Colour = colours.Pink; + HoverColour = colours.PinkDark; + } + } + + public class SkipButton : TwoLayerButton + { + public SkipButton() + { + Text = @"Skip"; + Icon = FontAwesome.fa_osu_right_o; + Anchor = Anchor.BottomRight; + Origin = Anchor.BottomRight; + } + + [BackgroundDependencyLoader] + private void load(AudioManager audio, OsuColour colours) + { + ActivationSound = audio.Sample.Get(@"Menu/menuhit"); + Colour = colours.Yellow; + HoverColour = colours.YellowDark; + } + } + + public class TwoLayerButton : ClickableContainer { private TextAwesome icon; - private Box leftBox; - private Box rightBox; + public Box IconLayer; + public Box TextLayer; - private const double transform_time = 600; + private const int transform_time = 600; private const int pulse_length = 250; private const float shear = 0.1f; public static readonly Vector2 SIZE_EXTENDED = new Vector2(140, 50); - public static readonly Vector2 SIZE_RETRACTED = new Vector2(100, 50); - private AudioSample sampleClick; + public static readonly Vector2 SIZE_RETRACTED = new Vector2(100, 50); + public AudioSample ActivationSound; + private SpriteText text; - public BackButton() + public Color4 HoverColour; + private Container c1; + private Container c2; + + public Color4 Colour { - Size = SIZE_RETRACTED; + set + { + TextLayer.Colour = value; + IconLayer.Colour = value; + } } - public override bool Contains(Vector2 screenSpacePos) => leftBox.Contains(screenSpacePos) || rightBox.Contains(screenSpacePos); + public override Anchor Origin + { + get + { + return base.Origin; + } + + set + { + base.Origin = value; + c1.Origin = c1.Anchor = (value & Anchor.x2) > 0 ? Anchor.TopLeft : Anchor.TopRight; + c2.Origin = c2.Anchor = (value & Anchor.x2) > 0 ? Anchor.TopRight : Anchor.TopLeft; + + Margin = new MarginPadding + { + Right = (value & Anchor.x2) > 0 ? -SIZE_RETRACTED.X * shear * 0.5f : 0 + }; + + c1.Depth = (value & Anchor.x2) > 0 ? 0 : 1; + c2.Depth = (value & Anchor.x2) > 0 ? 1 : 0; + } + } + + public TwoLayerButton() + { + Size = SIZE_RETRACTED; + + Children = new Drawable[] + { + c2 = new Container + { + RelativeSizeAxes = Axes.Both, + Width = 0.4f, + Children = new Drawable[] + { + new Container { + RelativeSizeAxes = Axes.Both, + Shear = new Vector2(shear, 0), + Masking = true, + EdgeEffect = new EdgeEffect { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.2f), + Offset = new Vector2(2, 0), + Radius = 2, + }, + Children = new [] { + IconLayer = new Box + { + RelativeSizeAxes = Axes.Both, + EdgeSmoothness = new Vector2(1.5f, 0), + }, + } + }, + icon = new TextAwesome + { + Anchor = Anchor.Centre, + TextSize = 25, + }, + } + }, + c1 = new Container + { + Origin = Anchor.TopRight, + Anchor = Anchor.TopRight, + RelativeSizeAxes = Axes.Both, + Width = 0.6f, + Children = new Drawable[] + { + new Container { + RelativeSizeAxes = Axes.Both, + Shear = new Vector2(shear, 0), + Masking = true, + EdgeEffect = new EdgeEffect { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.2f), + Offset = new Vector2(2, 0), + Radius = 2, + }, + Children = new [] { + TextLayer = new Box + { + Origin = Anchor.TopLeft, + Anchor = Anchor.TopLeft, + RelativeSizeAxes = Axes.Both, + EdgeSmoothness = new Vector2(1.5f, 0), + }, + } + }, + text = new SpriteText + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + } + } + }, + }; + } + + public FontAwesome Icon + { + set + { + icon.Icon = value; + } + } + + public string Text + { + set + { + text.Text = value; + } + } + + public override bool Contains(Vector2 screenSpacePos) => IconLayer.Contains(screenSpacePos) || TextLayer.Contains(screenSpacePos); protected override bool OnHover(InputState state) { @@ -47,6 +208,8 @@ namespace osu.Game.Graphics.UserInterface int duration = 0; //(int)(Game.Audio.BeatLength / 2); if (duration == 0) duration = pulse_length; + IconLayer.FadeColour(HoverColour, transform_time, EasingTypes.OutElastic); + double offset = 0; //(1 - Game.Audio.SyncBeatProgress) * duration; double startTime = Time.Current + offset; @@ -71,6 +234,8 @@ namespace osu.Game.Graphics.UserInterface ResizeTo(SIZE_RETRACTED, transform_time, EasingTypes.OutElastic); + IconLayer.FadeColour(TextLayer.Colour, transform_time, EasingTypes.OutElastic); + int duration = 0; //(int)(Game.Audio.BeatLength); if (duration == 0) duration = pulse_length * 2; @@ -90,60 +255,6 @@ namespace osu.Game.Graphics.UserInterface }); } - [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuColour colours) - { - sampleClick = audio.Sample.Get(@"Menu/menuback"); - Children = new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - Width = 0.4f, - Children = new Drawable[] - { - leftBox = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colours.PinkDark, - Shear = new Vector2(shear, 0), - }, - icon = new TextAwesome - { - Anchor = Anchor.Centre, - TextSize = 25, - Icon = FontAwesome.fa_osu_left_o - }, - } - }, - new Container - { - Origin = Anchor.TopRight, - Anchor = Anchor.TopRight, - RelativeSizeAxes = Axes.Both, - Width = 0.6f, - Children = new Drawable[] - { - rightBox = new Box - { - Colour = colours.Pink, - Origin = Anchor.TopLeft, - Anchor = Anchor.TopLeft, - RelativeSizeAxes = Axes.Both, - Shear = new Vector2(shear, 0), - EdgeSmoothness = new Vector2(1.5f, 0), - }, - new SpriteText - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Text = @"Back", - } - } - } - }; - } - protected override bool OnClick(InputState state) { var flash = new Box @@ -157,7 +268,7 @@ namespace osu.Game.Graphics.UserInterface flash.FadeOutFromOne(200); flash.Expire(); - sampleClick.Play(); + ActivationSound.Play(); return base.OnClick(state); } diff --git a/osu.Game/Graphics/UserInterface/SkipButton.cs b/osu.Game/Graphics/UserInterface/SkipButton.cs deleted file mode 100644 index 856506d306..0000000000 --- a/osu.Game/Graphics/UserInterface/SkipButton.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using OpenTK.Graphics; -using OpenTK.Input; -using osu.Framework.Graphics; -using osu.Framework.Graphics.UserInterface; -using osu.Framework.Input; -using osu.Framework.Timing; - -namespace osu.Game.Graphics.UserInterface -{ - class SkipButton : Button - { - private IAdjustableClock sourceClock; - private double time; - public SkipButton(IAdjustableClock clock, double time) - { - Height = 60; - Width = 100; - Text = "skip"; - Colour = new Color4(238, 51, 153, 255); - Action = skip; - sourceClock = clock; - this.time = time; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - Delay(time - 3000, true); - Content.FadeOut(250); - } - - private void skip() - { - sourceClock.Seek(time - 3000); - FadeOut(250); - } - - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) - { - switch (args.Key) - { - case Key.Space: - if(sourceClock.CurrentTime + 3000 < time) - skip(); - return true; - } - - return base.OnKeyDown(state, args); - } - } -} diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 9ec00c3215..e06dfb18dc 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -119,7 +119,7 @@ namespace osu.Game.Screens.Play } }, scoreOverlay, - new SkipButton(sourceClock, beatmap.HitObjects.First().StartTime) + //new SkipButton(sourceClock, beatmap.HitObjects.First().StartTime) }; } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index c19af7f784..a90fa2a8cb 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -67,7 +67,6 @@ - From 3e7503e860b46bdd485d34a81ef4be06e8b90b29 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 27 Jan 2017 21:57:22 +0900 Subject: [PATCH 3/3] Make skip button work. --- .../Tests/TestCaseKeyCounter.cs | 1 + .../Tests/TestCaseTwoLayerButton.cs | 2 +- osu.Game.Modes.Osu/UI/OsuScoreOverlay.cs | 1 + osu.Game/Graphics/UserInterface/BackButton.cs | 248 ------------------ .../Graphics/UserInterface/TwoLayerButton.cs | 237 +++++++++++++++++ osu.Game/Modes/UI/ScoreOverlay.cs | 1 + .../Play}/KeyCounter.cs | 7 +- .../Play}/KeyCounterCollection.cs | 4 +- .../Play}/KeyCounterKeyboard.cs | 4 +- .../Play}/KeyCounterMouse.cs | 6 +- osu.Game/Screens/Play/Player.cs | 39 ++- osu.Game/Screens/Play/SkipButton.cs | 32 +++ osu.Game/osu.Game.csproj | 10 +- 13 files changed, 321 insertions(+), 271 deletions(-) create mode 100644 osu.Game/Graphics/UserInterface/TwoLayerButton.cs rename osu.Game/{Graphics/UserInterface => Screens/Play}/KeyCounter.cs (95%) rename osu.Game/{Graphics/UserInterface => Screens/Play}/KeyCounterCollection.cs (95%) rename osu.Game/{Graphics/UserInterface => Screens/Play}/KeyCounterKeyboard.cs (92%) rename osu.Game/{Graphics/UserInterface => Screens/Play}/KeyCounterMouse.cs (92%) create mode 100644 osu.Game/Screens/Play/SkipButton.cs diff --git a/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs b/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs index e83cda77ee..1f25da39c1 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs @@ -13,6 +13,7 @@ using OpenTK.Graphics; using osu.Framework.MathUtils; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Transformations; +using osu.Game.Screens.Play; namespace osu.Desktop.VisualTests.Tests { diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTwoLayerButton.cs b/osu.Desktop.VisualTests/Tests/TestCaseTwoLayerButton.cs index eded8cbeb0..2edb6d6a55 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseTwoLayerButton.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseTwoLayerButton.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Menu; +using osu.Game.Screens.Play; using OpenTK.Graphics; namespace osu.Desktop.VisualTests.Tests @@ -21,7 +22,6 @@ namespace osu.Desktop.VisualTests.Tests Add(new BackButton()); Add(new SkipButton()); - } } } diff --git a/osu.Game.Modes.Osu/UI/OsuScoreOverlay.cs b/osu.Game.Modes.Osu/UI/OsuScoreOverlay.cs index 36a1f1c100..445cdd35a3 100644 --- a/osu.Game.Modes.Osu/UI/OsuScoreOverlay.cs +++ b/osu.Game.Modes.Osu/UI/OsuScoreOverlay.cs @@ -7,6 +7,7 @@ using osu.Game.Modes.UI; using OpenTK; using OpenTK.Input; using osu.Framework.Graphics.Primitives; +using osu.Game.Screens.Play; namespace osu.Game.Modes.Osu.UI { diff --git a/osu.Game/Graphics/UserInterface/BackButton.cs b/osu.Game/Graphics/UserInterface/BackButton.cs index 4a7dfdae93..636697c3d5 100644 --- a/osu.Game/Graphics/UserInterface/BackButton.cs +++ b/osu.Game/Graphics/UserInterface/BackButton.cs @@ -3,15 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Audio.Sample; -using OpenTK; -using OpenTK.Graphics; using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Primitives; -using osu.Framework.Graphics.Transformations; -using osu.Framework.Input; namespace osu.Game.Graphics.UserInterface { @@ -33,244 +25,4 @@ namespace osu.Game.Graphics.UserInterface HoverColour = colours.PinkDark; } } - - public class SkipButton : TwoLayerButton - { - public SkipButton() - { - Text = @"Skip"; - Icon = FontAwesome.fa_osu_right_o; - Anchor = Anchor.BottomRight; - Origin = Anchor.BottomRight; - } - - [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuColour colours) - { - ActivationSound = audio.Sample.Get(@"Menu/menuhit"); - Colour = colours.Yellow; - HoverColour = colours.YellowDark; - } - } - - public class TwoLayerButton : ClickableContainer - { - private TextAwesome icon; - - public Box IconLayer; - public Box TextLayer; - - private const int transform_time = 600; - private const int pulse_length = 250; - - private const float shear = 0.1f; - - public static readonly Vector2 SIZE_EXTENDED = new Vector2(140, 50); - public static readonly Vector2 SIZE_RETRACTED = new Vector2(100, 50); - public AudioSample ActivationSound; - private SpriteText text; - - public Color4 HoverColour; - private Container c1; - private Container c2; - - public Color4 Colour - { - set - { - TextLayer.Colour = value; - IconLayer.Colour = value; - } - } - - public override Anchor Origin - { - get - { - return base.Origin; - } - - set - { - base.Origin = value; - c1.Origin = c1.Anchor = (value & Anchor.x2) > 0 ? Anchor.TopLeft : Anchor.TopRight; - c2.Origin = c2.Anchor = (value & Anchor.x2) > 0 ? Anchor.TopRight : Anchor.TopLeft; - - Margin = new MarginPadding - { - Right = (value & Anchor.x2) > 0 ? -SIZE_RETRACTED.X * shear * 0.5f : 0 - }; - - c1.Depth = (value & Anchor.x2) > 0 ? 0 : 1; - c2.Depth = (value & Anchor.x2) > 0 ? 1 : 0; - } - } - - public TwoLayerButton() - { - Size = SIZE_RETRACTED; - - Children = new Drawable[] - { - c2 = new Container - { - RelativeSizeAxes = Axes.Both, - Width = 0.4f, - Children = new Drawable[] - { - new Container { - RelativeSizeAxes = Axes.Both, - Shear = new Vector2(shear, 0), - Masking = true, - EdgeEffect = new EdgeEffect { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.2f), - Offset = new Vector2(2, 0), - Radius = 2, - }, - Children = new [] { - IconLayer = new Box - { - RelativeSizeAxes = Axes.Both, - EdgeSmoothness = new Vector2(1.5f, 0), - }, - } - }, - icon = new TextAwesome - { - Anchor = Anchor.Centre, - TextSize = 25, - }, - } - }, - c1 = new Container - { - Origin = Anchor.TopRight, - Anchor = Anchor.TopRight, - RelativeSizeAxes = Axes.Both, - Width = 0.6f, - Children = new Drawable[] - { - new Container { - RelativeSizeAxes = Axes.Both, - Shear = new Vector2(shear, 0), - Masking = true, - EdgeEffect = new EdgeEffect { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.2f), - Offset = new Vector2(2, 0), - Radius = 2, - }, - Children = new [] { - TextLayer = new Box - { - Origin = Anchor.TopLeft, - Anchor = Anchor.TopLeft, - RelativeSizeAxes = Axes.Both, - EdgeSmoothness = new Vector2(1.5f, 0), - }, - } - }, - text = new SpriteText - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - } - } - }, - }; - } - - public FontAwesome Icon - { - set - { - icon.Icon = value; - } - } - - public string Text - { - set - { - text.Text = value; - } - } - - public override bool Contains(Vector2 screenSpacePos) => IconLayer.Contains(screenSpacePos) || TextLayer.Contains(screenSpacePos); - - protected override bool OnHover(InputState state) - { - icon.ClearTransformations(); - - ResizeTo(SIZE_EXTENDED, transform_time, EasingTypes.OutElastic); - - int duration = 0; //(int)(Game.Audio.BeatLength / 2); - if (duration == 0) duration = pulse_length; - - IconLayer.FadeColour(HoverColour, transform_time, EasingTypes.OutElastic); - - double offset = 0; //(1 - Game.Audio.SyncBeatProgress) * duration; - double startTime = Time.Current + offset; - - // basic pulse - icon.Transforms.Add(new TransformScale - { - StartValue = new Vector2(1.1f), - EndValue = Vector2.One, - StartTime = startTime, - EndTime = startTime + duration, - Easing = EasingTypes.Out, - LoopCount = -1, - LoopDelay = duration - }); - - return true; - } - - protected override void OnHoverLost(InputState state) - { - icon.ClearTransformations(); - - ResizeTo(SIZE_RETRACTED, transform_time, EasingTypes.OutElastic); - - IconLayer.FadeColour(TextLayer.Colour, transform_time, EasingTypes.OutElastic); - - int duration = 0; //(int)(Game.Audio.BeatLength); - if (duration == 0) duration = pulse_length * 2; - - double offset = 0; //(1 - Game.Audio.SyncBeatProgress) * duration; - double startTime = Time.Current + offset; - - // slow pulse - icon.Transforms.Add(new TransformScale - { - StartValue = new Vector2(1.1f), - EndValue = Vector2.One, - StartTime = startTime, - EndTime = startTime + duration, - Easing = EasingTypes.Out, - LoopCount = -1, - LoopDelay = duration - }); - } - - protected override bool OnClick(InputState state) - { - var flash = new Box - { - RelativeSizeAxes = Axes.Both, - Shear = new Vector2(shear, 0), - Colour = Color4.White.Opacity(0.5f), - }; - Add(flash); - - flash.FadeOutFromOne(200); - flash.Expire(); - - ActivationSound.Play(); - - return base.OnClick(state); - } - } } diff --git a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs new file mode 100644 index 0000000000..4bb57154cc --- /dev/null +++ b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs @@ -0,0 +1,237 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Audio.Sample; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Transformations; +using osu.Framework.Input; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Graphics.UserInterface +{ + public class TwoLayerButton : ClickableContainer + { + private TextAwesome icon; + + public Box IconLayer; + public Box TextLayer; + + private const int transform_time = 600; + private const int pulse_length = 250; + + private const float shear = 0.1f; + + public static readonly Vector2 SIZE_EXTENDED = new Vector2(140, 50); + public static readonly Vector2 SIZE_RETRACTED = new Vector2(100, 50); + public AudioSample ActivationSound; + private SpriteText text; + + public Color4 HoverColour; + private Container c1; + private Container c2; + + public Color4 Colour + { + set + { + TextLayer.Colour = value; + IconLayer.Colour = value; + } + } + + public override Anchor Origin + { + get + { + return base.Origin; + } + + set + { + base.Origin = value; + c1.Origin = c1.Anchor = (value & Anchor.x2) > 0 ? Anchor.TopLeft : Anchor.TopRight; + c2.Origin = c2.Anchor = (value & Anchor.x2) > 0 ? Anchor.TopRight : Anchor.TopLeft; + + Margin = new MarginPadding + { + Right = (value & Anchor.x2) > 0 ? -SIZE_RETRACTED.X * shear * 0.5f : 0 + }; + + c1.Depth = (value & Anchor.x2) > 0 ? 0 : 1; + c2.Depth = (value & Anchor.x2) > 0 ? 1 : 0; + } + } + + public TwoLayerButton() + { + Size = SIZE_RETRACTED; + + Children = new Drawable[] + { + c2 = new Container + { + RelativeSizeAxes = Axes.Both, + Width = 0.4f, + Children = new Drawable[] + { + new Container { + RelativeSizeAxes = Axes.Both, + Shear = new Vector2(shear, 0), + Masking = true, + EdgeEffect = new EdgeEffect { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.2f), + Offset = new Vector2(2, 0), + Radius = 2, + }, + Children = new [] { + IconLayer = new Box + { + RelativeSizeAxes = Axes.Both, + EdgeSmoothness = new Vector2(1.5f, 0), + }, + } + }, + icon = new TextAwesome + { + Anchor = Anchor.Centre, + TextSize = 25, + }, + } + }, + c1 = new Container + { + Origin = Anchor.TopRight, + Anchor = Anchor.TopRight, + RelativeSizeAxes = Axes.Both, + Width = 0.6f, + Children = new Drawable[] + { + new Container { + RelativeSizeAxes = Axes.Both, + Shear = new Vector2(shear, 0), + Masking = true, + EdgeEffect = new EdgeEffect { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.2f), + Offset = new Vector2(2, 0), + Radius = 2, + }, + Children = new [] { + TextLayer = new Box + { + Origin = Anchor.TopLeft, + Anchor = Anchor.TopLeft, + RelativeSizeAxes = Axes.Both, + EdgeSmoothness = new Vector2(1.5f, 0), + }, + } + }, + text = new SpriteText + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + } + } + }, + }; + } + + public FontAwesome Icon + { + set + { + icon.Icon = value; + } + } + + public string Text + { + set + { + text.Text = value; + } + } + + public override bool Contains(Vector2 screenSpacePos) => IconLayer.Contains(screenSpacePos) || TextLayer.Contains(screenSpacePos); + + protected override bool OnHover(InputState state) + { + icon.ClearTransformations(); + + ResizeTo(SIZE_EXTENDED, transform_time, EasingTypes.OutElastic); + + int duration = 0; //(int)(Game.Audio.BeatLength / 2); + if (duration == 0) duration = pulse_length; + + IconLayer.FadeColour(HoverColour, transform_time, EasingTypes.OutElastic); + + double offset = 0; //(1 - Game.Audio.SyncBeatProgress) * duration; + double startTime = Time.Current + offset; + + // basic pulse + icon.Transforms.Add(new TransformScale + { + StartValue = new Vector2(1.1f), + EndValue = Vector2.One, + StartTime = startTime, + EndTime = startTime + duration, + Easing = EasingTypes.Out, + LoopCount = -1, + LoopDelay = duration + }); + + return true; + } + + protected override void OnHoverLost(InputState state) + { + icon.ClearTransformations(); + + ResizeTo(SIZE_RETRACTED, transform_time, EasingTypes.OutElastic); + + IconLayer.FadeColour(TextLayer.Colour, transform_time, EasingTypes.OutElastic); + + int duration = 0; //(int)(Game.Audio.BeatLength); + if (duration == 0) duration = pulse_length * 2; + + double offset = 0; //(1 - Game.Audio.SyncBeatProgress) * duration; + double startTime = Time.Current + offset; + + // slow pulse + icon.Transforms.Add(new TransformScale + { + StartValue = new Vector2(1.1f), + EndValue = Vector2.One, + StartTime = startTime, + EndTime = startTime + duration, + Easing = EasingTypes.Out, + LoopCount = -1, + LoopDelay = duration + }); + } + + protected override bool OnClick(InputState state) + { + var flash = new Box + { + RelativeSizeAxes = Axes.Both, + Shear = new Vector2(shear, 0), + Colour = Color4.White.Opacity(0.5f), + }; + Add(flash); + + flash.Alpha = 1; + flash.FadeOut(500, EasingTypes.OutQuint); + flash.Expire(); + + ActivationSound.Play(); + + return base.OnClick(state); + } + } +} \ No newline at end of file diff --git a/osu.Game/Modes/UI/ScoreOverlay.cs b/osu.Game/Modes/UI/ScoreOverlay.cs index 144370c826..fe254dda80 100644 --- a/osu.Game/Modes/UI/ScoreOverlay.cs +++ b/osu.Game/Modes/UI/ScoreOverlay.cs @@ -8,6 +8,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Modes.Objects; using OpenTK; using osu.Framework.Graphics.Primitives; +using osu.Game.Screens.Play; namespace osu.Game.Modes.UI { diff --git a/osu.Game/Graphics/UserInterface/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs similarity index 95% rename from osu.Game/Graphics/UserInterface/KeyCounter.cs rename to osu.Game/Screens/Play/KeyCounter.cs index 5a7fe65925..d97f134f50 100644 --- a/osu.Game/Graphics/UserInterface/KeyCounter.cs +++ b/osu.Game/Screens/Play/KeyCounter.cs @@ -1,16 +1,15 @@ //Copyright (c) 2007-2016 ppy Pty Ltd . //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; -using OpenTK.Graphics; -using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using OpenTK; +using OpenTK.Graphics; -namespace osu.Game.Graphics.UserInterface +namespace osu.Game.Screens.Play { public abstract class KeyCounter : Container { diff --git a/osu.Game/Graphics/UserInterface/KeyCounterCollection.cs b/osu.Game/Screens/Play/KeyCounterCollection.cs similarity index 95% rename from osu.Game/Graphics/UserInterface/KeyCounterCollection.cs rename to osu.Game/Screens/Play/KeyCounterCollection.cs index 740c497f94..d92b37378c 100644 --- a/osu.Game/Graphics/UserInterface/KeyCounterCollection.cs +++ b/osu.Game/Screens/Play/KeyCounterCollection.cs @@ -2,11 +2,11 @@ //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using OpenTK; using OpenTK.Graphics; -using osu.Framework.Graphics.Containers; -namespace osu.Game.Graphics.UserInterface +namespace osu.Game.Screens.Play { public class KeyCounterCollection : FlowContainer { diff --git a/osu.Game/Graphics/UserInterface/KeyCounterKeyboard.cs b/osu.Game/Screens/Play/KeyCounterKeyboard.cs similarity index 92% rename from osu.Game/Graphics/UserInterface/KeyCounterKeyboard.cs rename to osu.Game/Screens/Play/KeyCounterKeyboard.cs index 9b75924cb6..373c14dc28 100644 --- a/osu.Game/Graphics/UserInterface/KeyCounterKeyboard.cs +++ b/osu.Game/Screens/Play/KeyCounterKeyboard.cs @@ -1,11 +1,11 @@ //Copyright (c) 2007-2016 ppy Pty Ltd . //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK.Input; using osu.Framework.Graphics; using osu.Framework.Input; +using OpenTK.Input; -namespace osu.Game.Graphics.UserInterface +namespace osu.Game.Screens.Play { public class KeyCounterKeyboard : KeyCounter { diff --git a/osu.Game/Graphics/UserInterface/KeyCounterMouse.cs b/osu.Game/Screens/Play/KeyCounterMouse.cs similarity index 92% rename from osu.Game/Graphics/UserInterface/KeyCounterMouse.cs rename to osu.Game/Screens/Play/KeyCounterMouse.cs index 982721c7a7..846ff44e11 100644 --- a/osu.Game/Graphics/UserInterface/KeyCounterMouse.cs +++ b/osu.Game/Screens/Play/KeyCounterMouse.cs @@ -1,12 +1,12 @@ //Copyright (c) 2007-2016 ppy Pty Ltd . //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; -using OpenTK.Input; using osu.Framework.Graphics; using osu.Framework.Input; +using OpenTK; +using OpenTK.Input; -namespace osu.Game.Graphics.UserInterface +namespace osu.Game.Screens.Play { public class KeyCounterMouse : KeyCounter { diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index e06dfb18dc..cacb9d83f3 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -1,21 +1,16 @@ //Copyright (c) 2007-2016 ppy Pty Ltd . //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; -using osu.Framework.Input; -using osu.Framework.Platform; using osu.Framework.Timing; using osu.Game.Database; using osu.Game.Modes; using osu.Game.Modes.Objects.Drawables; using osu.Game.Screens.Backgrounds; -using OpenTK.Input; -using MouseState = osu.Framework.Input.MouseState; using OpenTK; using osu.Framework.GameModes; using osu.Game.Modes.UI; @@ -23,7 +18,8 @@ using osu.Game.Screens.Ranking; using osu.Game.Configuration; using osu.Framework.Configuration; using System; -using osu.Game.Graphics.UserInterface; +using System.Linq; +using osu.Game.Beatmaps; using OpenTK.Graphics; namespace osu.Game.Screens.Play @@ -47,6 +43,7 @@ namespace osu.Game.Screens.Play private ScoreProcessor scoreProcessor; private HitRenderer hitRenderer; private Bindable dimLevel; + private SkipButton skipButton; [BackgroundDependencyLoader] private void load(AudioManager audio, BeatmapDatabase beatmaps, OsuGameBase game, OsuConfigManager config) @@ -116,13 +113,40 @@ namespace osu.Game.Screens.Play Children = new Drawable[] { hitRenderer, + skipButton = new SkipButton { Alpha = 0 }, } }, scoreOverlay, - //new SkipButton(sourceClock, beatmap.HitObjects.First().StartTime) }; } + private void initializeSkipButton() + { + const double skip_required_cutoff = 3000; + const double fade_time = 300; + + double firstHitObject = Beatmap.Beatmap.HitObjects.First().StartTime; + + if (firstHitObject < skip_required_cutoff) + { + skipButton.Alpha = 0; + skipButton.Expire(); + return; + } + + skipButton.FadeInFromZero(fade_time); + + skipButton.Action = () => + { + sourceClock.Seek(firstHitObject - skip_required_cutoff - fade_time); + skipButton.Action = null; + }; + + skipButton.Delay(firstHitObject - skip_required_cutoff - fade_time); + skipButton.FadeOut(fade_time); + skipButton.Expire(); + } + protected override void LoadComplete() { base.LoadComplete(); @@ -135,6 +159,7 @@ namespace osu.Game.Screens.Play Schedule(() => { sourceClock.Start(); + initializeSkipButton(); }); } diff --git a/osu.Game/Screens/Play/SkipButton.cs b/osu.Game/Screens/Play/SkipButton.cs new file mode 100644 index 0000000000..98adb4d3fb --- /dev/null +++ b/osu.Game/Screens/Play/SkipButton.cs @@ -0,0 +1,32 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Graphics; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Play +{ + public class SkipButton : TwoLayerButton + { + private readonly double skipDestination; + + public SkipButton() + { + Text = @"Skip"; + Icon = FontAwesome.fa_osu_right_o; + Anchor = Anchor.BottomRight; + Origin = Anchor.BottomRight; + } + + [BackgroundDependencyLoader] + private void load(AudioManager audio, OsuColour colours) + { + ActivationSound = audio.Sample.Get(@"Menu/menuhit"); + Colour = colours.Yellow; + HoverColour = colours.YellowDark; + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index a90fa2a8cb..75f3d0ac42 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -67,6 +67,7 @@ + @@ -118,6 +119,7 @@ + @@ -145,10 +147,10 @@ - - - - + + + +