8000 Implement designs for beatmap carousel v2 by frenzibyte · Pull Request #31774 · ppy/osu · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Implement designs for beatmap carousel v2 #31774

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 31 commits into from
Feb 20, 2025

Conversation

frenzibyte
Copy link
Member
@frenzibyte frenzibyte commented Feb 3, 2025

The implementation is rewritten from the original PR to be flat, organised, and simple. Things to note:

  • Multiple components were refactored to support changing the target beatmap set for which those components function on (e.g. DifficultySpectrumDisplay, TopLocalRankV2, UpdateBeatmapSetButtonV2)
  • Components which were primarily used in previous song select design are copy-pasted into a separate V2-suffixed file as the intention (my intention) is to nuke the entire Select folder, so it doesn't make sense to reference or re-use components from that namespace. Also, UpdateBeatmapSetButtonV2 is seeing a redesign very soon anyway.
  • StarsGroupDefinition is added temporarily to be able to implement a group panel specific for stars grouping, whether it will remain or not is unknown.
  • There may be opportunities to share code between all four/five panel classes here, but I'm not comfortable enough to tell how it should happen in a way that doesn't involve abstraction and mentally-unparsable code, so I'll leave that up to discussion.

Preview:

CleanShot 2025-02-05 at 08 24 49
CleanShot 2025-02-05 at 08 24 52
CleanShot 2025-02-05 at 08 24 24
CleanShot 2025-02-06 at 02 18 11

Comment on lines 472 to 481
// - Update all Y positions. After a selection occurs, panels may have changed visibility state and therefore Y positions.
// - Link selected models to CarouselItems. If a selection changed, this is where we find the relevant CarouselItems for further use.
// - Update all Y positions. After a selection occurs, panels may have changed visibility state and therefore Y positions.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change of order is necessary as the Y position now has a dependency on which beatmap is selected (see BeatmapCarousel.GetSpacingBetweenItems). Without that dependency, there's no way to make the expanded/selected beatmap set not overlap with the beatmap set above it, which looks broken to my eyes.

With overlap:
CleanShot 2025-02-03 at 02 32 52

Without overlap:
CleanShot 2025-02-03 at 02 33 06

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This undoes an important optimisation (you added back a second traversal of every item, which is costly), so will require scrutiny.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now please undo this one. Let's keep this PR as implementing the design and making minimal-to-no changes to the carousel code. You're welcome to force push away any changes if it will help with conflict avoidance with other carousel PRs.

@peppy
Copy link
Member
peppy commented Feb 4, 2025

Going to provide an initial feedback pass on this. Let's ignore transitions / animations for now since I will do a pass on that after everything is implemented and stable.

osu Game Tests 2025-02-04 at 06 25 04

The set panel is showing difficulty information but has a difficulty underneath it. I guess a post step is to remove this and only show the set panel? This doesn't really mesh with how I set things up – I was hoping the BeatmapCarousel would be the one doing the conditional switching, not the set header.

For now shall we ignore these details and focus on the designs? If so, I think having a test scene which shows each of the panel designs in isolation could be handy to have if it's not more than 10 minutes of work.

osu.Game.Tests.2025-02-04.at.06.30.47.mp4

Why is the shade of the set header here different between these two beatmaps? One is bright white, the other is gray. I guess it's the expanded flag going wrong for one reason or another?

osu.Game.Tests.2025-02-04.at.06.33.19.mp4

Test scene doesn't seem to work


I don't know where to cut off review feedback with this PR. Selection state feels bad and unintuitive:

osu.Game.Tests.2025-02-04.at.06.40.45.mp4
  • The shadow/glow applied to cards doesn't look great and I'm not immediately sure how to fix that (but one thing to note is you can't change the glow/shadow radius based on the expanded state without a transition it looks weird, also you can't fade a colour from black to non-black while also changing the opacity it doesn't work well).
  • Is the intended direction here copy pasting the same code across three to four classes? I think this is going to be a bit of a PITA for iterating design changes.
  • Is there a group panel design?

@frenzibyte
Copy link
Member Author

Is there a group panel design?

Not yet, I'll look into that.

@frenzibyte frenzibyte force-pushed the carousel-v2-implement-designs branch from 9280e74 to cb89684 Compare February 5, 2025 13:22
@peppy peppy self-requested a review February 5, 2025 15:11
@peppy
Copy link
Member
peppy 8000 commented Feb 5, 2025

I think you made the panels not wide enough:

2025-02-06 00 16 38@2x

Also the keyboard selection colour change is not applied to the selected item:

2025-02-06.00.18.00.mp4

@frenzibyte
Copy link
Member Author

I think you made the panels not wide enough:

This part is kinda intentional, the entire carousel is shifted 20px to the right in SongSelectV2 instead of making the panel appear as cut off:
https://github.com/ppy/osu/pull/31774/files#diff-832686445c300178c6eca7c2c8bd1cee02359d36fab0985126825fcec33ffd85R52-R53

@peppy
Copy link
Member
peppy commented Feb 5, 2025

I'm pretty sure that will cut off the scrollbar?

@frenzibyte
Copy link
Member Author

Hmm, good point.

@frenzibyte frenzibyte force-pushed the carousel-v2-implement-designs branch from 080e8e9 to 04a3ee8 Compare February 6, 2025 02:45
@frenzibyte
Copy link
Member Author

I've refactored the PR once more to appropriately share code between all panel classes (see CarouselPanelPiece), alongside addressing both of the points above.

@peppy
Copy link
Member
peppy commented Feb 12, 2025
  • Wrong depth:

osu Game Tests 2025-02-12 at 10 09 50

  • Tests failing
  • Initial x position set wrong (panels fly from left unexpectedly):
osu.Game.Tests.2025-02-12.at.10.11.34.mp4
  • Selected state is shared between keyboard and mouse (no hover effect as a result):
osu.Game.Tests.2025-02-12.at.10.11.34.mp4

(This can probably be fixed in a separate PR because I can hardly load this fucking page on github and am ready to rage merge it)

I'm going to ignore about 10 other UI/UX concerns and address in follow-up PRs because this PR thread is unmanageable atm.

@peppy
Copy link
Member
peppy commented Feb 12, 2025

I feel like CarouselItemPiece is forced and subclassing would be better? Also there's still plenty of shared code across all the panel classes.

Also fixing the tests probably requires subclassing or moving the Action handling out of that class anyway.

Copy link
Member
@peppy peppy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dealing with this PR thread is frustrating as fuck (due to github being slow to load anything).

Copy link
Member
@peppy peppy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test

@peppy
Copy link
Member
peppy commented Feb 18, 2025

@frenzibyte heads up i'm going to take this one over since there's no movement from your end

@peppy
Copy link
Member
peppy commented Feb 18, 2025

@frenzibyte I've done a clean-up pass on this to attempt to make the drawables bearable to work with. Please check my changes and see if you agree.

I'll do a second review pass later today and then look to get this in. It's not perfect (and I have serious issues with the visual design language), but nothing that would impede merging this code for future adjustment.

@frenzibyte
Copy link
Member Author
frenzibyte commented Feb 19, 2025

Changes look good. I've pushed one extra change to fix a minor issue with PanelBeatmapStandalone display. There's also a change that can be applied to fix panels awkwardly transforming when they first appear on the screen:

CleanShot.2025-02-19.at.10.22.51.mp4

The following fixes the issue by finishing any transforms pending at PrepareForUse state and only doing the fade-in after. Posting as a diff in case you feel it's better suited for a follow-up PR.

diff
diff --git a/osu.Game/Screens/SelectV2/PanelBase.cs b/osu.Game/Screens/SelectV2/PanelBase.cs
index 805cbac8eb..255e40fdb9 100644
--- a/osu.Game/Screens/SelectV2/PanelBase.cs
+++ b/osu.Game/Screens/SelectV2/PanelBase.cs
@@ -27,7 +27,7 @@ public abstract partial class PanelBase : PoolableDrawable, ICarouselPanel
         private const float keyboard_active_x_offset = 25f;
         private const float active_x_offset = 50f;
 
-        private const float duration = 500;
+        protected const float DURATION = 500;
 
         protected float PanelXOffset { get; init; }
 
@@ -165,12 +165,6 @@ protected override void LoadComplete()
             KeyboardSelected.BindValueChanged(_ => updateDisplay(), true);
         }
 
-        protected override void PrepareForUse()
-        {
-            base.PrepareForUse();
-            this.FadeInFromZero(duration, Easing.OutQuint);
-        }
-
         [Resolved]
         private BeatmapCarousel? carousel { get; set; }
 
@@ -183,15 +177,15 @@ protected override bool OnClick(ClickEvent e)
 
         private void updateDisplay()
         {
-            backgroundLayer.TransformTo(nameof(Padding), backgroundLayer.Padding with { Vertical = Expanded.Value ? 2f : 0f }, duration, Easing.OutQuint);
+            backgroundLayer.TransformTo(nameof(Padding), backgroundLayer.Padding with { Vertical = Expanded.Value ? 2f : 0f }, DURATION, Easing.OutQuint);
 
             var backgroundColour = accentColour ?? Color4.White;
             var edgeEffectColour = accentColour ?? Color4Extensions.FromHex(@"4EBFFF");
 
-            backgroundAccentGradient.FadeColour(ColourInfo.GradientHorizontal(backgroundColour.Opacity(0.25f), backgroundColour.Opacity(0f)), duration, Easing.OutQuint);
-            backgroundBorder.FadeColour(backgroundColour, duration, Easing.OutQuint);
+            backgroundAccentGradient.FadeColour(ColourInfo.GradientHorizontal(backgroundColour.Opacity(0.25f), backgroundColour.Opacity(0f)), DURATION, Easing.OutQuint);
+            backgroundBorder.FadeColour(backgroundColour, DURATION, Easing.OutQuint);
 
-            TopLevelContent.FadeEdgeEffectTo(Expanded.Value ? edgeEffectColour.Opacity(0.5f) : Color4.Black.Opacity(0.4f), duration, Easing.OutQuint);
+            TopLevelContent.FadeEdgeEffectTo(Expanded.Value ? edgeEffectColour.Opacity(0.5f) : Color4.Black.Opacity(0.4f), DURATION, Easing.OutQuint);
 
             updateXOffset();
             updateHover();
@@ -207,7 +201,7 @@ private void updateXOffset()
             if (KeyboardSelected.Value)
                 x -= keyboard_active_x_offset;
 
-            this.TransformTo(nameof(Padding), new MarginPadding { Left = x }, duration, Easing.OutQuint);
+            this.TransformTo(nameof(Padding), new MarginPadding { Left = x }, DURATION, Easing.OutQuint);
         }
 
         private void updateHover()
diff --git a/osu.Game/Screens/SelectV2/PanelBeatmap.cs b/osu.Game/Screens/SelectV2/PanelBeatmap.cs
index b27e5cae14..37c57987a8 100644
--- a/osu.Game/Screens/SelectV2/PanelBeatmap.cs
+++ b/osu.Game/Screens/SelectV2/PanelBeatmap.cs
@@ -182,6 +182,9 @@ protected override void PrepareForUse()
 
             computeStarRating();
             updateKeyCount();
+
+            FinishTransforms(true);
+            this.FadeInFromZero(DURATION, Easing.OutQuint);
         }
 
         protected override void FreeAfterUse()
diff --git a/osu.Game/Screens/SelectV2/PanelBeatmapSet.cs b/osu.Game/Screens/SelectV2/PanelBeatmapSet.cs
index 5c38fe8e04..e7b8995ae3 100644
--- a/osu.Game/Screens/SelectV2/PanelBeatmapSet.cs
+++ b/osu.Game/Screens/SelectV2/PanelBeatmapSet.cs
@@ -150,6 +150,9 @@ protected override void PrepareForUse()
             updateButton.BeatmapSet = beatmapSet;
             statusPill.Status = beatmapSet.Status;
             difficultiesDisplay.BeatmapSet = beatmapSet;
+
+            FinishTransforms(true);
+            this.FadeInFromZero(DURATION, Easing.OutQuint);
         }
 
         protected override void FreeAfterUse()
diff --git a/osu.Game/Screens/SelectV2/PanelBeatmapStandalone.cs b/osu.Game/Screens/SelectV2/PanelBeatmapStandalone.cs
index 948311a86e..983ed1d550 100644
--- a/osu.Game/Screens/SelectV2/PanelBeatmapStandalone.cs
+++ b/osu.Game/Screens/SelectV2/PanelBeatmapStandalone.cs
@@ -220,6 +220,9 @@ protected override void PrepareForUse()
             difficultyLine.Show();
 
             computeStarRating();
+
+            FinishTransforms(true);
+            this.FadeInFromZero(DURATION, Easing.OutQuint);
         }
 
         protected override void FreeAfterUse()
diff --git a/osu.Game/Screens/SelectV2/PanelGroup.cs b/osu.Game/Screens/SelectV2/PanelGroup.cs
index ecb64f4797..d5f48774dc 100644
--- a/osu.Game/Screens/SelectV2/PanelGroup.cs
+++ b/osu.Game/Screens/SelectV2/PanelGroup.cs
@@ -103,6 +103,9 @@ protected override void PrepareForUse()
             GroupDefinition group = (GroupDefinition)Item.Model;
 
             titleText.Text = group.Title;
+
+            FinishTransforms(true);
+            this.FadeInFromZero(DURATION, Easing.OutQuint);
         }
     }
 }
diff --git a/osu.Game/Screens/SelectV2/PanelGroupStarDifficulty.cs b/osu.Game/Screens/SelectV2/PanelGroupStarDifficulty.cs
index 0dc5a2f365..1a9c67bd06 100644
--- a/osu.Game/Screens/SelectV2/PanelGroupStarDifficulty.cs
+++ b/osu.Game/Screens/SelectV2/PanelGroupStarDifficulty.cs
@@ -129,6 +129,9 @@ protected override void PrepareForUse()
 
             chevronIcon.Colour = contentColour;
             starCounter.Colour = contentColour;
+
+            FinishTransforms(true);
+            this.FadeInFromZero(DURATION, Easing.OutQuint);
         }
 
         private void onExpanded()

@peppy
Copy link
Member
peppy commented Feb 19, 2025

The following fixes the issue by finishing any transforms pending at PrepareForUse state and only doing the fade-in after. Posting as a diff in case you feel it's better suited for a follow-up PR

I intentionally removed this because it was not 100% of the way there and i don't want animations to never play (aka FinishTransforms. Let's leave it out for now.

@peppy peppy merged commit 4c934da into ppy:master Feb 20, 2025
8 of 10 checks passed
@frenzibyte frenzibyte deleted the carousel-v2-implement-designs branch February 20, 2025 12:06
@Joehuu Joehuu mentioned this pull request Mar 27, 2025
17 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0