osu/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs

165 lines
4.6 KiB
C#
Raw Normal View History

// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
2018-04-13 09:19:50 +00:00
2020-10-12 06:36:03 +00:00
using System.Diagnostics;
using osu.Framework.Bindables;
2018-04-13 09:19:50 +00:00
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
2020-10-12 06:36:03 +00:00
using osu.Framework.Graphics.Pooling;
2018-10-02 03:02:47 +00:00
using osu.Framework.Input.Events;
using osuTK;
2018-04-13 09:19:50 +00:00
namespace osu.Game.Screens.Select.Carousel
{
2020-10-12 06:36:03 +00:00
public abstract class DrawableCarouselItem : PoolableDrawable
2018-04-13 09:19:50 +00:00
{
public const float MAX_HEIGHT = 80;
2020-10-12 06:36:03 +00:00
public override bool IsPresent => base.IsPresent || Item?.Visible == true;
2018-04-13 09:19:50 +00:00
public readonly CarouselHeader Header;
2020-10-13 06:32:37 +00:00
/// <summary>
/// Optional content which sits below the header.
/// </summary>
protected readonly Container<Drawable> Content;
protected readonly Container MovementContainer;
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) =>
Header.ReceivePositionalInputAt(screenSpacePos);
private CarouselItem item;
2020-10-12 06:36:03 +00:00
public CarouselItem Item
{
get => item;
set
{
if (item == value)
return;
if (item != null)
{
item.Filtered.ValueChanged -= onStateChange;
item.State.ValueChanged -= onStateChange;
Header.State.UnbindFrom(item.State);
if (item is CarouselGroup group)
{
foreach (var c in group.Children)
c.Filtered.ValueChanged -= onStateChange;
}
2020-10-12 06:36:03 +00:00
}
2018-04-13 09:19:50 +00:00
2020-10-12 06:36:03 +00:00
item = value;
if (IsLoaded)
UpdateItem();
}
}
2018-04-13 09:19:50 +00:00
2020-10-12 06:36:03 +00:00
protected DrawableCarouselItem()
2018-04-13 09:19:50 +00:00
{
RelativeSizeAxes = Axes.X;
2018-04-13 09:19:50 +00:00
Alpha = 0;
InternalChildren = new Drawable[]
2018-04-13 09:19:50 +00:00
{
MovementContainer = new Container
2018-04-13 09:19:50 +00:00
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
2018-04-13 09:19:50 +00:00
{
Header = new CarouselHeader(),
Content = new Container
{
RelativeSizeAxes = Axes.Both,
}
}
},
2018-04-13 09:19:50 +00:00
};
}
public void SetMultiplicativeAlpha(float alpha) => Header.BorderContainer.Alpha = alpha;
2018-04-13 09:19:50 +00:00
protected override void LoadComplete()
{
base.LoadComplete();
UpdateItem();
}
protected override void Update()
{
base.Update();
2020-10-13 06:32:37 +00:00
Content.Y = Header.Height;
2020-10-12 06:36:03 +00:00
}
protected virtual void UpdateItem()
{
if (item == null)
return;
2020-10-12 09:13:25 +00:00
Scheduler.AddOnce(ApplyState);
2020-10-12 06:36:03 +00:00
Item.Filtered.ValueChanged += onStateChange;
Item.State.ValueChanged += onStateChange;
Header.State.BindTo(Item.State);
if (Item is CarouselGroup group)
{
foreach (var c in group.Children)
c.Filtered.ValueChanged += onStateChange;
}
2018-04-13 09:19:50 +00:00
}
2020-10-12 09:13:25 +00:00
private void onStateChange(ValueChangedEvent<CarouselItemState> obj) => Scheduler.AddOnce(ApplyState);
2020-10-12 06:36:03 +00:00
2020-10-12 09:13:25 +00:00
private void onStateChange(ValueChangedEvent<bool> _) => Scheduler.AddOnce(ApplyState);
2020-10-12 06:36:03 +00:00
2018-04-13 09:19:50 +00:00
protected virtual void ApplyState()
{
// 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;
2020-10-12 06:36:03 +00:00
Debug.Assert(Item != null);
2018-04-13 09:19:50 +00:00
switch (Item.State.Value)
{
case CarouselItemState.NotSelected:
Deselected();
break;
2019-04-01 03:44:46 +00:00
2018-04-13 09:19:50 +00:00
case CarouselItemState.Selected:
Selected();
break;
}
if (!Item.Visible)
this.FadeOut(300, Easing.OutQuint);
else
this.FadeIn(250);
}
protected virtual void Selected()
{
2020-10-12 06:36:03 +00:00
Debug.Assert(Item != null);
2018-04-13 09:19:50 +00:00
}
protected virtual void Deselected()
{
}
2018-10-02 03:02:47 +00:00
protected override bool OnClick(ClickEvent e)
2018-04-13 09:19:50 +00:00
{
Item.State.Value = CarouselItemState.Selected;
return true;
}
}
}