From e451e43b9022542bc28c6f96e2263c44b27a1213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 5 Dec 2021 16:31:45 +0100 Subject: [PATCH] Implement input handling behaviour of beatmap card dropdown --- .../Beatmaps/Drawables/Cards/BeatmapCard.cs | 12 ++++- .../Drawables/Cards/BeatmapCardDropdown.cs | 52 +++++++++++++++++-- .../Cards/BeatmapCardExtraInfoRow.cs | 4 +- .../Drawables/Cards/HoverHandlingContainer.cs | 27 ++++++++++ 4 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 osu.Game/Beatmaps/Drawables/Cards/HoverHandlingContainer.cs diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs index 1a05607074..2ab77539b3 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs @@ -44,6 +44,8 @@ namespace osu.Game.Beatmaps.Drawables.Cards private readonly BeatmapDownloadTracker downloadTracker; + private BeatmapCardDropdown dropdown = null!; + private BeatmapCardThumbnail thumbnail = null!; private Container rightAreaBackground = null!; @@ -80,7 +82,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards GridContainer titleContainer; GridContainer artistContainer; - InternalChild = new BeatmapCardDropdown(height) + InternalChild = dropdown = new BeatmapCardDropdown(height) { Body = new Container { @@ -277,6 +279,14 @@ namespace osu.Game.Beatmaps.Drawables.Cards ChildrenEnumerable = createStatistics() }, new BeatmapCardExtraInfoRow(beatmapSet) + { + Hovered = _ => + { + dropdown.ScheduleShow(); + return false; + }, + Unhovered = _ => dropdown.ScheduleHide() + } } }, downloadProgressBar = new BeatmapCardDownloadProgressBar diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardDropdown.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardDropdown.cs index 877338ecb0..ef4ba67ab7 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardDropdown.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardDropdown.cs @@ -1,12 +1,15 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +#nullable enable + using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; +using osu.Framework.Threading; using osu.Game.Overlays; using osuTK; @@ -37,13 +40,13 @@ namespace osu.Game.Beatmaps.Drawables.Cards RelativeSizeAxes = Axes.X; Height = height; - InternalChild = content = new Container + InternalChild = content = new HoverHandlingContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, CornerRadius = BeatmapCard.CORNER_RADIUS, Masking = true, - + Unhovered = _ => checkForHide(), Children = new Drawable[] { background = new Box @@ -57,12 +60,18 @@ namespace osu.Game.Beatmaps.Drawables.Cards CornerRadius = BeatmapCard.CORNER_RADIUS, Masking = true, }, - dropdownContent = new Container + dropdownContent = new HoverHandlingContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Margin = new MarginPadding { Top = height }, - Alpha = 0 + Alpha = 0, + Hovered = _ => + { + keep(); + return true; + }, + Unhovered = _ => checkForHide() }, borderContainer = new Container { @@ -95,6 +104,41 @@ namespace osu.Game.Beatmaps.Drawables.Cards FinishTransforms(true); } + private ScheduledDelegate? scheduledExpandedChange; + + public void ScheduleShow() + { + scheduledExpandedChange?.Cancel(); + if (Expanded.Value) + return; + + scheduledExpandedChange = Scheduler.AddDelayed(() => Expanded.Value = true, 100); + } + + public void ScheduleHide() + { + scheduledExpandedChange?.Cancel(); + if (!Expanded.Value) + return; + + scheduledExpandedChange = Scheduler.AddDelayed(() => Expanded.Value = false, 500); + } + + private void checkForHide() + { + if (content.IsHovered || dropdownContent.IsHovered) + return; + + scheduledExpandedChange?.Cancel(); + Expanded.Value = false; + } + + private void keep() + { + scheduledExpandedChange?.Cancel(); + Expanded.Value = true; + } + private void updateState() { background.FadeTo(Expanded.Value ? 1 : 0, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtraInfoRow.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtraInfoRow.cs index c64e5b83d8..0a9d98e621 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtraInfoRow.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtraInfoRow.cs @@ -8,14 +8,14 @@ using osuTK; namespace osu.Game.Beatmaps.Drawables.Cards { - public class BeatmapCardExtraInfoRow : CompositeDrawable + public class BeatmapCardExtraInfoRow : HoverHandlingContainer { public BeatmapCardExtraInfoRow(APIBeatmapSet beatmapSet) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - InternalChild = new FillFlowContainer + Child = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, diff --git a/osu.Game/Beatmaps/Drawables/Cards/HoverHandlingContainer.cs b/osu.Game/Beatmaps/Drawables/Cards/HoverHandlingContainer.cs new file mode 100644 index 0000000000..1e2c616332 --- /dev/null +++ b/osu.Game/Beatmaps/Drawables/Cards/HoverHandlingContainer.cs @@ -0,0 +1,27 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable enable + +using System; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input.Events; + +namespace osu.Game.Beatmaps.Drawables.Cards +{ + public class HoverHandlingContainer : Container + { + public Func? Hovered { get; set; } + public Action? Unhovered { get; set; } + + protected override bool OnHover(HoverEvent e) => Hovered?.Invoke(e) ?? base.OnHover(e); + + protected override void OnHoverLost(HoverLostEvent e) + { + if (Unhovered != null) + Unhovered?.Invoke(e); + else + base.OnHoverLost(e); + } + } +}