2019-01-24 16:43:03 +08:00
// 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 17:19:50 +08:00
2018-12-20 20:06:40 +08:00
using System ;
2018-04-13 17:19:50 +08:00
using System.Collections.Generic ;
2018-12-20 20:06:40 +08:00
using System.Linq ;
2019-02-21 18:04:31 +08:00
using osu.Framework.Bindables ;
2018-04-13 17:19:50 +08:00
using osu.Framework.Graphics ;
using osu.Framework.Graphics.Containers ;
using osu.Framework.Graphics.UserInterface ;
using osu.Game.Graphics.Sprites ;
using osu.Game.Rulesets.Mods ;
using osu.Game.Rulesets.UI ;
2018-11-20 15:51:59 +08:00
using osuTK ;
2018-04-13 17:19:50 +08:00
using osu.Game.Graphics.Containers ;
2018-10-02 11:02:47 +08:00
using osu.Framework.Input.Events ;
2019-02-12 12:04:46 +08:00
using osu.Game.Graphics ;
2018-04-13 17:19:50 +08:00
namespace osu.Game.Screens.Play.HUD
{
2019-04-10 16:13:12 +08:00
public class ModDisplay : Container , IHasCurrentValue < IReadOnlyList < Mod > >
2018-04-13 17:19:50 +08:00
{
private const int fade_duration = 1000 ;
2018-12-12 13:38:03 +08:00
public bool DisplayUnrankedText = true ;
2020-02-13 17:05:53 +08:00
public ExpansionMode ExpansionMode = ExpansionMode . ExpandOnHover ;
2019-05-08 17:42:26 +08:00
2021-02-01 17:50:32 +08:00
/// <summary>
/// Whether the mods should initially appear expanded, before potentially contracting into their final expansion state (depending on <see cref="ExpansionMode"/>).
/// </summary>
2021-02-01 16:54:56 +08:00
public bool ExpandOnAppear = true ;
2019-04-10 16:13:12 +08:00
private readonly Bindable < IReadOnlyList < Mod > > current = new Bindable < IReadOnlyList < Mod > > ( ) ;
2018-12-20 20:06:40 +08:00
2019-04-10 16:13:12 +08:00
public Bindable < IReadOnlyList < Mod > > Current
2018-12-20 20:06:40 +08:00
{
get = > current ;
set
{
if ( value = = null )
throw new ArgumentNullException ( nameof ( value ) ) ;
2018-04-13 17:19:50 +08:00
2018-12-20 20:06:40 +08:00
current . UnbindBindings ( ) ;
current . BindTo ( value ) ;
}
}
2018-04-13 17:19:50 +08:00
2020-04-06 05:53:49 +08:00
private readonly FillFlowContainer < ModIcon > iconsContainer ;
2018-04-13 17:19:50 +08:00
private readonly OsuSpriteText unrankedText ;
public ModDisplay ( )
{
2018-12-12 13:38:03 +08:00
AutoSizeAxes = Axes . Both ;
2020-10-15 16:10:35 +08:00
Child = new FillFlowContainer
2018-04-13 17:19:50 +08:00
{
2020-10-15 16:10:35 +08:00
Anchor = Anchor . TopCentre ,
Origin = Anchor . TopCentre ,
AutoSizeAxes = Axes . Both ,
Direction = FillDirection . Vertical ,
Children = new Drawable [ ]
2018-04-13 17:19:50 +08:00
{
2020-10-15 16:10:35 +08:00
iconsContainer = new ReverseChildIDFillFlowContainer < ModIcon >
{
Anchor = Anchor . TopCentre ,
Origin = Anchor . TopCentre ,
AutoSizeAxes = Axes . Both ,
Direction = FillDirection . Horizontal ,
} ,
unrankedText = new OsuSpriteText
{
Anchor = Anchor . TopCentre ,
Origin = Anchor . TopCentre ,
Text = @"/ UNRANKED /" ,
Font = OsuFont . Numeric . With ( size : 12 )
}
2018-04-13 17:19:50 +08:00
} ,
} ;
2018-12-20 20:06:40 +08:00
Current . ValueChanged + = mods = >
2018-04-13 17:19:50 +08:00
{
2020-04-06 05:53:49 +08:00
iconsContainer . Clear ( ) ;
2019-04-01 11:16:05 +08:00
2019-02-22 16:51:39 +08:00
foreach ( Mod mod in mods . NewValue )
2018-04-13 17:19:50 +08:00
{
2020-04-06 05:53:49 +08:00
iconsContainer . Add ( new ModIcon ( mod ) { Scale = new Vector2 ( 0.6f ) } ) ;
2018-04-13 17:19:50 +08:00
}
if ( IsLoaded )
appearTransform ( ) ;
} ;
}
2018-08-20 23:15:51 +08:00
protected override void Dispose ( bool isDisposing )
{
base . Dispose ( isDisposing ) ;
2018-12-20 20:06:40 +08:00
Current . UnbindAll ( ) ;
2018-08-20 23:15:51 +08:00
}
2018-04-13 17:19:50 +08:00
protected override void LoadComplete ( )
{
base . LoadComplete ( ) ;
2019-05-08 17:42:26 +08:00
2018-04-13 17:19:50 +08:00
appearTransform ( ) ;
2020-04-06 05:53:49 +08:00
iconsContainer . FadeInFromZero ( fade_duration , Easing . OutQuint ) ;
2018-04-13 17:19:50 +08:00
}
private void appearTransform ( )
{
2018-12-22 13:02:45 +08:00
if ( DisplayUnrankedText & & Current . Value . Any ( m = > ! m . Ranked ) )
2018-04-13 17:19:50 +08:00
unrankedText . FadeInFromZero ( fade_duration , Easing . OutQuint ) ;
else
unrankedText . Hide ( ) ;
2021-02-02 12:41:01 +08:00
expand ( ) ;
using ( iconsContainer . BeginDelayedSequence ( ExpandOnAppear ? 1200 : 0 ) )
contract ( ) ;
2018-04-13 17:19:50 +08:00
}
2019-05-08 17:42:26 +08:00
private void expand ( )
{
2020-02-13 17:05:53 +08:00
if ( ExpansionMode ! = ExpansionMode . AlwaysContracted )
2020-04-06 05:53:49 +08:00
iconsContainer . TransformSpacingTo ( new Vector2 ( 5 , 0 ) , 500 , Easing . OutQuint ) ;
2019-05-08 17:42:26 +08:00
}
2018-04-13 17:19:50 +08:00
2020-02-13 17:05:53 +08:00
private void contract ( )
{
if ( ExpansionMode ! = ExpansionMode . AlwaysExpanded )
2020-04-06 05:53:49 +08:00
iconsContainer . TransformSpacingTo ( new Vector2 ( - 25 , 0 ) , 500 , Easing . OutQuint ) ;
2020-02-13 17:05:53 +08:00
}
2018-04-13 17:19:50 +08:00
2018-10-02 11:02:47 +08:00
protected override bool OnHover ( HoverEvent e )
2018-04-13 17:19:50 +08:00
{
expand ( ) ;
2018-10-02 11:02:47 +08:00
return base . OnHover ( e ) ;
2018-04-13 17:19:50 +08:00
}
2018-10-02 11:02:47 +08:00
protected override void OnHoverLost ( HoverLostEvent e )
2018-04-13 17:19:50 +08:00
{
contract ( ) ;
2018-10-02 11:02:47 +08:00
base . OnHoverLost ( e ) ;
2018-04-13 17:19:50 +08:00
}
}
2020-02-13 17:05:53 +08:00
public enum ExpansionMode
{
/// <summary>
/// The <see cref="ModDisplay"/> will expand only when hovered.
/// </summary>
ExpandOnHover ,
/// <summary>
/// The <see cref="ModDisplay"/> will always be expanded.
/// </summary>
AlwaysExpanded ,
/// <summary>
/// The <see cref="ModDisplay"/> will always be contracted.
/// </summary>
AlwaysContracted
}
2018-04-13 17:19:50 +08:00
}