mirror of
https://github.com/ppy/osu.git
synced 2025-03-11 02:17:19 +08:00
Add transition for selecting a beatmap
This commit is contained in:
parent
f0d6641adf
commit
1be3b990e7
@ -10,6 +10,7 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Pooling;
|
using osu.Framework.Graphics.Pooling;
|
||||||
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
@ -260,6 +261,32 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Animation
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Moves non-selected beatmaps to the right, hiding off-screen.
|
||||||
|
/// </summary>
|
||||||
|
public bool VisuallyFocusSelected { get; set; }
|
||||||
|
|
||||||
|
private float selectionFocusOffset;
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
selectionFocusOffset = (float)Interpolation.DampContinuously(selectionFocusOffset, VisuallyFocusSelected ? 300 : 0, 100, Time.Elapsed);
|
||||||
|
|
||||||
|
foreach (var panel in Scroll.Panels)
|
||||||
|
{
|
||||||
|
var c = (ICarouselPanel)panel;
|
||||||
|
|
||||||
|
if (!c.Selected.Value)
|
||||||
|
panel.X += selectionFocusOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Filtering
|
#region Filtering
|
||||||
|
|
||||||
public FilterCriteria Criteria { get; private set; } = new FilterCriteria();
|
public FilterCriteria Criteria { get; private set; } = new FilterCriteria();
|
||||||
|
@ -75,7 +75,7 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The number of items currently actualised into drawables.
|
/// The number of items currently actualised into drawables.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int VisibleItems => scroll.Panels.Count;
|
public int VisibleItems => Scroll.Panels.Count;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The currently selected model. Generally of type T.
|
/// The currently selected model. Generally of type T.
|
||||||
@ -185,7 +185,7 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
/// <param name="item">The item to find a related drawable representation.</param>
|
/// <param name="item">The item to find a related drawable representation.</param>
|
||||||
/// <returns>The drawable representation if it exists.</returns>
|
/// <returns>The drawable representation if it exists.</returns>
|
||||||
protected Drawable? GetMaterialisedDrawableForItem(CarouselItem item) =>
|
protected Drawable? GetMaterialisedDrawableForItem(CarouselItem item) =>
|
||||||
scroll.Panels.SingleOrDefault(p => ((ICarouselPanel)p).Item == item);
|
Scroll.Panels.SingleOrDefault(p => ((ICarouselPanel)p).Item == item);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When a user is traversing the carousel via group selection keys, assert whether the item provided is a valid target.
|
/// When a user is traversing the carousel via group selection keys, assert whether the item provided is a valid target.
|
||||||
@ -222,11 +222,11 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
|
|
||||||
#region Initialisation
|
#region Initialisation
|
||||||
|
|
||||||
private readonly CarouselScrollContainer scroll;
|
protected readonly CarouselScrollContainer Scroll;
|
||||||
|
|
||||||
protected Carousel()
|
protected Carousel()
|
||||||
{
|
{
|
||||||
InternalChild = scroll = new CarouselScrollContainer
|
InternalChild = Scroll = new CarouselScrollContainer
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
};
|
};
|
||||||
@ -499,13 +499,13 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
// If a keyboard selection is currently made, we want to keep the view stable around the selection.
|
// If a keyboard selection is currently made, we want to keep the view stable around the selection.
|
||||||
// That means that we should offset the immediate scroll position by any change in Y position for the selection.
|
// That means that we should offset the immediate scroll position by any change in Y position for the selection.
|
||||||
if (prevKeyboard.YPosition != null && currentKeyboardSelection.YPosition != prevKeyboard.YPosition)
|
if (prevKeyboard.YPosition != null && currentKeyboardSelection.YPosition != prevKeyboard.YPosition)
|
||||||
scroll.OffsetScrollPosition((float)(currentKeyboardSelection.YPosition!.Value - prevKeyboard.YPosition.Value));
|
Scroll.OffsetScrollPosition((float)(currentKeyboardSelection.YPosition!.Value - prevKeyboard.YPosition.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scrollToSelection()
|
private void scrollToSelection()
|
||||||
{
|
{
|
||||||
if (currentKeyboardSelection.CarouselItem != null)
|
if (currentKeyboardSelection.CarouselItem != null)
|
||||||
scroll.ScrollTo(currentKeyboardSelection.CarouselItem.CarouselYPosition - visibleHalfHeight);
|
Scroll.ScrollTo(currentKeyboardSelection.CarouselItem.CarouselYPosition - visibleHalfHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -519,12 +519,12 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The position of the lower visible bound with respect to the current scroll position.
|
/// The position of the lower visible bound with respect to the current scroll position.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private float visibleBottomBound => (float)(scroll.Current + DrawHeight + BleedBottom);
|
private float visibleBottomBound => (float)(Scroll.Current + DrawHeight + BleedBottom);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The position of the upper visible bound with respect to the current scroll position.
|
/// The position of the upper visible bound with respect to the current scroll position.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private float visibleUpperBound => (float)(scroll.Current - BleedTop);
|
private float visibleUpperBound => (float)(Scroll.Current - BleedTop);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Half the height of the visible content.
|
/// Half the height of the visible content.
|
||||||
@ -557,7 +557,7 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
|
|
||||||
double selectedYPos = currentSelection.CarouselItem?.CarouselYPosition ?? 0;
|
double selectedYPos = currentSelection.CarouselItem?.CarouselYPosition ?? 0;
|
||||||
|
|
||||||
foreach (var panel in scroll.Panels)
|
foreach (var panel in Scroll.Panels)
|
||||||
{
|
{
|
||||||
var c = (ICarouselPanel)panel;
|
var c = (ICarouselPanel)panel;
|
||||||
|
|
||||||
@ -566,12 +566,12 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
float normalisedDepth = (float)(Math.Abs(selectedYPos - c.DrawYPosition) / DrawHeight);
|
float normalisedDepth = (float)(Math.Abs(selectedYPos - c.DrawYPosition) / DrawHeight);
|
||||||
scroll.Panels.ChangeChildDepth(panel, c.Item.DepthLayer + normalisedDepth);
|
Scroll.Panels.ChangeChildDepth(panel, c.Item.DepthLayer + normalisedDepth);
|
||||||
|
|
||||||
if (c.DrawYPosition != c.Item.CarouselYPosition)
|
if (c.DrawYPosition != c.Item.CarouselYPosition)
|
||||||
c.DrawYPosition = Interpolation.DampContinuously(c.DrawYPosition, c.Item.CarouselYPosition, 50, Time.Elapsed);
|
c.DrawYPosition = Interpolation.DampContinuously(c.DrawYPosition, c.Item.CarouselYPosition, 50, Time.Elapsed);
|
||||||
|
|
||||||
Vector2 posInScroll = scroll.ToLocalSpace(panel.ScreenSpaceDrawQuad.Centre);
|
Vector2 posInScroll = Scroll.ToLocalSpace(panel.ScreenSpaceDrawQuad.Centre);
|
||||||
float dist = Math.Abs(1f - posInScroll.Y / visibleHalfHeight);
|
float dist = Math.Abs(1f - posInScroll.Y / visibleHalfHeight);
|
||||||
|
|
||||||
panel.X = offsetX(dist, visibleHalfHeight);
|
panel.X = offsetX(dist, visibleHalfHeight);
|
||||||
@ -628,7 +628,7 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
toDisplay.RemoveAll(i => !i.IsVisible);
|
toDisplay.RemoveAll(i => !i.IsVisible);
|
||||||
|
|
||||||
// Iterate over all panels which are already displayed and figure which need to be displayed / removed.
|
// Iterate over all panels which are already displayed and figure which need to be displayed / removed.
|
||||||
foreach (var panel in scroll.Panels)
|
foreach (var panel in Scroll.Panels)
|
||||||
{
|
{
|
||||||
var carouselPanel = (ICarouselPanel)panel;
|
var carouselPanel = (ICarouselPanel)panel;
|
||||||
|
|
||||||
@ -658,7 +658,7 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
carouselPanel.DrawYPosition = item.CarouselYPosition;
|
carouselPanel.DrawYPosition = item.CarouselYPosition;
|
||||||
carouselPanel.Item = item;
|
carouselPanel.Item = item;
|
||||||
|
|
||||||
scroll.Add(drawable);
|
Scroll.Add(drawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the total height of all items (to make the scroll container scrollable through the full height even though
|
// Update the total height of all items (to make the scroll container scrollable through the full height even though
|
||||||
@ -666,10 +666,10 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
if (carouselItems.Count > 0)
|
if (carouselItems.Count > 0)
|
||||||
{
|
{
|
||||||
var lastItem = carouselItems[^1];
|
var lastItem = carouselItems[^1];
|
||||||
scroll.SetLayoutHeight((float)(lastItem.CarouselYPosition + lastItem.DrawHeight + visibleHalfHeight));
|
Scroll.SetLayoutHeight((float)(lastItem.CarouselYPosition + lastItem.DrawHeight + visibleHalfHeight));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
scroll.SetLayoutHeight(0);
|
Scroll.SetLayoutHeight(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void expirePanelImmediately(Drawable panel)
|
private static void expirePanelImmediately(Drawable panel)
|
||||||
@ -713,7 +713,7 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
/// Implementation of scroll container which handles very large vertical lists by internally using <c>double</c> precision
|
/// Implementation of scroll container which handles very large vertical lists by internally using <c>double</c> precision
|
||||||
/// for pre-display Y values.
|
/// for pre-display Y values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private partial class CarouselScrollContainer : UserTrackingScrollContainer, IKeyBindingHandler<GlobalAction>
|
protected partial class CarouselScrollContainer : UserTrackingScrollContainer, IKeyBindingHandler<GlobalAction>
|
||||||
{
|
{
|
||||||
public readonly Container Panels;
|
public readonly Container Panels;
|
||||||
|
|
||||||
|
@ -99,9 +99,13 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
base.OnEntering(e);
|
base.OnEntering(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const double fade_duration = 300;
|
||||||
|
|
||||||
public override void OnResuming(ScreenTransitionEvent e)
|
public override void OnResuming(ScreenTransitionEvent e)
|
||||||
{
|
{
|
||||||
this.FadeIn();
|
this.FadeIn(fade_duration, Easing.OutQuint);
|
||||||
|
|
||||||
|
carousel.VisuallyFocusSelected = false;
|
||||||
|
|
||||||
// required due to https://github.com/ppy/osu-framework/issues/3218
|
// required due to https://github.com/ppy/osu-framework/issues/3218
|
||||||
modSelectOverlay.SelectedMods.Disabled = false;
|
modSelectOverlay.SelectedMods.Disabled = false;
|
||||||
@ -112,16 +116,18 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
|
|
||||||
public override void OnSuspending(ScreenTransitionEvent e)
|
public override void OnSuspending(ScreenTransitionEvent e)
|
||||||
{
|
{
|
||||||
this.Delay(400).FadeOut();
|
this.Delay(100).FadeOut(fade_duration, Easing.OutQuint);
|
||||||
|
|
||||||
modSelectOverlay.SelectedMods.UnbindFrom(Mods);
|
modSelectOverlay.SelectedMods.UnbindFrom(Mods);
|
||||||
|
|
||||||
|
carousel.VisuallyFocusSelected = true;
|
||||||
|
|
||||||
base.OnSuspending(e);
|
base.OnSuspending(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnExiting(ScreenExitEvent e)
|
public override bool OnExiting(ScreenExitEvent e)
|
||||||
{
|
{
|
||||||
this.Delay(400).FadeOut();
|
this.FadeOut(fade_duration, Easing.OutQuint);
|
||||||
return base.OnExiting(e);
|
return base.OnExiting(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user