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:
@@ -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(
|
||||
|
||||
79
Content.Client/UserInterface/Controls/MonotoneButton.cs
Normal file
79
Content.Client/UserInterface/Controls/MonotoneButton.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
24
Content.Client/UserInterface/Controls/MonotoneCheckBox.cs
Normal file
24
Content.Client/UserInterface/Controls/MonotoneCheckBox.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user