Because of this it was possible for a scroll to not be able to scroll
to the panel it wanted to scroll to because its layout height was
too small for the target Y position of the panel that it wanted to
scroll to.
The scroll height was set in `updateDisplayedRange()` which is notably
after attempting to scroll to the current selection.
I'm having trouble finding a repro for this, but I know it's been an
ongoing issue. I've had this patch applied locally for a while now and
haven't run into a failed scroll to selection with it.
This also allows *all* panels to be re-used based on equality, as
originally intended. Beatmap updates should be handled correctly without
a full (flashing) recreation of panels now.
This is a minimal implementation in order to keep moving forward.
For simplicity I've copied over the old implementation verbatim. Note
that this is beatmap*set* based randomisation, which means that when
panels are split up by difficulty, it is still randomising by set (with
the difficulty choice being left up to the user recommendation system).
I think this is what we want, but if it isn't, any changes can come
later.
This isn't used visually for context menus, but is handy to have when
using this class to convey more general information about actions,
including usages outside of context menus where an icon is relevant to
have.
Previously, carousel panels would appear immediately at their required Y
position. This didn't look great when they appear with other panels
surrounding them.
Now they will spawn in underneath the nearest item before them, making
the animation feel much more correct.