1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-18 21:10:46 +08:00
Files
osu-lazer/osu.Game/Screens/SelectV2/PanelGroup.cs
T
Dean Herbert 891f0c469f Add context menus to new carousel panels
This changes the flow of actions (yet again.. sorry) to standardise what
is shown on the beatmap options button in the footer and the context
menus.

This is something I wanted from the start – for devices where right
click is not available, it's always preferable to have a second method
of accessing actions which isn't the context menu.

Collection actions are missing for now, as they will come in a second
pass which includes tidying things up further.

Fix formatting

Duplicate menu items between implementations
2025-05-23 16:02:13 +09:00

176 lines
6.1 KiB
C#

// 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.
using System;
using System.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Carousel;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Screens.SelectV2
{
public partial class PanelGroup : Panel
{
public const float HEIGHT = CarouselItem.DEFAULT_HEIGHT * 1.2f;
private Drawable iconContainer = null!;
private OsuSpriteText titleText = null!;
private TrianglesV2 triangles = null!;
private CircularContainer countPill = null!;
private OsuSpriteText countText = null!;
private Box glow = null!;
[Resolved]
private OverlayColourProvider colourProvider { get; set; } = null!;
[BackgroundDependencyLoader]
private void load()
{
Height = HEIGHT;
Icon = iconContainer = new Container
{
AlwaysPresent = true,
RelativeSizeAxes = Axes.Y,
Child = new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.Solid.ChevronDown,
Size = new Vector2(12),
Colour = colourProvider.Background3,
},
};
Background = new Container
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background5,
},
triangles = new TrianglesV2
{
RelativeSizeAxes = Axes.Both,
Thickness = 0.02f,
SpawnRatio = 0.6f,
Colour = ColourInfo.GradientHorizontal(colourProvider.Background6, colourProvider.Background5)
},
glow = new Box
{
RelativeSizeAxes = Axes.Both,
Width = 0.5f,
Colour = ColourInfo.GradientHorizontal(colourProvider.Highlight1, colourProvider.Highlight1.Opacity(0f)),
},
},
};
AccentColour = colourProvider.Highlight1;
Content.Children = new Drawable[]
{
titleText = new OsuSpriteText
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Font = OsuFont.Style.Heading2,
UseFullGlyphHeight = false,
X = 10f,
},
countPill = new CircularContainer
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Size = new Vector2(50f, 14f),
Margin = new MarginPadding { Right = 30f },
Masking = true,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(0.7f),
},
countText = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = OsuFont.Style.Caption1.With(weight: FontWeight.Bold),
UseFullGlyphHeight = false,
}
},
},
};
}
protected override void LoadComplete()
{
base.LoadComplete();
Expanded.BindValueChanged(_ => onExpanded(), true);
}
private void onExpanded()
{
const float duration = 500;
iconContainer.ResizeWidthTo(Expanded.Value ? 20f : 5f, duration, Easing.OutQuint);
iconContainer.FadeTo(Expanded.Value ? 1f : 0f, duration, Easing.OutQuint);
ColourInfo colour = Expanded.Value
? ColourInfo.GradientHorizontal(colourProvider.Highlight1.Opacity(0.25f), colourProvider.Highlight1.Opacity(0f))
: ColourInfo.GradientHorizontal(colourProvider.Background6, colourProvider.Background5);
triangles.FadeColour(colour, duration, Easing.OutQuint);
glow.FadeTo(Expanded.Value ? 0.4f : 0, duration, Easing.OutQuint);
}
protected override void PrepareForUse()
{
base.PrepareForUse();
Debug.Assert(Item != null);
GroupDefinition group = (GroupDefinition)Item.Model;
titleText.Text = group.Title;
countText.Text = Item.NestedItemCount.ToString("N0");
}
protected override void Update()
{
base.Update();
// Move the count pill in the opposite direction to keep it pinned to the screen regardless of the X position of TopLevelContent.
countPill.X = -TopLevelContent.X;
}
public override MenuItem[] ContextMenuItems
{
get
{
if (Item == null)
return Array.Empty<MenuItem>();
return new MenuItem[]
{
new OsuMenuItem(Expanded.Value ? "Collapse" : "Expand", MenuItemType.Highlighted, () => TriggerClick())
};
}
}
}
}