mirror of
https://github.com/ppy/osu.git
synced 2024-12-17 12:22:55 +08:00
Integrate hotkey display into drawable menu items
This commit is contained in:
parent
3c6c49187a
commit
3acc5fe5a0
@ -3,6 +3,7 @@
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
@ -20,12 +21,13 @@ namespace osu.Game.Graphics.UserInterface
|
||||
{
|
||||
public partial class DrawableOsuMenuItem : Menu.DrawableMenuItem
|
||||
{
|
||||
public const int MARGIN_HORIZONTAL = 17;
|
||||
public const int MARGIN_HORIZONTAL = 10;
|
||||
public const int MARGIN_VERTICAL = 4;
|
||||
private const int text_size = 17;
|
||||
private const int transition_length = 80;
|
||||
|
||||
private TextContainer text;
|
||||
protected TextContainer Text { get; private set; }
|
||||
private HotkeyDisplay hotkey;
|
||||
private HoverClickSounds hoverClickSounds;
|
||||
|
||||
public DrawableOsuMenuItem(MenuItem item)
|
||||
@ -39,32 +41,33 @@ namespace osu.Game.Graphics.UserInterface
|
||||
BackgroundColour = Color4.Transparent;
|
||||
BackgroundColourHover = Color4Extensions.FromHex(@"172023");
|
||||
|
||||
AddInternal(hotkey = new HotkeyDisplay
|
||||
{
|
||||
Alpha = 0,
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
Margin = new MarginPadding { Right = 10, Top = 1 },
|
||||
});
|
||||
AddInternal(hoverClickSounds = new HoverClickSounds());
|
||||
|
||||
updateTextColour();
|
||||
updateText();
|
||||
|
||||
bool hasSubmenu = Item.Items.Any();
|
||||
|
||||
// Only add right chevron if direction of menu items is vertical (i.e. width is relative size, see `DrawableMenuItem.SetFlowDirection()`).
|
||||
if (hasSubmenu && RelativeSizeAxes == Axes.X)
|
||||
if (showChevron)
|
||||
{
|
||||
AddInternal(new SpriteIcon
|
||||
{
|
||||
Margin = new MarginPadding(6),
|
||||
Margin = new MarginPadding { Horizontal = 10, },
|
||||
Size = new Vector2(8),
|
||||
Icon = FontAwesome.Solid.ChevronRight,
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
});
|
||||
|
||||
text.Padding = new MarginPadding
|
||||
{
|
||||
// Add some padding for the chevron above.
|
||||
Right = 5,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Only add right chevron if direction of menu items is vertical (i.e. width is relative size, see `DrawableMenuItem.SetFlowDirection()`).
|
||||
private bool showChevron => Item.Items.Any() && RelativeSizeAxes == Axes.X;
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
@ -73,23 +76,39 @@ namespace osu.Game.Graphics.UserInterface
|
||||
FinishTransforms();
|
||||
}
|
||||
|
||||
private void updateTextColour()
|
||||
private void updateText()
|
||||
{
|
||||
switch ((Item as OsuMenuItem)?.Type)
|
||||
var osuMenuItem = Item as OsuMenuItem;
|
||||
|
||||
switch (osuMenuItem?.Type)
|
||||
{
|
||||
default:
|
||||
case MenuItemType.Standard:
|
||||
text.Colour = Color4.White;
|
||||
Text.Colour = Color4.White;
|
||||
break;
|
||||
|
||||
case MenuItemType.Destructive:
|
||||
text.Colour = Color4.Red;
|
||||
Text.Colour = Color4.Red;
|
||||
break;
|
||||
|
||||
case MenuItemType.Highlighted:
|
||||
text.Colour = Color4Extensions.FromHex(@"ffcc22");
|
||||
Text.Colour = Color4Extensions.FromHex(@"ffcc22");
|
||||
break;
|
||||
}
|
||||
|
||||
hotkey.Hotkey = osuMenuItem?.Hotkey ?? default;
|
||||
hotkey.Alpha = EqualityComparer<Hotkey>.Default.Equals(hotkey.Hotkey, default) ? 0 : 1;
|
||||
}
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
{
|
||||
base.UpdateAfterChildren();
|
||||
|
||||
// this hack ensures that the menu can auto-size while leaving enough space for the hotkey display.
|
||||
// the gist of it is that while the hotkey display is not in the text / "content" that determines sizing
|
||||
// (because it cannot be, because we want the hotkey display to align to the *right* and not the left),
|
||||
// enough padding to fit the hotkey with _its_ spacing is added as padding of the text to compensate.
|
||||
Text.Padding = new MarginPadding { Right = hotkey.Alpha > 0 || showChevron ? hotkey.DrawWidth + 15 : 0 };
|
||||
}
|
||||
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
@ -111,20 +130,20 @@ namespace osu.Game.Graphics.UserInterface
|
||||
|
||||
if (IsHovered && IsActionable)
|
||||
{
|
||||
text.BoldText.FadeIn(transition_length, Easing.OutQuint);
|
||||
text.NormalText.FadeOut(transition_length, Easing.OutQuint);
|
||||
Text.BoldText.FadeIn(transition_length, Easing.OutQuint);
|
||||
Text.NormalText.FadeOut(transition_length, Easing.OutQuint);
|
||||
}
|
||||
else
|
||||
{
|
||||
text.BoldText.FadeOut(transition_length, Easing.OutQuint);
|
||||
text.NormalText.FadeIn(transition_length, Easing.OutQuint);
|
||||
Text.BoldText.FadeOut(transition_length, Easing.OutQuint);
|
||||
Text.NormalText.FadeIn(transition_length, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
|
||||
protected sealed override Drawable CreateContent() => text = CreateTextContainer();
|
||||
protected sealed override Drawable CreateContent() => Text = CreateTextContainer();
|
||||
protected virtual TextContainer CreateTextContainer() => new TextContainer();
|
||||
|
||||
protected partial class TextContainer : FillFlowContainer, IHasText
|
||||
protected partial class TextContainer : Container, IHasText
|
||||
{
|
||||
public LocalisableString Text
|
||||
{
|
||||
@ -138,39 +157,53 @@ namespace osu.Game.Graphics.UserInterface
|
||||
|
||||
public readonly SpriteText NormalText;
|
||||
public readonly SpriteText BoldText;
|
||||
public readonly Container CheckboxContainer;
|
||||
|
||||
public TextContainer()
|
||||
{
|
||||
Anchor = Anchor.CentreLeft;
|
||||
Origin = Anchor.CentreLeft;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
Spacing = new Vector2(10);
|
||||
Direction = FillDirection.Horizontal;
|
||||
|
||||
Child = new Container
|
||||
Child = new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Margin = new MarginPadding { Horizontal = MARGIN_HORIZONTAL, Vertical = MARGIN_VERTICAL },
|
||||
Spacing = new Vector2(10),
|
||||
Direction = FillDirection.Horizontal,
|
||||
Padding = new MarginPadding { Horizontal = MARGIN_HORIZONTAL, Vertical = MARGIN_VERTICAL, },
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
NormalText = new OsuSpriteText
|
||||
CheckboxContainer = new Container
|
||||
{
|
||||
AlwaysPresent = true, // ensures that the menu item does not change width when switching between normal and bold text.
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Font = OsuFont.GetFont(size: text_size),
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = MARGIN_HORIZONTAL,
|
||||
},
|
||||
BoldText = new OsuSpriteText
|
||||
new Container
|
||||
{
|
||||
AlwaysPresent = true, // ensures that the menu item does not change width when switching between normal and bold text.
|
||||
Alpha = 0,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold),
|
||||
}
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
NormalText = new OsuSpriteText
|
||||
{
|
||||
AlwaysPresent = true, // ensures that the menu item does not change width when switching between normal and bold text.
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Font = OsuFont.GetFont(size: text_size),
|
||||
},
|
||||
BoldText = new OsuSpriteText
|
||||
{
|
||||
AlwaysPresent = true, // ensures that the menu item does not change width when switching between normal and bold text.
|
||||
Alpha = 0,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -46,12 +46,11 @@ namespace osu.Game.Graphics.UserInterface
|
||||
|
||||
state = menuItem.State.GetBoundCopy();
|
||||
|
||||
Add(stateIcon = new SpriteIcon
|
||||
CheckboxContainer.Add(stateIcon = new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(10),
|
||||
Margin = new MarginPadding { Left = -MARGIN_HORIZONTAL, Right = MARGIN_HORIZONTAL },
|
||||
AlwaysPresent = true,
|
||||
});
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
Colour = BackgroundColourHover,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 2f,
|
||||
Width = 0.8f,
|
||||
Width = 0.9f,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,8 @@ namespace osu.Game.Graphics.UserInterface
|
||||
{
|
||||
public readonly MenuItemType Type;
|
||||
|
||||
public Hotkey Hotkey { get; init; }
|
||||
|
||||
public OsuMenuItem(LocalisableString text, MenuItemType type = MenuItemType.Standard)
|
||||
: this(text, type, null)
|
||||
{
|
||||
|
@ -92,6 +92,7 @@ namespace osu.Game.Screens.Edit.Components.Menus
|
||||
BackgroundColour = colourProvider.Background2;
|
||||
ForegroundColourHover = colourProvider.Content1;
|
||||
BackgroundColourHover = colourProvider.Background1;
|
||||
Text.CheckboxContainer.Alpha = 0;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
Loading…
Reference in New Issue
Block a user