diff --git a/osu.Desktop.VisualTests/Tests/TestCaseBeatmapOptionsOverlay.cs b/osu.Desktop.VisualTests/Tests/TestCaseBeatmapOptionsOverlay.cs new file mode 100644 index 0000000000..407bb79bb6 --- /dev/null +++ b/osu.Desktop.VisualTests/Tests/TestCaseBeatmapOptionsOverlay.cs @@ -0,0 +1,31 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Screens.Testing; +using osu.Game.Graphics; +using osu.Game.Overlays; +using osu.Game.Overlays.BeatmapOptions; + +namespace osu.Desktop.VisualTests +{ + class TestCaseBeatmapOptionsOverlay : TestCase + { + public override string Name => @"Beatmap Options"; + public override string Description => @"Beatmap options in song select"; + + public override void Reset() + { + base.Reset(); + + var overlay = new BeatmapOptionsOverlay + { + RelativeSizeAxes = Axes.Both, + }; + + Add(overlay); + + AddButton(@"Toggle", overlay.ToggleVisibility); + } + } +} diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 85d6d7055e..2aca6694ef 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -195,6 +195,7 @@ + diff --git a/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsButton.cs b/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsButton.cs new file mode 100644 index 0000000000..96deca7321 --- /dev/null +++ b/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsButton.cs @@ -0,0 +1,145 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Transforms; +using osu.Framework.Input; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Overlays.BeatmapOptions +{ + public class BeatmapOptionsButton : ClickableContainer + { + private Box background, flash; + private TextAwesome iconText; + private OsuSpriteText firstLine, secondLine; + + public Color4 ButtonColour + { + get { return background.Colour; } + set { background.Colour = value; } + } + + public FontAwesome Icon + { + get { return iconText.Icon; } + set { iconText.Icon = value; } + } + + public string FirstLineText + { + get { return firstLine.Text; } + set { firstLine.Text = value; } + } + + public string SecondLineText + { + get { return secondLine.Text; } + set { secondLine.Text = value; } + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + flash.FadeTo(0.1f, 1000, EasingTypes.OutQuint); + return base.OnMouseDown(state, args); + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + flash.FadeTo(0, 1000, EasingTypes.OutQuint); + return base.OnMouseUp(state, args); + } + + protected override bool OnClick(InputState state) + { + flash.ClearTransforms(); + flash.Alpha = 0.9f; + flash.FadeOut(800, EasingTypes.OutExpo); + + return base.OnClick(state); + } + + public BeatmapOptionsButton() + { + Size = new Vector2(130f, 100f); + + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Shear = new Vector2(0.2f, 0f), + Masking = true, + EdgeEffect = new EdgeEffect + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.2f), + Roundness = 5, + Radius = 8, + }, + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + EdgeSmoothness = new Vector2(1.5f, 0), + Colour = Color4.Black, + }, + flash = new Box + { + RelativeSizeAxes = Axes.Both, + EdgeSmoothness = new Vector2(1.5f, 0), + BlendingMode = BlendingMode.Additive, + Colour = Color4.White, + Alpha = 0, + }, + }, + }, + new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Position = new Vector2(-10f, -5f), // center the content visually + Direction = FillDirection.Down, + Children = new Drawable[] + { + iconText = new TextAwesome + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + TextSize = 30, + Shadow = true, + Icon = FontAwesome.fa_close, + Margin = new MarginPadding + { + Bottom = 5, + }, + }, + firstLine = new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Font = @"Exo2.0-Bold", + Text = @"", + }, + secondLine = new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Font = @"Exo2.0-Bold", + Text = @"", + }, + }, + }, + }; + } + } +} diff --git a/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsClearLocalScoresButton.cs b/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsClearLocalScoresButton.cs new file mode 100644 index 0000000000..9058d6c34f --- /dev/null +++ b/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsClearLocalScoresButton.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Game.Graphics; + +namespace osu.Game.Overlays.BeatmapOptions +{ + public class BeatmapOptionsClearLocalScoresButton : BeatmapOptionsButton + { + [BackgroundDependencyLoader] + private void load(OsuColour colour) + { + ButtonColour = colour.Purple; + } + + public BeatmapOptionsClearLocalScoresButton() + { + Icon = FontAwesome.fa_eraser; + FirstLineText = @"Clear"; + SecondLineText = @"local scores"; + } + } +} diff --git a/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsDeleteButton.cs b/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsDeleteButton.cs new file mode 100644 index 0000000000..4572839a6b --- /dev/null +++ b/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsDeleteButton.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Game.Graphics; + +namespace osu.Game.Overlays.BeatmapOptions +{ + public class BeatmapOptionsDeleteButton : BeatmapOptionsButton + { + [BackgroundDependencyLoader] + private void load(OsuColour colour) + { + ButtonColour = colour.Pink; + } + + public BeatmapOptionsDeleteButton() + { + Icon = FontAwesome.fa_trash; + FirstLineText = @"Delete"; + SecondLineText = @"Beatmap"; + } + } +} diff --git a/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsEditButton.cs b/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsEditButton.cs new file mode 100644 index 0000000000..8dc1ab6e2e --- /dev/null +++ b/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsEditButton.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Game.Graphics; + +namespace osu.Game.Overlays.BeatmapOptions +{ + public class BeatmapOptionsEditButton : BeatmapOptionsButton + { + [BackgroundDependencyLoader] + private void load(OsuColour colour) + { + ButtonColour = colour.Yellow; + } + + public BeatmapOptionsEditButton() + { + Icon = FontAwesome.fa_pencil; + FirstLineText = @"Edit"; + SecondLineText = @"Beatmap"; + } + } +} diff --git a/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsOverlay.cs b/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsOverlay.cs new file mode 100644 index 0000000000..4ec0993ef3 --- /dev/null +++ b/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsOverlay.cs @@ -0,0 +1,118 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Transforms; +using osu.Game.Graphics; + +namespace osu.Game.Overlays.BeatmapOptions +{ + public class BeatmapOptionsOverlay : FocusedOverlayContainer + { + private const float transition_duration = 500; + private const float x_position = 290; + + private Container background; + private FillFlowContainer buttonsContainer; + + public Action OnRemoveFromUnplayed; + public Action OnClearLocalScores; + public Action OnEdit; + public Action OnDelete; + + protected override void PopIn() + { + base.PopIn(); + + if (buttonsContainer.Position.X >= DrawWidth || buttonsContainer.Alpha <= 0) + buttonsContainer.MoveToX(-buttonsContainer.DrawWidth); + + buttonsContainer.Alpha = 1; + + background.FadeIn(transition_duration, EasingTypes.OutQuint); + buttonsContainer.MoveToX(x_position, transition_duration, EasingTypes.OutQuint); + buttonsContainer.TransformSpacingTo(Vector2.Zero, transition_duration, EasingTypes.OutQuint); + } + + protected override void PopOut() + { + base.PopOut(); + + background.FadeOut(transition_duration, EasingTypes.InSine); + buttonsContainer.MoveToX(DrawWidth, transition_duration, EasingTypes.InSine); + buttonsContainer.TransformSpacingTo(new Vector2(200f, 0f), transition_duration, EasingTypes.InSine); + + Delay(transition_duration); + Schedule(() => + { + if (State == Visibility.Hidden) + buttonsContainer.Alpha = 0; + }); + } + + public BeatmapOptionsOverlay() + { + Children = new Drawable[] + { + background = new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.5f), + }, + }, + }, + buttonsContainer = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + Children = new BeatmapOptionsButton[] + { + new BeatmapOptionsRemoveFromUnplayedButton + { + Action = () => + { + Hide(); + OnRemoveFromUnplayed?.Invoke(); + }, + }, + new BeatmapOptionsClearLocalScoresButton + { + Action = () => + { + Hide(); + OnClearLocalScores?.Invoke(); + }, + }, + new BeatmapOptionsEditButton + { + Action = () => + { + Hide(); + OnEdit?.Invoke(); + }, + }, + new BeatmapOptionsDeleteButton + { + Action = () => + { + Hide(); + OnDelete?.Invoke(); + }, + }, + }, + }, + }; + } + } +} diff --git a/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsRemoveFromUnplayedButton.cs b/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsRemoveFromUnplayedButton.cs new file mode 100644 index 0000000000..df5bde60c4 --- /dev/null +++ b/osu.Game/Overlays/BeatmapOptions/BeatmapOptionsRemoveFromUnplayedButton.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Game.Graphics; + +namespace osu.Game.Overlays.BeatmapOptions +{ + public class BeatmapOptionsRemoveFromUnplayedButton : BeatmapOptionsButton + { + [BackgroundDependencyLoader] + private void load(OsuColour colour) + { + ButtonColour = colour.Purple; + } + + public BeatmapOptionsRemoveFromUnplayedButton() + { + Icon = FontAwesome.fa_times_circle_o; + FirstLineText = @"Remove"; + SecondLineText = @"from Unplayed"; + } + } +} diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 4252de2978..c67d7c9662 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -28,6 +28,7 @@ using OpenTK.Input; using System.Collections.Generic; using osu.Framework.Threading; using osu.Game.Overlays; +using osu.Game.Overlays.BeatmapOptions; namespace osu.Game.Screens.Select { @@ -52,6 +53,7 @@ namespace osu.Game.Screens.Select private List beatmapGroups; + private BeatmapOptionsOverlay beatmapOptions; private Footer footer; OsuScreen player; @@ -125,6 +127,20 @@ namespace osu.Game.Screens.Select Right = 20, }, }, + beatmapOptions = new BeatmapOptionsOverlay + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + OnRemoveFromUnplayed = null, + OnClearLocalScores = null, + OnEdit = null, + OnDelete = promptDelete, + Margin = new MarginPadding + { + Bottom = 50, + }, + }, footer = new Footer { OnBack = Exit, @@ -144,7 +160,7 @@ namespace osu.Game.Screens.Select footer.AddButton(@"mods", colours.Yellow, null); footer.AddButton(@"random", colours.Green, carousel.SelectRandom); - footer.AddButton(@"options", colours.Blue, null); + footer.AddButton(@"options", colours.Blue, beatmapOptions.ToggleVisibility); if (osuGame != null) { @@ -394,6 +410,12 @@ namespace osu.Game.Screens.Select filterChanged(); } + private void promptDelete() + { + if (Beatmap != null) + dialogOverlay?.Push(new BeatmapDeleteDialog(Beatmap)); + } + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { switch (args.Key) @@ -404,9 +426,7 @@ namespace osu.Game.Screens.Select case Key.Delete: if (state.Keyboard.ShiftPressed) { - if (Beatmap != null) - dialogOverlay?.Push(new BeatmapDeleteDialog(Beatmap)); - + promptDelete(); return true; } break; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 1c5996b51e..215457f9d4 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -287,6 +287,12 @@ + + + + + + @@ -309,6 +315,7 @@ +