diff --git a/osu.Game/Overlays/Direct/DirectRulesetSelector.cs b/osu.Game/Overlays/Direct/DirectRulesetSelector.cs new file mode 100644 index 0000000000..b42633eed3 --- /dev/null +++ b/osu.Game/Overlays/Direct/DirectRulesetSelector.cs @@ -0,0 +1,94 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Direct +{ + public class DirectRulesetSelector : RulesetSelector + { + public override bool HandleNonPositionalInput => !Current.Disabled && base.HandleNonPositionalInput; + + public override bool HandlePositionalInput => !Current.Disabled && base.HandlePositionalInput; + + public override bool PropagatePositionalInputSubTree => !Current.Disabled && base.PropagatePositionalInputSubTree; + + public DirectRulesetSelector() + { + TabContainer.Masking = false; + TabContainer.Spacing = new Vector2(10, 0); + AutoSizeAxes = Axes.Both; + + Current.DisabledChanged += value => SelectedTab.FadeColour(value ? Color4.DarkGray : Color4.White, 200, Easing.OutQuint); + } + + protected override TabItem CreateTabItem(RulesetInfo value) => new DirectRulesetTabItem(value); + + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer + { + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + }; + + private class DirectRulesetTabItem : TabItem + { + private readonly SpriteIcon icon; + + public DirectRulesetTabItem(RulesetInfo value) + : base(value) + { + AutoSizeAxes = Axes.Both; + + Children = new Drawable[] + { + icon = (SpriteIcon)value.CreateInstance().CreateIcon(), + new HoverClickSounds() + }; + + icon.Size = new Vector2(30); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + updateState(); + } + + protected override bool OnHover(HoverEvent e) + { + base.OnHover(e); + updateState(); + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + updateState(); + } + + protected override void OnActivated() => updateState(); + + protected override void OnDeactivated() => updateState(); + + private void updateState() + { + if (IsHovered || Active.Value) + { + icon.FadeColour(Color4.White, 120, Easing.InQuad); + } + else + icon.FadeColour(Color4.Gray, 120, Easing.InQuad); + } + } + } +} diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index 268e011350..4b43542b43 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -4,105 +4,30 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests; using osu.Game.Overlays.SearchableList; using osu.Game.Rulesets; -using osuTK; using osuTK.Graphics; namespace osu.Game.Overlays.Direct { public class FilterControl : SearchableListFilterControl { - public readonly Bindable Ruleset = new Bindable(); - private FillFlowContainer modeButtons; + private DirectRulesetSelector rulesetSelector; protected override Color4 BackgroundColour => OsuColour.FromHex(@"384552"); protected override DirectSortCriteria DefaultTab => DirectSortCriteria.Ranked; - protected override Drawable CreateSupplementaryControls() - { - modeButtons = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Spacing = new Vector2(10f, 0f), - }; + protected override Drawable CreateSupplementaryControls() => rulesetSelector = new DirectRulesetSelector(); - return modeButtons; - } + public Bindable Ruleset => rulesetSelector.Current; [BackgroundDependencyLoader(true)] - private void load(RulesetStore rulesets, OsuColour colours, Bindable ruleset) + private void load(OsuColour colours, Bindable ruleset) { DisplayStyleControl.Dropdown.AccentColour = colours.BlueDark; - - Ruleset.Value = ruleset.Value ?? rulesets.GetRuleset(0); - foreach (var r in rulesets.AvailableRulesets) - modeButtons.Add(new RulesetToggleButton(Ruleset, r)); - } - - private class RulesetToggleButton : OsuClickableContainer - { - private Drawable icon - { - get => iconContainer.Icon; - set => iconContainer.Icon = value; - } - - private RulesetInfo ruleset; - - public RulesetInfo Ruleset - { - get => ruleset; - set - { - ruleset = value; - icon = Ruleset.CreateInstance().CreateIcon(); - } - } - - private readonly Bindable bindable; - - private readonly ConstrainedIconContainer iconContainer; - - private void Bindable_ValueChanged(ValueChangedEvent e) - { - iconContainer.FadeTo(Ruleset.ID == e.NewValue?.ID ? 1f : 0.5f, 100); - } - - public override bool HandleNonPositionalInput => !bindable.Disabled && base.HandleNonPositionalInput; - public override bool HandlePositionalInput => !bindable.Disabled && base.HandlePositionalInput; - - public RulesetToggleButton(Bindable bindable, RulesetInfo ruleset) - { - this.bindable = bindable; - AutoSizeAxes = Axes.Both; - - Children = new[] - { - iconContainer = new ConstrainedIconContainer - { - Origin = Anchor.TopLeft, - Anchor = Anchor.TopLeft, - Size = new Vector2(32), - } - }; - - Ruleset = ruleset; - bindable.ValueChanged += Bindable_ValueChanged; - Bindable_ValueChanged(new ValueChangedEvent(bindable.Value, bindable.Value)); - Action = () => bindable.Value = Ruleset; - } - - protected override void Dispose(bool isDisposing) - { - if (bindable != null) - bindable.ValueChanged -= Bindable_ValueChanged; - base.Dispose(isDisposing); - } + rulesetSelector.Current.BindTo(ruleset); } }