Sentry turrets - Part 5: Reuseable UI components (#35149)

* Initial commit

* Updated how monotone buttons are styled

* Removed unnecessary textures

* Updated attributions

* Addressing reviewer comments

* Adjusted monotone checkbox styling
This commit is contained in:
chromiumboy
2025-05-03 12:19:08 -05:00
committed by GitHub
parent 885eb7bc35
commit f213753e2b
21 changed files with 496 additions and 0 deletions

View File

@@ -68,6 +68,10 @@ namespace Content.Client.Stylesheets
public const string StyleClassStorageButton = "storageButton";
public const string StyleClassInset = "Inset";
public const string StyleClassConsoleHeading = "ConsoleHeading";
public const string StyleClassConsoleSubHeading = "ConsoleSubHeading";
public const string StyleClassConsoleText = "ConsoleText";
public const string StyleClassSliderRed = "Red";
public const string StyleClassSliderGreen = "Green";
public const string StyleClassSliderBlue = "Blue";
@@ -180,6 +184,10 @@ namespace Content.Client.Stylesheets
var notoSansBold18 = resCache.NotoStack(variation: "Bold", size: 18);
var notoSansBold20 = resCache.NotoStack(variation: "Bold", size: 20);
var notoSansMono = resCache.GetFont("/EngineFonts/NotoSans/NotoSansMono-Regular.ttf", size: 12);
var robotoMonoBold11 = resCache.GetFont("/Fonts/RobotoMono/RobotoMono-Bold.ttf", size: 11);
var robotoMonoBold12 = resCache.GetFont("/Fonts/RobotoMono/RobotoMono-Bold.ttf", size: 12);
var robotoMonoBold14 = resCache.GetFont("/Fonts/RobotoMono/RobotoMono-Bold.ttf", size: 14);
var windowHeaderTex = resCache.GetTexture("/Textures/Interface/Nano/window_header.png");
var windowHeader = new StyleBoxTexture
{
@@ -414,9 +422,60 @@ namespace Content.Client.Stylesheets
};
progressBarForeground.SetContentMarginOverride(StyleBox.Margin.Vertical, 14.5f);
// Monotone (unfilled)
var monotoneButton = new StyleBoxTexture
{
Texture = resCache.GetTexture("/Textures/Interface/Nano/Monotone/monotone_button.svg.96dpi.png"),
};
monotoneButton.SetPatchMargin(StyleBox.Margin.All, 11);
monotoneButton.SetPadding(StyleBox.Margin.All, 1);
monotoneButton.SetContentMarginOverride(StyleBox.Margin.Vertical, 2);
monotoneButton.SetContentMarginOverride(StyleBox.Margin.Horizontal, 14);
var monotoneButtonOpenLeft = new StyleBoxTexture(monotoneButton)
{
Texture = resCache.GetTexture("/Textures/Interface/Nano/Monotone/monotone_button_open_left.svg.96dpi.png"),
};
var monotoneButtonOpenRight = new StyleBoxTexture(monotoneButton)
{
Texture = resCache.GetTexture("/Textures/Interface/Nano/Monotone/monotone_button_open_right.svg.96dpi.png"),
};
var monotoneButtonOpenBoth = new StyleBoxTexture(monotoneButton)
{
Texture = resCache.GetTexture("/Textures/Interface/Nano/Monotone/monotone_button_open_both.svg.96dpi.png"),
};
// Monotone (filled)
var monotoneFilledButton = new StyleBoxTexture(monotoneButton)
{
Texture = buttonTex,
};
var monotoneFilledButtonOpenLeft = new StyleBoxTexture(monotoneButton)
{
Texture = new AtlasTexture(buttonTex, UIBox2.FromDimensions(new Vector2(10, 0), new Vector2(14, 24))),
};
monotoneFilledButtonOpenLeft.SetPatchMargin(StyleBox.Margin.Left, 0);
var monotoneFilledButtonOpenRight = new StyleBoxTexture(monotoneButton)
{
Texture = new AtlasTexture(buttonTex, UIBox2.FromDimensions(new Vector2(0, 0), new Vector2(14, 24))),
};
monotoneFilledButtonOpenRight.SetPatchMargin(StyleBox.Margin.Right, 0);
var monotoneFilledButtonOpenBoth = new StyleBoxTexture(monotoneButton)
{
Texture = new AtlasTexture(buttonTex, UIBox2.FromDimensions(new Vector2(10, 0), new Vector2(3, 24))),
};
monotoneFilledButtonOpenBoth.SetPatchMargin(StyleBox.Margin.Horizontal, 0);
// CheckBox
var checkBoxTextureChecked = resCache.GetTexture("/Textures/Interface/Nano/checkbox_checked.svg.96dpi.png");
var checkBoxTextureUnchecked = resCache.GetTexture("/Textures/Interface/Nano/checkbox_unchecked.svg.96dpi.png");
var monotoneCheckBoxTextureChecked = resCache.GetTexture("/Textures/Interface/Nano/Monotone/monotone_checkbox_checked.svg.96dpi.png");
var monotoneCheckBoxTextureUnchecked = resCache.GetTexture("/Textures/Interface/Nano/Monotone/monotone_checkbox_unchecked.svg.96dpi.png");
// Tooltip box
var tooltipTexture = resCache.GetTexture("/Textures/Interface/Nano/tooltip.png");
@@ -946,6 +1005,17 @@ namespace Content.Client.Stylesheets
new StyleProperty(BoxContainer.StylePropertySeparation, 10),
}),
// MonotoneCheckBox
new StyleRule(new SelectorElement(typeof(TextureRect), new [] { MonotoneCheckBox.StyleClassMonotoneCheckBox }, null, null), new[]
{
new StyleProperty(TextureRect.StylePropertyTexture, monotoneCheckBoxTextureUnchecked),
}),
new StyleRule(new SelectorElement(typeof(TextureRect), new [] { MonotoneCheckBox.StyleClassMonotoneCheckBox, CheckBox.StyleClassCheckBoxChecked }, null, null), new[]
{
new StyleProperty(TextureRect.StylePropertyTexture, monotoneCheckBoxTextureChecked),
}),
// Tooltip
new StyleRule(new SelectorElement(typeof(Tooltip), null, null, null), new[]
{
@@ -1144,6 +1214,22 @@ namespace Content.Client.Stylesheets
new StyleProperty(Label.StylePropertyFontColor, Color.DarkGray),
}),
// Console text
new StyleRule(new SelectorElement(typeof(Label), new[] {StyleClassConsoleText}, null, null), new[]
{
new StyleProperty(Label.StylePropertyFont, robotoMonoBold11)
}),
new StyleRule(new SelectorElement(typeof(Label), new[] {StyleClassConsoleSubHeading}, null, null), new[]
{
new StyleProperty(Label.StylePropertyFont, robotoMonoBold12)
}),
new StyleRule(new SelectorElement(typeof(Label), new[] {StyleClassConsoleHeading}, null, null), new[]
{
new StyleProperty(Label.StylePropertyFont, robotoMonoBold14)
}),
// Big Button
new StyleRule(new SelectorChild(
new SelectorElement(typeof(Button), new[] {StyleClassButtonBig}, null, null),
@@ -1243,6 +1329,64 @@ namespace Content.Client.Stylesheets
new StyleProperty(Label.StylePropertyFont, notoSansDisplayBold14),
}),
// MonotoneButton (unfilled)
new StyleRule(
new SelectorElement(typeof(MonotoneButton), null, null, null),
new[]
{
new StyleProperty(Button.StylePropertyStyleBox, monotoneButton),
}),
new StyleRule(
new SelectorElement(typeof(MonotoneButton), new[] { ButtonOpenLeft }, null, null),
new[]
{
new StyleProperty(Button.StylePropertyStyleBox, monotoneButtonOpenLeft),
}),
new StyleRule(
new SelectorElement(typeof(MonotoneButton), new[] { ButtonOpenRight }, null, null),
new[]
{
new StyleProperty(Button.StylePropertyStyleBox, monotoneButtonOpenRight),
}),
new StyleRule(
new SelectorElement(typeof(MonotoneButton), new[] { ButtonOpenBoth }, null, null),
new[]
{
new StyleProperty(Button.StylePropertyStyleBox, monotoneButtonOpenBoth),
}),
// MonotoneButton (filled)
new StyleRule(
new SelectorElement(typeof(MonotoneButton), null, null, new[] { Button.StylePseudoClassPressed }),
new[]
{
new StyleProperty(Button.StylePropertyStyleBox, monotoneFilledButton),
}),
new StyleRule(
new SelectorElement(typeof(MonotoneButton), new[] { ButtonOpenLeft }, null, new[] { Button.StylePseudoClassPressed }),
new[]
{
new StyleProperty(Button.StylePropertyStyleBox, monotoneFilledButtonOpenLeft),
}),
new StyleRule(
new SelectorElement(typeof(MonotoneButton), new[] { ButtonOpenRight }, null, new[] { Button.StylePseudoClassPressed }),
new[]
{
new StyleProperty(Button.StylePropertyStyleBox, monotoneFilledButtonOpenRight),
}),
new StyleRule(
new SelectorElement(typeof(MonotoneButton), new[] { ButtonOpenBoth }, null, new[] { Button.StylePseudoClassPressed }),
new[]
{
new StyleProperty(Button.StylePropertyStyleBox, monotoneFilledButtonOpenBoth),
}),
// NanoHeading
new StyleRule(

View File

@@ -0,0 +1,79 @@
using JetBrains.Annotations;
using Robust.Client.UserInterface.Controls;
using static Robust.Client.UserInterface.Controls.Label;
namespace Content.Client.UserInterface.Controls;
/// <summary>
/// A button intended for use with a monotone color palette
/// </summary>
public sealed class MonotoneButton : ContainerButton
{
/// <summary>
/// Specifies the color of the label text when the button is pressed.
/// </summary>
[ViewVariables]
public Color AltTextColor { set; get; } = new Color(0.2f, 0.2f, 0.2f);
/// <summary>
/// The label that holds the button text.
/// </summary>
public Label Label { get; }
/// <summary>
/// The text displayed by the button.
/// </summary>
[PublicAPI, ViewVariables]
public string? Text { get => Label.Text; set => Label.Text = value; }
/// <summary>
/// How to align the text inside the button.
/// </summary>
[PublicAPI, ViewVariables]
public AlignMode TextAlign { get => Label.Align; set => Label.Align = value; }
/// <summary>
/// If true, the button will allow shrinking and clip text
/// to prevent the text from going outside the bounds of the button.
/// If false, the minimum size will always fit the contained text.
/// </summary>
[PublicAPI, ViewVariables]
public bool ClipText
{
get => Label.ClipText;
set => Label.ClipText = value;
}
public MonotoneButton()
{
Label = new Label
{
StyleClasses = { StyleClassButton }
};
AddChild(Label);
UpdateAppearance();
}
private void UpdateAppearance()
{
// Recolor the label
if (Label != null)
Label.ModulateSelfOverride = DrawMode == DrawModeEnum.Pressed ? AltTextColor : null;
// Modulate the button if disabled
Modulate = Disabled ? Color.Gray : Color.White;
}
protected override void StylePropertiesChanged()
{
base.StylePropertiesChanged();
UpdateAppearance();
}
protected override void DrawModeChanged()
{
base.DrawModeChanged();
UpdateAppearance();
}
}

View File

@@ -0,0 +1,24 @@
using Robust.Client.UserInterface.Controls;
namespace Content.Client.UserInterface.Controls;
/// <summary>
/// A check box intended for use with a monotone color palette
/// </summary>
public sealed class MonotoneCheckBox : CheckBox
{
public const string StyleClassMonotoneCheckBox = "monotoneCheckBox";
public MonotoneCheckBox()
{
TextureRect.AddStyleClass(StyleClassMonotoneCheckBox);
}
protected override void DrawModeChanged()
{
base.DrawModeChanged();
// Appearance modulations
Modulate = Disabled ? Color.Gray : Color.White;
}
}