1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-13 19:53:23 +08:00

Merge pull request #16716 from peppy/carousel-less-invalidations

Refactor carousel drawables to reduce invalidations
This commit is contained in:
Dan Balasescu 2022-01-31 15:52:08 +09:00 committed by GitHub
commit 8d13e0514b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 68 additions and 54 deletions

View File

@ -894,10 +894,8 @@ namespace osu.Game.Screens.Select
// child items (difficulties) are still visible.
item.Header.X = offsetX(dist, visibleHalfHeight) - (parent?.X ?? 0);
// We are applying a multiplicative alpha (which is internally done by nesting an
// additional container and setting that container's alpha) such that we can
// layer alpha transformations on top.
item.SetMultiplicativeAlpha(Math.Clamp(1.75f - 1.5f * dist, 0, 1));
// We are applying alpha to the header here such that we can layer alpha transformations on top.
item.Header.Alpha = Math.Clamp(1.75f - 1.5f * dist, 0, 1);
}
private enum PendingScrollOperation

View File

@ -21,8 +21,6 @@ namespace osu.Game.Screens.Select.Carousel
{
public class CarouselHeader : Container
{
public Container BorderContainer;
public readonly Bindable<CarouselItemState> State = new Bindable<CarouselItemState>(CarouselItemState.NotSelected);
private readonly HoverLayer hoverLayer;
@ -37,17 +35,14 @@ namespace osu.Game.Screens.Select.Carousel
RelativeSizeAxes = Axes.X;
Height = DrawableCarouselItem.MAX_HEIGHT;
InternalChild = BorderContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Masking = true,
CornerRadius = corner_radius,
BorderColour = new Color4(221, 255, 255, 255),
Children = new Drawable[]
Masking = true;
CornerRadius = corner_radius;
BorderColour = new Color4(221, 255, 255, 255);
InternalChildren = new Drawable[]
{
Content,
hoverLayer = new HoverLayer()
}
};
}
@ -66,21 +61,21 @@ namespace osu.Game.Screens.Select.Carousel
case CarouselItemState.NotSelected:
hoverLayer.InsetForBorder = false;
BorderContainer.BorderThickness = 0;
BorderContainer.EdgeEffect = new EdgeEffectParameters
BorderThickness = 0;
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Shadow,
Offset = new Vector2(1),
Radius = 10,
Colour = Color4.Black.Opacity(100),
Colour = Color4.Black.Opacity(0.5f),
};
break;
case CarouselItemState.Selected:
hoverLayer.InsetForBorder = true;
BorderContainer.BorderThickness = border_thickness;
BorderContainer.EdgeEffect = new EdgeEffectParameters
BorderThickness = border_thickness;
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Colour = new Color4(130, 204, 255, 150),

View File

@ -36,9 +36,9 @@ namespace osu.Game.Screens.Select.Carousel
/// <summary>
/// The height of a carousel beatmap, including vertical spacing.
/// </summary>
public const float HEIGHT = height + CAROUSEL_BEATMAP_SPACING;
public const float HEIGHT = header_height + CAROUSEL_BEATMAP_SPACING;
private const float height = MAX_HEIGHT * 0.6f;
private const float header_height = MAX_HEIGHT * 0.6f;
private readonly BeatmapInfo beatmapInfo;
@ -67,16 +67,18 @@ namespace osu.Game.Screens.Select.Carousel
private CancellationTokenSource starDifficultyCancellationSource;
public DrawableCarouselBeatmap(CarouselBeatmap panel)
: base(header_height)
{
beatmapInfo = panel.BeatmapInfo;
Item = panel;
// Difficulty panels should start hidden for a better initial effect.
Hide();
}
[BackgroundDependencyLoader(true)]
private void load(BeatmapManager manager, SongSelect songSelect)
{
Header.Height = height;
if (songSelect != null)
{
startRequested = b => songSelect.FinaliseSelection(b);

View File

@ -122,12 +122,10 @@ namespace osu.Game.Screens.Select.Carousel
},
};
background.DelayedLoadComplete += fadeContentIn;
mainFlow.DelayedLoadComplete += fadeContentIn;
background.DelayedLoadComplete += d => d.FadeInFromZero(750, Easing.OutQuint);
mainFlow.DelayedLoadComplete += d => d.FadeInFromZero(500, Easing.OutQuint);
}
private void fadeContentIn(Drawable d) => d.FadeInFromZero(750, Easing.OutQuint);
protected override void Deselected()
{
base.Deselected();

View File

@ -60,12 +60,10 @@ namespace osu.Game.Screens.Select.Carousel
}
}
protected DrawableCarouselItem()
protected DrawableCarouselItem(float headerHeight = MAX_HEIGHT)
{
RelativeSizeAxes = Axes.X;
Alpha = 0;
InternalChildren = new Drawable[]
{
MovementContainer = new Container
@ -73,18 +71,20 @@ namespace osu.Game.Screens.Select.Carousel
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
Header = new CarouselHeader(),
Header = new CarouselHeader
{
Height = headerHeight,
},
Content = new Container
{
RelativeSizeAxes = Axes.Both,
Y = headerHeight,
}
}
},
};
}
public void SetMultiplicativeAlpha(float alpha) => Header.BorderContainer.Alpha = alpha;
protected override void LoadComplete()
{
base.LoadComplete();
@ -92,12 +92,6 @@ namespace osu.Game.Screens.Select.Carousel
UpdateItem();
}
protected override void Update()
{
base.Update();
Content.Y = Header.Height;
}
protected virtual void UpdateItem()
{
if (item == null)
@ -121,15 +115,21 @@ namespace osu.Game.Screens.Select.Carousel
private void onStateChange(ValueChangedEvent<bool> _) => Scheduler.AddOnce(ApplyState);
private CarouselItemState? lastAppliedState;
protected virtual void ApplyState()
{
Debug.Assert(Item != null);
if (lastAppliedState != Item.State.Value)
{
lastAppliedState = Item.State.Value;
// Use the fact that we know the precise height of the item from the model to avoid the need for AutoSize overhead.
// Additionally, AutoSize doesn't work well due to content starting off-screen and being masked away.
Height = Item.TotalHeight;
Debug.Assert(Item != null);
switch (Item.State.Value)
switch (lastAppliedState)
{
case CarouselItemState.NotSelected:
Deselected();
@ -139,13 +139,34 @@ namespace osu.Game.Screens.Select.Carousel
Selected();
break;
}
}
if (!Item.Visible)
this.FadeOut(300, Easing.OutQuint);
Hide();
else
Show();
}
private bool isVisible = true;
public override void Show()
{
if (isVisible)
return;
isVisible = true;
this.FadeIn(250);
}
public override void Hide()
{
if (!isVisible)
return;
isVisible = false;
this.FadeOut(300, Easing.OutQuint);
}
protected virtual void Selected()
{
Debug.Assert(Item != null);