From c1bec7a7c374f38adc33b124f93d40ff267657f7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2024 14:55:55 +0900 Subject: [PATCH 1/3] Simplify colour logic for beatmap overlay filter rows --- .../BeatmapSearchGeneralFilterRow.cs | 5 ++-- ...BeatmapSearchMultipleSelectionFilterRow.cs | 10 ++----- .../Overlays/BeatmapListing/FilterTabItem.cs | 29 ++++++++++++++----- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs index a4a914db55..2d56c60de6 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs @@ -56,8 +56,6 @@ namespace osu.Game.Overlays.BeatmapListing [Resolved(canBeNull: true)] private IDialogOverlay dialogOverlay { get; set; } - protected override Color4 GetStateColour() => colours.Orange1; - protected override void LoadComplete() { base.LoadComplete(); @@ -65,6 +63,9 @@ namespace osu.Game.Overlays.BeatmapListing disclaimerShown = sessionStatics.GetBindable(Static.FeaturedArtistDisclaimerShownOnce); } + protected override Color4 ColourNormal => colours.Orange1; + protected override Color4 ColourActive => colours.Orange2; + protected override bool OnClick(ClickEvent e) { if (!disclaimerShown.Value && dialogOverlay != null) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs index 4bd25f6561..9b2e1d57fe 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs @@ -1,13 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -24,7 +21,7 @@ namespace osu.Game.Overlays.BeatmapListing { public new readonly BindableList Current = new BindableList(); - private MultipleSelectionFilter filter; + private MultipleSelectionFilter filter = null!; public BeatmapSearchMultipleSelectionFilterRow(LocalisableString header) : base(header) @@ -42,7 +39,6 @@ namespace osu.Game.Overlays.BeatmapListing /// /// Creates a filter control that can be used to simultaneously select multiple values of type . /// - [NotNull] protected virtual MultipleSelectionFilter CreateMultipleSelectionFilter() => new MultipleSelectionFilter(); protected partial class MultipleSelectionFilter : FillFlowContainer @@ -69,7 +65,7 @@ namespace osu.Game.Overlays.BeatmapListing Current.BindCollectionChanged(currentChanged, true); } - private void currentChanged(object sender, NotifyCollectionChangedEventArgs e) + private void currentChanged(object? sender, NotifyCollectionChangedEventArgs e) { foreach (var c in Children) c.Active.Value = Current.Contains(c.Value); @@ -122,7 +118,7 @@ namespace osu.Game.Overlays.BeatmapListing { base.UpdateState(); selectedUnderline.FadeTo(Active.Value ? 1 : 0, 200, Easing.OutQuint); - selectedUnderline.FadeColour(IsHovered ? ColourProvider.Content2 : GetStateColour(), 200, Easing.OutQuint); + selectedUnderline.FadeColour(ColourForCurrentState, 200, Easing.OutQuint); } protected override bool OnClick(ClickEvent e) diff --git a/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs b/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs index ee188d34ce..2896039a99 100644 --- a/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs +++ b/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs @@ -8,6 +8,7 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Extensions; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; @@ -24,7 +25,7 @@ namespace osu.Game.Overlays.BeatmapListing [Resolved] protected OverlayColourProvider ColourProvider { get; private set; } - private OsuSpriteText text; + protected OsuSpriteText Text; protected Sample SelectSample { get; private set; } = null!; @@ -39,7 +40,7 @@ namespace osu.Game.Overlays.BeatmapListing AutoSizeAxes = Axes.Both; AddRangeInternal(new Drawable[] { - text = new OsuSpriteText + Text = new OsuSpriteText { Font = OsuFont.GetFont(size: 13, weight: FontWeight.Regular), Text = LabelFor(Value) @@ -86,14 +87,26 @@ namespace osu.Game.Overlays.BeatmapListing protected virtual bool HighlightOnHoverWhenActive => false; - protected virtual void UpdateState() - { - bool highlightHover = IsHovered && (!Active.Value || HighlightOnHoverWhenActive); + protected virtual Color4 ColourActive => ColourProvider.Content1; + protected virtual Color4 ColourNormal => ColourProvider.Light2; - text.FadeColour(highlightHover ? ColourProvider.Content2 : GetStateColour(), 200, Easing.OutQuint); - text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Regular); + protected Color4 ColourForCurrentState + { + get + { + Color4 colour = Active.Value ? ColourActive : ColourNormal; + + if (IsHovered && (!Active.Value || HighlightOnHoverWhenActive)) + colour = colour.Lighten(0.2f); + + return colour; + } } - protected virtual Color4 GetStateColour() => Active.Value ? ColourProvider.Content1 : ColourProvider.Light2; + protected virtual void UpdateState() + { + Text.FadeColour(ColourForCurrentState, 200, Easing.OutQuint); + Text.Font = Text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Regular); + } } } From fa1527f446163f546ae7f88a551e0d4ff9ff9caa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Jun 2024 15:43:04 +0900 Subject: [PATCH 2/3] Update design for selected filters to better imply that they are selected --- ...BeatmapSearchMultipleSelectionFilterRow.cs | 88 ++++++++++++++++--- .../Overlays/BeatmapListing/FilterTabItem.cs | 22 ++--- 2 files changed, 83 insertions(+), 27 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs index 9b2e1d57fe..9cf3328149 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs @@ -7,12 +7,17 @@ using System.Collections.Specialized; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Framework.Localisation; +using osu.Game.Graphics; using osuTK; +using osuTK.Graphics; +using FontWeight = osu.Game.Graphics.FontWeight; namespace osu.Game.Overlays.BeatmapListing { @@ -95,30 +100,91 @@ namespace osu.Game.Overlays.BeatmapListing protected partial class MultipleSelectionFilterTabItem : FilterTabItem { - private readonly Box selectedUnderline; - - protected override bool HighlightOnHoverWhenActive => true; + private Drawable activeContent = null!; + private Circle background = null!; public MultipleSelectionFilterTabItem(T value) : base(value) { + } + + [BackgroundDependencyLoader] + private void load() + { + AutoSizeDuration = 100; + AutoSizeEasing = Easing.OutQuint; + // This doesn't match any actual design, but should make it easier for the user to understand // that filters are applied until we settle on a final design. - AddInternal(selectedUnderline = new Box + AddInternal(activeContent = new Container { Depth = float.MaxValue, - RelativeSizeAxes = Axes.X, - Height = 1.5f, - Anchor = Anchor.BottomLeft, - Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.Both, + Alpha = 0, + Padding = new MarginPadding + { + Left = -16, + Right = -4, + Vertical = -2 + }, + Children = new Drawable[] + { + background = new Circle + { + Colour = Color4.White, + RelativeSizeAxes = Axes.Both, + }, + new SpriteIcon + { + Icon = FontAwesome.Solid.TimesCircle, + Size = new Vector2(10), + Colour = ColourProvider.Background4, + Position = new Vector2(3, 0.5f), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + } + } }); } + protected override Color4 ColourActive => ColourProvider.Light1; + + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) + { + return Active.Value + ? background.ReceivePositionalInputAt(screenSpacePos) + : base.ReceivePositionalInputAt(screenSpacePos); + } + protected override void UpdateState() { - base.UpdateState(); - selectedUnderline.FadeTo(Active.Value ? 1 : 0, 200, Easing.OutQuint); - selectedUnderline.FadeColour(ColourForCurrentState, 200, Easing.OutQuint); + Color4 colour = Active.Value ? ColourActive : ColourNormal; + + if (IsHovered) + colour = Active.Value ? colour.Darken(0.2f) : colour.Lighten(0.2f); + + if (Active.Value) + { + // This just allows enough spacing for adjacent tab items to show the "x". + Padding = new MarginPadding { Left = 12 }; + + activeContent.FadeIn(200, Easing.OutQuint); + background.FadeColour(colour, 200, Easing.OutQuint); + + // flipping colours + Text.FadeColour(ColourProvider.Background4, 200, Easing.OutQuint); + Text.Font = Text.Font.With(weight: FontWeight.SemiBold); + } + else + { + Padding = new MarginPadding(); + + activeContent.FadeOut(); + + background.FadeColour(colour, 200, Easing.OutQuint); + Text.FadeColour(colour, 200, Easing.OutQuint); + Text.Font = Text.Font.With(weight: FontWeight.Regular); + } } protected override bool OnClick(ClickEvent e) diff --git a/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs b/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs index 2896039a99..8f4ecaa0f5 100644 --- a/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs +++ b/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs @@ -85,27 +85,17 @@ namespace osu.Game.Overlays.BeatmapListing /// protected virtual LocalisableString LabelFor(T value) => (value as Enum)?.GetLocalisableDescription() ?? value.ToString(); - protected virtual bool HighlightOnHoverWhenActive => false; - protected virtual Color4 ColourActive => ColourProvider.Content1; protected virtual Color4 ColourNormal => ColourProvider.Light2; - protected Color4 ColourForCurrentState - { - get - { - Color4 colour = Active.Value ? ColourActive : ColourNormal; - - if (IsHovered && (!Active.Value || HighlightOnHoverWhenActive)) - colour = colour.Lighten(0.2f); - - return colour; - } - } - protected virtual void UpdateState() { - Text.FadeColour(ColourForCurrentState, 200, Easing.OutQuint); + Color4 colour = Active.Value ? ColourActive : ColourNormal; + + if (IsHovered) + colour = colour.Lighten(0.2f); + + Text.FadeColour(colour, 200, Easing.OutQuint); Text.Font = Text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Regular); } } From 030bbf26414f075e55528ead9a18a518d539d237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 28 Jun 2024 09:07:29 +0200 Subject: [PATCH 3/3] Fix vertical overlaps on multiselection filters when they wrap --- .../BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs index 9cf3328149..958297b559 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs @@ -55,7 +55,7 @@ namespace osu.Game.Overlays.BeatmapListing { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Spacing = new Vector2(10, 0); + Spacing = new Vector2(10, 5); AddRange(GetValues().Select(CreateTabItem)); }