Verb confirmation (#6137)

This commit is contained in:
ShadowCommander
2022-01-13 06:28:17 -08:00
committed by GitHub
parent 007caf26b7
commit 4f80dfda0d
8 changed files with 117 additions and 12 deletions

View File

@@ -18,6 +18,7 @@
Name="ExpansionIndicator"
HorizontalAlignment="Right"
Stretch="KeepCentered"
StyleClasses="contextMenuExpansionTexture"
TextureScale="0.5 0.5"
SetWidth="{x:Static ui:ContextMenuElement.ElementHeight}"
SetHeight="{x:Static ui:ContextMenuElement.ElementHeight}"

View File

@@ -18,6 +18,7 @@ namespace Content.Client.ContextMenu.UI
public partial class ContextMenuElement : ContainerButton
{
public const string StyleClassContextMenuButton = "contextMenuButton";
public const string StyleClassContextMenuExpansionTexture = "contextMenuExpansionTexture";
public const float ElementMargin = 2;
public const float ElementHeight = 32;
@@ -45,7 +46,7 @@ namespace Content.Client.ContextMenu.UI
/// <summary>
/// Convenience property to set label text.
/// </summary>
public string Text { set => Label.SetMessage(FormattedMessage.FromMarkupPermissive(value.Trim())); }
public virtual string Text { set => Label.SetMessage(FormattedMessage.FromMarkupPermissive(value.Trim())); }
public ContextMenuElement(string? text = null)
{
@@ -55,9 +56,6 @@ namespace Content.Client.ContextMenu.UI
if (text != null)
Text = text;
ExpansionIndicator.Texture = IoCManager.Resolve<IResourceCache>()
.GetTexture("/Textures/Interface/VerbIcons/group.svg.192dpi.png");
}
protected override void Dispose(bool disposing)
@@ -95,6 +93,7 @@ namespace Content.Client.ContextMenu.UI
if (_subMenu?.Visible ?? true)
return;
if (HasStylePseudoClass(StylePseudoClassHover))
RemoveStylePseudoClass(StylePseudoClassHover);
}
}

View File

@@ -446,6 +446,9 @@ namespace Content.Client.Stylesheets
};
insetBack.SetPatchMargin(StyleBox.Margin.All, 10);
var contextMenuExpansionTexture = resCache.GetTexture("/Textures/Interface/VerbIcons/group.svg.192dpi.png");
var verbMenuConfirmationTexture = resCache.GetTexture("/Textures/Interface/VerbIcons/group.svg.192dpi.png");
Stylesheet = new Stylesheet(BaseRules.Concat(new[]
{
// Window title.
@@ -623,6 +626,32 @@ namespace Content.Client.Stylesheets
Element<RichTextLabel>().Class(VerbMenuElement.StyleClassVerbOtherText)
.Prop(Label.StylePropertyFont, notoSans12),
Element<TextureRect>().Class(ContextMenuElement.StyleClassContextMenuExpansionTexture)
.Prop(TextureRect.StylePropertyTexture, contextMenuExpansionTexture),
Element<TextureRect>().Class(VerbMenuElement.StyleClassVerbMenuConfirmationTexture)
.Prop(TextureRect.StylePropertyTexture, verbMenuConfirmationTexture),
// Context menu confirm buttons
Element<ContextMenuElement>().Class(ConfirmationMenuElement.StyleClassConfirmationContextMenuButton)
.Prop(ContainerButton.StylePropertyStyleBox, buttonContext),
Element<ContextMenuElement>().Class(ConfirmationMenuElement.StyleClassConfirmationContextMenuButton)
.Pseudo(ContainerButton.StylePseudoClassNormal)
.Prop(Control.StylePropertyModulateSelf, ButtonColorCautionDefault),
Element<ContextMenuElement>().Class(ConfirmationMenuElement.StyleClassConfirmationContextMenuButton)
.Pseudo(ContainerButton.StylePseudoClassHover)
.Prop(Control.StylePropertyModulateSelf, ButtonColorCautionHovered),
Element<ContextMenuElement>().Class(ConfirmationMenuElement.StyleClassConfirmationContextMenuButton)
.Pseudo(ContainerButton.StylePseudoClassPressed)
.Prop(Control.StylePropertyModulateSelf, ButtonColorCautionPressed),
Element<ContextMenuElement>().Class(ConfirmationMenuElement.StyleClassConfirmationContextMenuButton)
.Pseudo(ContainerButton.StylePseudoClassDisabled)
.Prop(Control.StylePropertyModulateSelf, ButtonColorCautionDisabled),
// Thin buttons (No padding nor vertical margin)
Element<EntityContainerButton>().Class(StyleClassStorageButton)
.Prop(ContainerButton.StylePropertyStyleBox, buttonStorage),

View File

@@ -0,0 +1,34 @@
using Content.Client.ContextMenu.UI;
using Content.Shared.Verbs;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
namespace Content.Client.Verbs.UI;
public partial class ConfirmationMenuElement : ContextMenuElement
{
public const string StyleClassConfirmationContextMenuButton = "confirmationContextMenuButton";
public readonly Verb Verb;
public readonly VerbType Type;
public override string Text
{
set
{
var message = new FormattedMessage();
message.PushColor(Color.White);
message.AddMarkupPermissive(value.Trim());
Label.SetMessage(message);
}
}
public ConfirmationMenuElement(Verb verb, string? text, VerbType type) : base(text)
{
Verb = verb;
Type = type;
Icon.Visible = false;
SetOnlyStyleClass(StyleClassConfirmationContextMenuButton);
}
}

View File

@@ -16,6 +16,7 @@ namespace Content.Client.Verbs.UI
public const string StyleClassVerbActivationText = "ActivationVerb";
public const string StyleClassVerbAlternativeText = "AlternativeVerb";
public const string StyleClassVerbOtherText = "OtherVerb";
public const string StyleClassVerbMenuConfirmationTexture = "verbMenuConfirmationTexture";
public const float VerbTooltipDelay = 0.5f;
@@ -62,6 +63,12 @@ namespace Content.Client.Verbs.UI
TooltipDelay = VerbTooltipDelay;
Disabled = verb.Disabled;
Verb = verb;
if (verb.ConfirmationPopup)
{
ExpansionIndicator.SetOnlyStyleClass(StyleClassVerbMenuConfirmationTexture);
ExpansionIndicator.Visible = true;
}
}
public VerbMenuElement(VerbCategory category, VerbType verbType) : this(category.Text, category.Icon, verbType) { }

View File

@@ -170,33 +170,60 @@ namespace Content.Client.Verbs.UI
return;
if (element is not VerbMenuElement verbElement)
{
if (element is not ConfirmationMenuElement confElement)
return;
args.Handle();
ExecuteVerb(confElement.Verb, confElement.Type);
return;
}
args.Handle();
var verb = verbElement.Verb;
if (verb == null)
{
// The user probably clicked on a verb category.
// We will act as if they clicked on the first verb in that category.
// If there's only one verb in the category, then it will act as if they clicked on that verb.
// Otherwise it opens the category menu.
if (verbElement.SubMenu == null || verbElement.SubMenu.ChildCount == 0)
return;
if (verbElement.SubMenu.MenuBody.ChildCount != 1
|| verbElement.SubMenu.MenuBody.Children.First() is not VerbMenuElement verbCategoryElement)
|| verbElement.SubMenu.MenuBody.Children.First() is not VerbMenuElement verbMenuElement)
{
OpenSubMenu(verbElement);
return;
}
verb = verbCategoryElement.Verb;
verb = verbMenuElement.Verb;
if (verb == null)
return;
}
_verbSystem.ExecuteVerb(CurrentTarget, verb, verbElement.Type);
if (verb.ConfirmationPopup)
{
if (verbElement.SubMenu == null)
{
var popupElement = new ConfirmationMenuElement(verb, "Confirm", verbElement.Type);
verbElement.SubMenu = new ContextMenuPopup(this, verbElement);
AddElement(verbElement.SubMenu, popupElement);
}
OpenSubMenu(verbElement);
}
else
{
ExecuteVerb(verb, verbElement.Type);
}
}
private void ExecuteVerb(Verb verb, VerbType verbType)
{
_verbSystem.ExecuteVerb(CurrentTarget, verb, verbType);
if (verb.CloseMenu)
_verbSystem.CloseAllMenus();
}

View File

@@ -116,6 +116,7 @@ namespace Content.Server.Administration
}
};
verb.Impact = LogImpact.Extreme; // if you're just outright killing a person, I guess that deserves to be extreme?
verb.ConfirmationPopup = true;
args.Verbs.Add(verb);
}
}
@@ -136,6 +137,7 @@ namespace Content.Server.Administration
verb.IconTexture = "/Textures/Interface/VerbIcons/delete_transparent.svg.192dpi.png";
verb.Act = () => EntityManager.DeleteEntity(args.Target);
verb.Impact = LogImpact.Medium;
verb.ConfirmationPopup = true;
args.Verbs.Add(verb);
}
@@ -166,6 +168,7 @@ namespace Content.Server.Administration
player.ContentData()?.Mind?.TransferTo(args.Target, ghostCheckOverride: true);
};
verb.Impact = LogImpact.High;
verb.ConfirmationPopup = true;
args.Verbs.Add(verb);
}

View File

@@ -135,6 +135,11 @@ namespace Content.Shared.Verbs
/// </remarks>
public LogImpact Impact = LogImpact.Low;
/// <summary>
/// Whether this verb requires confirmation before being executed.
/// </summary>
public bool ConfirmationPopup = false;
/// <summary>
/// Compares two verbs based on their <see cref="Priority"/>, <see cref="Category"/>, <see cref="Text"/>,
/// and <see cref="IconTexture"/>.