using Robust.Shared.Prototypes;
using System.Numerics;
using System.Linq;
+using Content.Client.Stylesheets;
namespace Content.Client.Access.UI
{
icons.Sort((x, y) => string.Compare(x.LocalizedJobName, y.LocalizedJobName, StringComparison.CurrentCulture));
foreach (var jobIcon in icons)
{
- String styleBase = StyleBase.ButtonOpenBoth;
+ String styleBase = StyleClass.ButtonOpenBoth;
var modulo = i % JobIconColumnCount;
if (modulo == 0)
- styleBase = StyleBase.ButtonOpenRight;
+ styleBase = StyleClass.ButtonOpenRight;
else if (modulo == JobIconColumnCount - 1)
- styleBase = StyleBase.ButtonOpenLeft;
+ styleBase = StyleClass.ButtonOpenLeft;
// Generate buttons
var jobIconButton = new Button
if (_groupedAccessLevels.Count > 1)
{
if (AccessGroupList.ChildCount == 0)
- accessGroupButton.AddStyleClass(StyleBase.ButtonOpenLeft);
+ accessGroupButton.AddStyleClass(StyleClass.ButtonOpenLeft);
else if (_groupedAccessLevels.Count > 1 && AccessGroupList.ChildCount == (_groupedAccessLevels.Count - 1))
- accessGroupButton.AddStyleClass(StyleBase.ButtonOpenRight);
+ accessGroupButton.AddStyleClass(StyleClass.ButtonOpenRight);
else
- accessGroupButton.AddStyleClass(StyleBase.ButtonOpenBoth);
+ accessGroupButton.AddStyleClass(StyleClass.ButtonOpenBoth);
}
accessGroupButton.Pressed = _accessGroupTabIndex == orderedAccessGroups.IndexOf(accessGroup);
public ActionAlertTooltip(FormattedMessage name, FormattedMessage? desc, string? requires = null)
{
+ Stylesheet = IoCManager.Resolve<IStylesheetManager>().SheetSystem;
_gameTiming = IoCManager.Resolve<IGameTiming>();
- SetOnlyStyleClass(StyleNano.StyleClassTooltipPanel);
+ SetOnlyStyleClass(StyleClass.TooltipPanel);
BoxContainer vbox;
AddChild(vbox = new BoxContainer
var nameLabel = new RichTextLabel
{
MaxWidth = TooltipTextMaxWidth,
- StyleClasses = {StyleNano.StyleClassTooltipActionTitle}
+ StyleClasses = { StyleClass.TooltipTitle }
};
nameLabel.SetMessage(name);
vbox.AddChild(nameLabel);
var description = new RichTextLabel
{
MaxWidth = TooltipTextMaxWidth,
- StyleClasses = {StyleNano.StyleClassTooltipActionDescription}
+ StyleClasses = { StyleClass.TooltipDesc }
};
description.SetMessage(desc);
vbox.AddChild(description);
vbox.AddChild(_cooldownLabel = new RichTextLabel
{
MaxWidth = TooltipTextMaxWidth,
- StyleClasses = {StyleNano.StyleClassTooltipActionCooldown},
+ StyleClasses = { StyleClass.TooltipDesc },
Visible = false
});
var requiresLabel = new RichTextLabel
{
MaxWidth = TooltipTextMaxWidth,
- StyleClasses = {StyleNano.StyleClassTooltipActionRequirements}
+ StyleClasses = { StyleClass.TooltipDesc }
};
if (!FormattedMessage.TryFromMarkup("[color=#635c5c]" + requires + "[/color]", out var markup))
</PanelContainer.PanelOverride>
<Control HorizontalAlignment="Center" VerticalAlignment="Center" MaxWidth="600">
- <PanelContainer StyleClasses="AngleRect" />
+ <PanelContainer StyleClasses="BackgroundPanel" />
<BoxContainer Orientation="Vertical" Margin="4">
<RichTextLabel Name="Description" />
[GenerateTypedNameReferences]
public sealed partial class AdminMessagePopupWindow : Control
{
+ [Dependency] private readonly IStylesheetManager _styleMan = default!;
+
private float _timer = float.MaxValue;
public event Action? OnDismissPressed;
-
public event Action? OnAcceptPressed;
public AdminMessagePopupWindow()
{
RobustXamlLoader.Load(this);
+ IoCManager.InjectDependencies(this);
- Stylesheet = IoCManager.Resolve<IStylesheetManager>().SheetSpace;
+ Stylesheet = _styleMan.SheetSystem;
AcceptButton.OnPressed += OnAcceptButtonPressed;
DismissButton.OnPressed += OnDismissButtonPressed;
MessageContainer.AddChild(new AdminMessagePopupMessage(message));
}
- Description.SetMessage(FormattedMessage.FromMarkupOrThrow(Loc.GetString("admin-notes-message-desc", ("count", state.Messages.Length))));
+ Description.SetMessage(
+ FormattedMessage.FromMarkup(Loc.GetString("admin-notes-message-desc", ("count", state.Messages.Length))));
}
private void OnDismissButtonPressed(BaseButton.ButtonEventArgs obj)
[Dependency] private readonly IClientAdminManager _adminManager = default!;
private readonly Menu _menu;
- private readonly List<DefaultWindow> _subWindows = new();
+ private readonly List<BaseWindow> _subWindows = new();
private Dictionary<int, PermissionsEuiState.AdminRankData> _ranks =
new();
var titleControl = new Label { Text = admin.Title ?? Loc.GetString("permissions-eui-edit-admin-title-control-text").ToLowerInvariant() };
if (admin.Title == null) // none
{
- titleControl.StyleClasses.Add(StyleBase.StyleClassItalic);
+ titleControl.StyleClasses.Add(StyleClass.Italic);
}
al.AddChild(titleControl);
var rankControl = new Label { Text = rank };
if (italic)
{
- rankControl.StyleClasses.Add(StyleBase.StyleClassItalic);
+ rankControl.StyleClasses.Add(StyleClass.Italic);
}
al.AddChild(rankControl);
tab.AddChild(adminVBox);
tab.AddChild(rankVBox);
- Contents.AddChild(tab);
+ ContentsContainer.AddChild(tab);
+ ContentsContainer.MinSize = new(600, 400);
}
-
- protected override Vector2 ContentsMinimumSize => new Vector2(600, 400);
}
private sealed class EditAdminWindow : DefaultWindow
var inherit = new Button
{
Text = "I",
- StyleClasses = { StyleBase.ButtonOpenRight },
+ StyleClasses = { StyleClass.ButtonOpenRight },
Disabled = disable,
Group = group,
};
var sub = new Button
{
Text = "-",
- StyleClasses = { StyleBase.ButtonOpenBoth },
+ StyleClasses = { StyleClass.ButtonOpenBoth },
Disabled = disable,
Group = group
};
var plus = new Button
{
Text = "+",
- StyleClasses = { StyleBase.ButtonOpenLeft },
+ StyleClasses = { StyleClass.ButtonOpenLeft },
Disabled = disable,
Group = group
};
bottomButtons.AddChild(SaveButton);
- Contents.AddChild(new BoxContainer
+ ContentsContainer.AddChild(new BoxContainer
{
Orientation = LayoutOrientation.Vertical,
Children =
bottomButtons.AddChild(SaveButton);
- Contents.AddChild(new BoxContainer
+ ContentsContainer.AddChild(new BoxContainer
{
Orientation = LayoutOrientation.Vertical,
Children =
VerticalExpand="True"
Margin="0 0 0 0"
VerticalAlignment="Center">
- <Label Text="{Loc 'anomaly-generator-fuel-display'}" StyleClasses="StatusFieldTitle" />
+ <Label Text="{Loc 'anomaly-generator-fuel-display'}" StyleClasses="highlight" />
<ProgressBar Name="FuelBar"
HorizontalExpand="True"
MaxValue="1"
Text="0 %" />
</ProgressBar>
</BoxContainer>
- <RichTextLabel Name="CooldownLabel" StyleClasses="StatusFieldTitle" />
- <RichTextLabel Name="ReadyLabel" StyleClasses="StatusFieldTitle" />
+ <RichTextLabel Name="CooldownLabel" StyleClasses="highlight" />
+ <RichTextLabel Name="ReadyLabel" StyleClasses="highlight" />
</BoxContainer>
<!--Sprite View-->
<PanelContainer Margin="12 0 0 0"
menuInnerPanel.AddChild(menuContainer);
#endregion
- Contents.AddChild(_mainPanel);
+ ContentsContainer.AddChild(_mainPanel);
CanKeyboardFocus = true;
}
newGame.OnPressed += _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.NewGame);
grid.AddChild(newGame);
- Contents.AddChild(grid);
+ ContentsContainer.AddChild(grid);
}
private void UpdateMetadata(SharedSpaceVillainArcadeComponent.SpaceVillainArcadeMetaDataUpdateMessage message)
using Content.Client.Atmos.Monitor.UI.Widgets;
using Content.Client.Message;
-using Content.Client.Stylesheets;
+using Content.Client.Stylesheets.Palette;
using Content.Client.UserInterface.Controls;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor;
public sealed partial class AirAlarmWindow : FancyWindow
{
public event Action<string, IAtmosDeviceData>? AtmosDeviceDataChanged;
- public event Action<IAtmosDeviceData>? AtmosDeviceDataCopied;
+ public event Action<IAtmosDeviceData>? AtmosDeviceDataCopied;
public event Action<string, AtmosMonitorThresholdType, AtmosAlarmThreshold, Gas?>? AtmosAlarmThresholdChanged;
public event Action<AirAlarmMode>? AirAlarmModeChanged;
public event Action<bool>? AutoModeChanged;
case GasVentPumpData pump:
if (!_pumps.TryGetValue(addr, out var pumpControl))
{
- var control= new PumpControl(pump, addr);
+ var control = new PumpControl(pump, addr);
control.PumpDataChanged += AtmosDeviceDataChanged;
control.PumpDataCopied += AtmosDeviceDataCopied;
_pumps.Add(addr, control);
{
return curAlarm switch
{
- AtmosAlarmType.Danger => StyleNano.DangerousRedFore,
- AtmosAlarmType.Warning => StyleNano.ConcerningOrangeFore,
- _ => StyleNano.GoodGreenFore,
+ AtmosAlarmType.Danger => Palettes.Status.Critical,
+ AtmosAlarmType.Warning => Palettes.Status.Warning,
+ _ => Palettes.Status.Good,
};
}
-
-
}
+using Content.Client.Stylesheets;
using Content.Shared.Atmos.Monitor;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
if (enabled)
{
- CBoundLabel.RemoveStyleClass("Disabled");
+ CBoundLabel.RemoveStyleClass(StyleClass.LabelWeak);
}
else
{
- CBoundLabel.SetOnlyStyleClass("Disabled");
+ CBoundLabel.SetOnlyStyleClass(StyleClass.LabelWeak);
}
}
MinSize="480 400" Title="Canister">
<BoxContainer Orientation="Vertical" Margin="5 5 5 5" SeparationOverride="10">
<BoxContainer Orientation="Vertical" VerticalExpand="True">
- <Label Text="{Loc comp-gas-canister-ui-canister-status}" FontColorOverride="{x:Static s:StyleNano.NanoGold}" StyleClasses="LabelBig"/>
+ <Label Text="{Loc comp-gas-canister-ui-canister-status}" StyleClasses="LabelHeading"/>
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc comp-gas-canister-ui-canister-pressure}"/>
<Label Name="CanisterPressureLabel" Align="Center" HorizontalExpand="True"/>
</BoxContainer>
<BoxContainer Orientation="Vertical" VerticalExpand="True">
- <Label Text="{Loc comp-gas-canister-ui-holding-tank-status}" FontColorOverride="{x:Static s:StyleNano.NanoGold}" StyleClasses="LabelBig"/>
+ <Label Text="{Loc comp-gas-canister-ui-holding-tank-status}" StyleClasses="LabelHeading"/>
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc comp-gas-canister-ui-holding-tank-label}"/>
<Label Name="TankLabelLabel" Text="{Loc comp-gas-canister-ui-holding-tank-label-empty}" Align="Center" HorizontalExpand="True"/>
</BoxContainer>
<BoxContainer Orientation="Vertical" VerticalExpand="True">
- <Label Text="{Loc comp-gas-canister-ui-release-valve-status}" FontColorOverride="{x:Static s:StyleNano.NanoGold}" StyleClasses="LabelBig"/>
+ <Label Text="{Loc comp-gas-canister-ui-release-valve-status}" StyleClasses="LabelHeading"/>
<BoxContainer Orientation="Horizontal">
<BoxContainer Orientation="Vertical">
<Label Text="{Loc comp-gas-canister-ui-release-pressure}"/>
Orientation="Vertical"
HorizontalExpand="True"
Margin="0 0 0 5">
- <PanelContainer>
- <PanelContainer.PanelOverride>
- <graphics:StyleBoxFlat BackgroundColor="{xNamespace:Static style:StyleNano.ButtonColorDisabled}" />
- </PanelContainer.PanelOverride>
+ <PanelContainer StyleClasses="PanelDark">
<Collapsible Name="Collapsible">
<CollapsibleHeading Name="Heading" MinHeight="35"/>
<CollapsibleBody Name="Body">
<PanelContainer
VerticalExpand="True"
HorizontalExpand="True"
- Margin="15">
- <PanelContainer.PanelOverride>
- <graphics:StyleBoxFlat BackgroundColor="{xNamespace:Static style:StyleNano.PanelDark}" />
- </PanelContainer.PanelOverride>
+ Margin="15"
+ StyleClasses="PanelDark">
<ScrollContainer VerticalExpand="True" HorizontalExpand="True">
<Control>
<Label Text="{Loc 'cryostorage-ui-label-no-bodies'}" Name="EmptyLabel" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<DefaultWindow
xmlns="https://spacestation14.io"
Title="{Loc 'ui-bql-results-title'}">
- <BoxContainer Orientation="Vertical">
+ <BoxContainer Orientation="Vertical" MinSize="500 700">
<Label Name="StatusLabel" />
<ScrollContainer VerticalExpand="True">
<BoxContainer Orientation="Vertical" Name="ItemList" VerticalExpand="True" />
RobustXamlLoader.Load(this);
}
- protected override Vector2 ContentsMinimumSize => new(500, 700);
-
public void Update((string name, NetEntity entity)[] entities)
{
StatusLabel.Text = _loc.GetString("ui-bql-results-status", ("count", entities.Length));
Margin="10 10 10 0"
HorizontalExpand="True"
Visible="True">
- <PanelContainer StyleClasses="AngleRect" HorizontalExpand="True">
+ <PanelContainer StyleClasses="BackgroundPanel" HorizontalExpand="True">
<BoxContainer Orientation="Vertical"
HorizontalExpand="True">
<BoxContainer Orientation="Horizontal">
if (_changelogManager.NewChangelogEntries)
{
Text = Loc.GetString("changelog-button-new-entries");
- StyleClasses.Add(StyleBase.ButtonCaution);
+ StyleClasses.Add(StyleClass.Negative);
}
else
{
Text = Loc.GetString("changelog-button");
- StyleClasses.Remove(StyleBase.ButtonCaution);
+ StyleClasses.Remove(StyleClass.Negative);
}
}
}
ChangelogBody.AddChild(new Label
{
Text = dayNice,
- StyleClasses = { StyleBase.StyleClassLabelHeading },
+ StyleClasses = { StyleClass.LabelHeading },
Margin = new Thickness(4, 6, 0, 0)
});
};
readDivider.AddChild(hBox);
- readDivider.AddChild(new PanelContainer { StyleClasses = { StyleBase.ClassLowDivider } });
+ readDivider.AddChild(new PanelContainer { StyleClasses = { StyleClass.LowDivider } });
ChangelogBody.AddChild(readDivider);
if (first)
xmlns:ui="clr-namespace:Content.Client.Changelog"
Title="{Loc 'changelog-window-title'}"
MinSize="500 400"
- SetSize="500 400">
- <PanelContainer StyleClasses="AngleRect" />
+ SetSize="500 400"
+ Stylesheet="Interface">
+ <PanelContainer StyleClasses="BackgroundPanel" />
<BoxContainer Orientation="Vertical">
<TabContainer Name="Tabs" Access="Public" HorizontalExpand="True" VerticalExpand="True" />
<PanelContainer StyleClasses="LowDivider" />
public ChangelogWindow()
{
RobustXamlLoader.Load(this);
- WindowTitle.AddStyleClass(StyleBase.StyleClassLabelHeading);
- Stylesheet = IoCManager.Resolve<IStylesheetManager>().SheetSpace;
+ WindowTitle.AddStyleClass(StyleClass.LabelHeading);
}
protected override void Opened()
<Label Text="{Loc 'chem-master-window-packaging-text'}" />
<Control HorizontalExpand="True"/>
<Label Text="{Loc 'chem-master-window-buffer-label'}" />
- <Label Name="BufferCurrentVolume" StyleClasses="LabelSecondaryColor" />
+ <Label Name="BufferCurrentVolume" StyleClasses="LabelWeak" />
</BoxContainer>
<!-- Wrap the packaging info-->
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'chem-master-window-pills-label'}" />
<Control HorizontalExpand="True" MinSize="50 0" />
- <Label Text="{Loc 'chem-master-window-pills-number-label'}" Margin="5 0 0 0" StyleClasses="LabelSecondaryColor" />
+ <Label Text="{Loc 'chem-master-window-pills-number-label'}" Margin="5 0 0 0" StyleClasses="LabelWeak" />
<SpinBox MinSize="100 0" Name="PillNumber" Access="Public" Value="0" />
- <Label Text="{Loc 'chem-master-window-dose-label'}" Margin="5 0 0 0" StyleClasses="LabelSecondaryColor" />
+ <Label Text="{Loc 'chem-master-window-dose-label'}" Margin="5 0 0 0" StyleClasses="LabelWeak" />
<SpinBox MinSize="100 0" Name="PillDosage" Access="Public" Value="1" />
<Button MinSize="80 0" Name="CreatePillButton" Access="Public" Text="{Loc 'chem-master-window-create-button'}" />
</BoxContainer>
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'chem-master-window-bottles-label'}" />
<Control HorizontalExpand="True" MinSize="50 0" />
- <Label Text="{Loc 'chem-master-window-dose-label'}" Margin="5 0 0 0" StyleClasses="LabelSecondaryColor" />
+ <Label Text="{Loc 'chem-master-window-dose-label'}" Margin="5 0 0 0" StyleClasses="LabelWeak" />
<SpinBox MinSize="100 0" Name="BottleDosage" Access="Public" Value="0" />
<Button MinSize="80 0" Name="CreateBottleButton" Access="Public" Text="{Loc 'chem-master-window-create-button'}" />
</BoxContainer>
{
// For every button decide which stylebase to have
// Every row has 10 buttons
- String styleBase = StyleBase.ButtonOpenBoth;
+ String styleBase = StyleClass.ButtonOpenBoth;
uint modulo = i % 10;
if (i > 0 && modulo == 0)
- styleBase = StyleBase.ButtonOpenRight;
+ styleBase = StyleClass.ButtonOpenRight;
else if (i > 0 && modulo == 9)
- styleBase = StyleBase.ButtonOpenLeft;
+ styleBase = StyleClass.ButtonOpenLeft;
else if (i == 0)
- styleBase = StyleBase.ButtonOpenRight;
+ styleBase = StyleClass.ButtonOpenRight;
// Generate buttons
PillTypeButtons[i] = new Button
var buttonConfigs = new (string text, ChemMasterReagentAmount amount, string styleClass)[]
{
- ("1", ChemMasterReagentAmount.U1, StyleBase.ButtonOpenBoth),
- ("5", ChemMasterReagentAmount.U5, StyleBase.ButtonOpenBoth),
- ("10", ChemMasterReagentAmount.U10, StyleBase.ButtonOpenBoth),
- ("15", ChemMasterReagentAmount.U15, StyleBase.ButtonOpenBoth),
- ("20", ChemMasterReagentAmount.U20, StyleBase.ButtonOpenBoth),
- ("25", ChemMasterReagentAmount.U25, StyleBase.ButtonOpenBoth),
- ("30", ChemMasterReagentAmount.U30, StyleBase.ButtonOpenBoth),
- ("50", ChemMasterReagentAmount.U50, StyleBase.ButtonOpenBoth),
- ("100", ChemMasterReagentAmount.U100, StyleBase.ButtonOpenBoth),
- (Loc.GetString("chem-master-window-buffer-all-amount"), ChemMasterReagentAmount.All, StyleBase.ButtonOpenLeft),
+ ("1", ChemMasterReagentAmount.U1, StyleClass.ButtonOpenBoth),
+ ("5", ChemMasterReagentAmount.U5, StyleClass.ButtonOpenBoth),
+ ("10", ChemMasterReagentAmount.U10, StyleClass.ButtonOpenBoth),
+ ("15", ChemMasterReagentAmount.U15, StyleClass.ButtonOpenBoth),
+ ("20", ChemMasterReagentAmount.U20, StyleClass.ButtonOpenBoth),
+ ("25", ChemMasterReagentAmount.U25, StyleClass.ButtonOpenBoth),
+ ("30", ChemMasterReagentAmount.U30, StyleClass.ButtonOpenBoth),
+ ("50", ChemMasterReagentAmount.U50, StyleClass.ButtonOpenBoth),
+ ("100", ChemMasterReagentAmount.U100, StyleClass.ButtonOpenBoth),
+ (Loc.GetString("chem-master-window-buffer-all-amount"), ChemMasterReagentAmount.All, StyleClass.ButtonOpenLeft),
};
var buttons = new List<ReagentButton>();
var bufferVol = new Label
{
Text = $"{state.BufferCurrentVolume}u",
- StyleClasses = { StyleNano.StyleClassLabelSecondaryColor }
+ StyleClasses = { StyleClass.LabelWeak }
};
bufferHBox.AddChild(bufferVol);
new Label
{
Text = $"{info.CurrentVolume}/{info.MaxVolume}",
- StyleClasses = { StyleNano.StyleClassLabelSecondaryColor }
+ StyleClasses = { StyleClass.LabelWeak }
}
}
});
new Label
{
Text = $"{quantity}u",
- StyleClasses = { StyleNano.StyleClassLabelSecondaryColor }
+ StyleClasses = { StyleClass.LabelWeak }
},
// Padding
{
_parent = parent;
_solutionContainers = solutionContainers;
- _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
+ _label = new RichTextLabel { StyleClasses = { StyleClass.ItemStatus } };
AddChild(_label);
}
{
_parent = parent;
_solutionContainers = solutionContainers;
- _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
+ _label = new RichTextLabel { StyleClasses = { StyleClass.ItemStatus } };
AddChild(_label);
}
var quantityLabel = new Label
{
Text = Loc.GetString("reagent-dispenser-window-quantity-label-text", ("quantity", quantity)),
- StyleClasses = { StyleNano.StyleClassLabelSecondaryColor },
+ StyleClasses = { StyleClass.LabelWeak },
};
ContainerInfo.Children.Add(new BoxContainer
_parent = parent;
_entityManager = entityManager;
_solutionContainers = solutionContainers;
- _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
+ _label = new RichTextLabel { StyleClasses = { StyleClass.ItemStatus } };
AddChild(_label);
}
Title = Loc.GetString("accept-cloning-window-title");
- Contents.AddChild(new BoxContainer
+ ContentsContainer.AddChild(new BoxContainer
{
Orientation = LayoutOrientation.Vertical,
Children =
MinSize = new Vector2(48, 48),
HorizontalExpand = true,
Group = group,
- StyleClasses = {StyleBase.ButtonSquare},
+ StyleClasses = {StyleClass.ButtonSquare},
ToggleMode = true,
Pressed = _selectedId == id,
ToolTip = proto.Name
outerColumn.AddChild(Column);
baseContainer.AddChild(outerColumn);
baseContainer.AddChild(confirmButton);
- Contents.AddChild(baseContainer);
+ ContentsContainer.AddChild(baseContainer);
}
private void OnConfirm(ButtonEventArgs args)
Name="IconLabel"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
- StyleClasses="contextMenuIconLabel"
+ StyleClasses="LabelSubText"
+ Align="Right"
Visible="false"/>
</SpriteView>
<RichTextLabel
{
public const string StyleClassContextMenuButton = "contextMenuButton";
public const string StyleClassContextMenuExpansionTexture = "contextMenuExpansionTexture";
- public const string StyleClassEntityMenuIconLabel = "contextMenuIconLabel";
public const float ElementMargin = 2;
public const float ElementHeight = 32;
_crayon = crayon;
_charges = charges;
_capacity = entityManage.GetComponent<LimitedChargesComponent>(_crayon.Owner).MaxCharges;
- _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
+ _label = new RichTextLabel { StyleClasses = { StyleClass.ItemStatus } };
AddChild(_label);
}
private void ButtonOnPressed(ButtonEventArgs obj)
{
- if (obj.Button.Name == null) return;
+ if (obj.Button.Name == null)
+ return;
_selected = obj.Button.Name;
_autoSelected = null;
foreach (var entry in CreditsManager.GetLicenses(_resourceManager).OrderBy(p => p.Name))
{
licensesContainer.AddChild(new Label
- { StyleClasses = { StyleBase.StyleClassLabelHeading }, Text = entry.Name });
+ { StyleClasses = { StyleClass.LabelHeading }, Text = entry.Name });
// We split these line by line because otherwise
// the LGPL causes Clyde to go out of bounds in the rendering code.
first = false;
patronsContainer.AddChild(new Label
- { StyleClasses = { StyleBase.StyleClassLabelHeading }, Text = $"{tier.Key}" });
+ { StyleClasses = { StyleClass.LabelHeading }, Text = $"{tier.Key}" });
var msg = string.Join(", ", tier.OrderBy(p => p.Name).Select(p => p.Name));
first = false;
ss14ContributorsContainer.AddChild(new Label
- { StyleClasses = { StyleBase.StyleClassLabelHeading }, Text = title });
+ { StyleClasses = { StyleClass.LabelHeading }, Text = title });
var label = new RichTextLabel();
var text = _resourceManager.ContentFileReadAllText($"/Credits/{path}");
{
var panelContainer = new PanelContainer
{
- PanelOverride = new StyleBoxFlat
- {
- BackgroundColor = StyleNano.ButtonColorDefault
- },
Children =
{
button
}
};
+ panelContainer.SetOnlyStyleClass(StyleClass.PanelLight);
Grid.AddChild(panelContainer);
}
else
_parent = parent;
_entMan = IoCManager.Resolve<IEntityManager>();
_transform = _entMan.System<TransformSystem>();
- _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
+ _label = new RichTextLabel { StyleClasses = { StyleClass.ItemStatus } };
AddChild(_label);
UpdateGpsDetails();
}
if (Pressable())
{
- openButton.AddStyleClass(StyleBase.ButtonCaution);
+ openButton.AddStyleClass(StyleClass.Negative);
}
var buttonContainer = new BoxContainer()
{
Title = Loc.GetString("ghost-return-to-body-title");
- Contents.AddChild(new BoxContainer
+ ContentsContainer.AddChild(new BoxContainer
{
Orientation = LayoutOrientation.Vertical,
Children =
var button = new Button
{
HorizontalExpand = true,
- StyleClasses = {StyleBase.ButtonSquare},
+ StyleClasses = {StyleClass.ButtonSquare},
ToolTip = Loc.GetString(name),
Text = Loc.GetString(name),
Margin = new Thickness(0, 0, 15, 0),
{
IoCManager.InjectDependencies(this);
_parent = parent;
- _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
+ _label = new RichTextLabel { StyleClasses = { StyleClass.ItemStatus } };
_label.MaxWidth = 350;
AddChild(new ClipControl { Children = { _label } });
PopulateTutorial(tutorialList);
- Contents.AddChild(rootContainer);
+ ContentsContainer.AddChild(rootContainer);
SetSize = new Vector2(650, 650);
}
Text="{Loc 'ui-rules-accept'}"
Disabled="True" />
<Button Name="QuitButton"
- StyleClasses="Caution"
+ StyleClasses="negative"
Text="{Loc 'ui-escape-quit'}" />
</BoxContainer>
</BoxContainer>
var button = new Button()
{
Text = Loc.GetString("strippable-bound-user-interface-stripping-menu-ensnare-button"),
- StyleClasses = { StyleBase.ButtonOpenRight }
+ StyleClasses = { StyleClass.ButtonOpenRight }
};
button.OnPressed += (_) => SendPredictedMessage(new StrippingEnsnareButtonPressed());
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
- xmlns:style="clr-namespace:Content.Client.Stylesheets"
Title="{Loc 'microwave-menu-title'}"
MinWidth="512"
MinSize="512 256">
Name="StartButton"
Access="Public"
Text="{Loc 'microwave-menu-start-button'}"
- StyleClasses="ButtonColorGreen"
+ StyleClasses="positive"
TextAlign="Center" />
<Button
Name="EjectButton"
Access="Public"
Text="{Loc 'microwave-menu-eject-all-text'}"
ToolTip="{Loc 'microwave-menu-eject-all-tooltip'}"
- StyleClasses="ButtonColorRed"
+ StyleClasses="negative"
TextAlign="Center" />
</BoxContainer>
</BoxContainer>
VerticalExpand = true,
};
- Contents.AddChild(_base);
+ ContentsContainer.AddChild(_base);
_jobRequirements.Updated += RebuildUI;
RebuildUI();
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls">
<parallax:ParallaxControl SpeedX="20"/>
<Control HorizontalAlignment="Center" VerticalAlignment="Center">
- <PanelContainer StyleClasses="AngleRect" />
+ <PanelContainer StyleClasses="BackgroundPanel" />
<BoxContainer Orientation="Vertical" MinSize="300 200">
<BoxContainer Orientation="Horizontal">
<Label Margin="8 0 0 0" Text="{Loc 'connecting-title'}"
</BoxContainer>
</Control>
<!-- Bottom window for tips -->
- <PanelContainer Name="LoginTips" StyleClasses="AngleRect" Margin="0 10" MaxWidth="600" VerticalExpand="True" VerticalAlignment="Bottom">
+ <PanelContainer Name="LoginTips" StyleClasses="BackgroundPanel" Margin="0 10" MaxWidth="600" VerticalExpand="True" VerticalAlignment="Bottom">
<BoxContainer Orientation="Vertical" VerticalExpand="True">
<controls:StripeBack>
<BoxContainer Orientation="Horizontal" HorizontalAlignment="Center">
LayoutContainer.SetAnchorPreset(this, LayoutContainer.LayoutPreset.Wide);
- Stylesheet = IoCManager.Resolve<IStylesheetManager>().SheetSpace;
+ Stylesheet = IoCManager.Resolve<IStylesheetManager>().SheetSystem;
ChangeLoginTip();
RetryButton.OnPressed += ReconnectButtonPressed;
<Button Name="ConfirmDeleteButton"
Text="{Loc 'character-setup-gui-character-picker-button-confirm-delete-button'}"
Visible="False"
- ModulateSelfOverride="{x:Static style:StyleNano.ButtonColorCautionDefault}"/>
+ StyleClasses="negative"/>
</BoxContainer>
</ContainerButton>
Text="{Loc 'character-setup-gui-character-setup-close-button'}"
StyleClasses="ButtonBig"/>
</BoxContainer>
- <PanelContainer>
- <PanelContainer.PanelOverride>
- <gfx:StyleBoxFlat BackgroundColor="{x:Static style:StyleNano.NanoGold}" ContentMarginTopOverride="2" />
- </PanelContainer.PanelOverride>
+ <PanelContainer StyleClasses="highlight">
</PanelContainer>
<BoxContainer Orientation="Horizontal" VerticalExpand="True" SeparationOverride="0">
<ScrollContainer MinSize="325 0" Margin="5 5 0 0">
<BoxContainer Name="Characters" Orientation="Vertical" />
</ScrollContainer>
- <PanelContainer MinSize="2 0">
- <PanelContainer.PanelOverride>
- <gfx:StyleBoxFlat BackgroundColor="{x:Static style:StyleNano.NanoGold}" ContentMarginTopOverride="2" />
- </PanelContainer.PanelOverride>
+ <PanelContainer MinSize="2 0" StyleClasses="highlight">
</PanelContainer>
<BoxContainer Name="CharEditor" HorizontalExpand="True" />
</BoxContainer>
using Content.Client.Lobby.UI.Roles;
using Content.Client.Message;
using Content.Client.Players.PlayTimeTracking;
-using Content.Client.Sprite;
using Content.Client.Stylesheets;
+using Content.Client.Sprite;
using Content.Client.UserInterface.Systems.Guidebook;
using Content.Shared.CCVar;
using Content.Shared.Clothing;
{
Text = Loc.GetString(category.Name),
Margin = new Thickness(0, 10, 0, 0),
- StyleClasses = { StyleBase.StyleClassLabelHeading },
+ StyleClasses = { StyleClass.LabelHeading },
});
}
return;
const string style = "SpeciesInfoDefault";
- SpeciesInfoButton.StyleClasses.Add(style);
+ SpeciesInfoButton.StyleIdentifier = style;
}
private void UpdateMarkings()
--- /dev/null
+using Content.Client.Resources;
+using Content.Client.Stylesheets;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Lobby.UI;
+
+[CommonSheetlet]
+public sealed class HumanoidProfileEditorSheetlet : Sheetlet<PalettedStylesheet>
+{
+ public override StyleRule[] GetRules(PalettedStylesheet sheet, object config)
+ {
+ return
+ [
+ E<TextureButton>()
+ .Identifier("SpeciesInfoDefault")
+ .Prop(TextureButton.StylePropertyTexture,
+ ResCache.GetTexture("/Textures/Interface/VerbIcons/information.svg.192dpi.png")),
+ // copied from `StyleNano`, but this is unused
+ // E<TextureButton>()
+ // .Identifier("SpeciesInfoWarning")
+ // .Prop(TextureButton.StylePropertyTexture,
+ // ResCache.GetTexture("/Textures/Interface/info.svg.192dpi.png"))
+ // .Prop(Control.StylePropertyModulateSelf, sheet.HighlightPalette[0]),
+ ];
+ }
+}
<BoxContainer xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Orientation="Vertical">
- <PanelContainer StyleClasses="AngleRect" HorizontalExpand="True" Margin="5">
+ <PanelContainer StyleClasses="BackgroundPanel" HorizontalExpand="True" Margin="5">
<BoxContainer Name="LoadoutsContainer" Orientation="Vertical" VerticalExpand="True" HorizontalExpand="True"/>
</PanelContainer>
<!-- Buffer space so we have 10 margin between controls but also 10 to the borders -->
<Control Name="DefaultState" VerticalExpand="True">
<BoxContainer Name="TopLeft" Orientation="Vertical">
<!-- Left Top Panel -->
- <PanelContainer StyleClasses="AngleRect" HorizontalAlignment="Left" Name="LeftSideTop"
+ <PanelContainer StyleClasses="BackgroundPanel" HorizontalAlignment="Left" Name="LeftSideTop"
VerticalAlignment="Top">
<BoxContainer Orientation="Vertical" HorizontalAlignment="Center" MaxWidth="800">
<info:LinkBanner Name="LinkBanner" VerticalExpand="false" HorizontalAlignment="Center"
<!-- Left Bot Panel -->
<BoxContainer Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Bottom">
<info:DevInfoBanner Name="DevInfoBanner" VerticalExpand="false" Margin="3 3 3 3" />
- <PanelContainer StyleClasses="AngleRect">
+ <PanelContainer StyleClasses="BackgroundPanel">
<RichTextLabel Name="LobbySong" Access="Public" HorizontalAlignment="Center" />
</PanelContainer>
</BoxContainer>
<Control Access="Public" Visible="False" Name="CharacterSetupState" VerticalExpand="True" />
</BoxContainer>
<!-- Right Panel -->
- <PanelContainer Name="RightSide" Access="Public" StyleClasses="AngleRect" HorizontalAlignment="Right" VerticalExpand="True"
+ <PanelContainer Name="RightSide" Access="Public" StyleClasses="BackgroundPanel" HorizontalAlignment="Right" VerticalExpand="True"
VerticalAlignment="Stretch">
<BoxContainer Orientation="Vertical" HorizontalExpand="True">
<!-- Top row -->
HorizontalExpand="True" HorizontalAlignment="Center" />
</BoxContainer>
<!-- Gold line -->
- <controls:HLine Color="{x:Static style:StyleNano.NanoGold}" Thickness="2" />
+ <controls:HLine StyleClasses="highlight" Thickness="2" />
<controls:HSpacer Spacing="10" />
<!-- Voting & misc button bar -->
<BoxContainer Orientation="Horizontal" MinSize="0 40" HorizontalAlignment="Right">
<controls:HSpacer Spacing="5" />
<BoxContainer MinHeight="10" />
<!-- Gold line -->
- <controls:HLine Color="{x:Static style:StyleNano.NanoGold}" Thickness="2" Access="Public" />
+ <controls:HLine StyleClasses="highlight" Thickness="2" Access="Public" />
<controls:HSpacer Spacing="10" />
<widgets:ChatBox Name="Chat" Access="Public" VerticalExpand="True" Margin="3 3 3 3" MinHeight="50" />
</BoxContainer>
</PanelContainer>
</SplitContainer>
<PanelContainer Name="ExpandPanel"
- StyleClasses="AngleRect"
+ StyleClasses="BackgroundPanel"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Margin="0 2 2 0"
<BoxContainer Orientation="Horizontal">
<Button Name="NevermindButton" Text="{Loc 'observe-nevermind'}" SizeFlagsStretchRatio="1"/>
<Control HorizontalExpand="True" SizeFlagsStretchRatio="2" />
- <cc:CommandButton Command="observe" Name="ObserveButton" StyleClasses="Caution" Text="{Loc 'observe-confirm'}" SizeFlagsStretchRatio="1"/>
+ <cc:CommandButton Command="observe" Name="ObserveButton" StyleClasses="negative" Text="{Loc 'observe-confirm'}" SizeFlagsStretchRatio="1"/>
<cc:CommandButton Command="observe admin" Name="ObserveAsAdminButton" Text="{Loc 'observe-as-admin'}" SizeFlagsStretchRatio="1" Visible="False"/>
</BoxContainer>
</BoxContainer>
RobustXamlLoader.Load(this);
_options = new RadioOptions<int>(RadioOptionsLayout.Horizontal)
{
- FirstButtonStyle = StyleBase.ButtonOpenRight,
- ButtonStyle = StyleBase.ButtonOpenBoth,
- LastButtonStyle = StyleBase.ButtonOpenLeft,
+ FirstButtonStyle = StyleClass.ButtonOpenRight,
+ ButtonStyle = StyleClass.ButtonOpenBoth,
+ LastButtonStyle = StyleClass.ButtonOpenLeft,
HorizontalExpand = true,
};
//Override default radio option button width
Text = Loc.GetString("role-timer-locked"),
Visible = true,
HorizontalAlignment = HAlignment.Center,
- StyleClasses = {StyleBase.StyleClassLabelSubText},
+ StyleClasses = {StyleClass.LabelSubText},
};
_lockStripe = new StripeBack()
[GenerateTypedNameReferences]
public sealed partial class MainMenuControl : Control
{
+ public const string StyleIdentifierMainMenu = "mainMenu";
+ public const string StyleIdentifierMainMenuVBox = "mainMenuVBox";
+
public MainMenuControl(IResourceCache resCache, IConfigurationManager configMan)
{
RobustXamlLoader.Load(this);
--- /dev/null
+using Content.Client.Stylesheets;
+using Content.Client.Stylesheets.Fonts;
+using Content.Client.Stylesheets.Stylesheets;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.MainMenu.UI;
+
+[CommonSheetlet]
+public sealed class MainMenuSheetlet : Sheetlet<NanotrasenStylesheet>
+{
+ public override StyleRule[] GetRules(NanotrasenStylesheet sheet, object config)
+ {
+ return
+ [
+ // make those buttons bigger
+ E<Button>()
+ .Identifier(MainMenuControl.StyleIdentifierMainMenu)
+ .ParentOf(E<Label>())
+ .Font(sheet.BaseFont.GetFont(16, FontKind.Bold)),
+ E<BoxContainer>()
+ .Identifier(MainMenuControl.StyleIdentifierMainMenuVBox)
+ .Prop(BoxContainer.StylePropertySeparation, 2),
+ ];
+ }
+}
<Control xmlns="https://spacestation14.io"
xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
MouseFilter="Stop">
- <PanelContainer StyleClasses="BackgroundOpenLeft"/>
+ <PanelContainer StyleClasses="BackgroundPanelOpenLeft"/>
<PanelContainer>
<PanelContainer.PanelOverride>
<graphics:StyleBoxFlat BorderColor="#25252A" BorderThickness="0 0 0 3"/>
<Label Text="{Loc news-write-ui-article-name-label}" Margin="17 10 0 9" VerticalAlignment="Center"/>
<LineEdit Name="TitleField" Margin="6 10 0 9" MinWidth="260" MinHeight="23" Access="Public"/>
<Control HorizontalExpand="True" />
- <Label Name="RichTextInfoLabel" Text="?" MouseFilter="Pass" Margin="14 0" StyleClasses="LabelSecondaryColor"/>
+ <Label Name="RichTextInfoLabel" Text="?" MouseFilter="Pass" Margin="14 0" StyleClasses="LabelWeak"/>
</BoxContainer>
<Control Name="TextEditPanel" VerticalExpand="True" Margin="11 0 11 0">
<PanelContainer>
<BoxContainer Orientation="Horizontal" Margin="12 5 12 8">
<Control>
<Button Name="ButtonCancel" SetHeight="32" SetWidth="85"
- StyleClasses="ButtonColorRed" Text="{Loc news-write-ui-cancel-text}"/>
+ StyleClasses="negative" Text="{Loc news-write-ui-cancel-text}"/>
</Control>
<Control HorizontalExpand="True"/>
<BoxContainer Orientation="Horizontal">
{
RobustXamlLoader.Load(this);
- ButtonPublish.StyleClasses.Add(StyleBase.ButtonOpenLeft);
- ButtonPublish.StyleClasses.Add(StyleNano.StyleClassButtonColorGreen);
+ ButtonPublish.StyleClasses.Add(StyleClass.ButtonOpenLeft);
+ ButtonPublish.StyleClasses.Add(StyleClass.Positive);
ContentField.GetChild(0).Margin = new Thickness(9, 3);
// Customize scrollbar width and margin. This is not possible in xaml
xmlns:system="clr-namespace:System;assembly=System.Runtime"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Margin="0 0 0 8">
- <PanelContainer StyleClasses="AngleRect" ModulateSelfOverride="#2b2b31"/>
+ <PanelContainer StyleClasses="BackgroundPanel" ModulateSelfOverride="#2b2b31"/>
<BoxContainer Orientation="Vertical" SetHeight="60">
<Control HorizontalExpand="True" SetHeight="27">
<PanelContainer>
HorizontalAlignment="Right" Margin="8 6 6 6" SetHeight="19" SetWidth="52" Access="Public">
<Button.StyleClasses>
<system:String>ButtonSmall</system:String>
- <system:String>ButtonColorRed</system:String>
+ <system:String>negative</system:String>
</Button.StyleClasses>
</controls:ConfirmButton>
</BoxContainer>
{
var sheetsToEject = sheetsToEjectArray[i];
- var styleClass = StyleBase.ButtonOpenBoth;
+ var styleClass = StyleClass.ButtonOpenBoth;
if (i == 0)
- styleClass = StyleBase.ButtonOpenRight;
+ styleClass = StyleClass.ButtonOpenRight;
else if (i == sheetsToEjectArray.Length - 1)
- styleClass = StyleBase.ButtonOpenLeft;
+ styleClass = StyleClass.ButtonOpenLeft;
var button = new Button
{
};
deparmentLabel.SetMessage(department);
- deparmentLabel.StyleClasses.Add(StyleNano.StyleClassTooltipActionDescription);
+ deparmentLabel.StyleClasses.Add("font-large");
SensorsTable.AddChild(deparmentLabel);
};
deparmentLabel.SetMessage(Loc.GetString("crew-monitoring-ui-no-department-label"));
- deparmentLabel.StyleClasses.Add(StyleNano.StyleClassTooltipActionDescription);
SensorsTable.AddChild(deparmentLabel);
};
if (sensor.SuitSensorUid == _trackedEntity)
- sensorButton.AddStyleClass(StyleNano.StyleClassButtonColorGreen);
+ sensorButton.AddStyleClass(StyleClass.Positive);
SensorsTable.AddChild(sensorButton);
var castSensor = (CrewMonitoringButton) sensor;
if (castSensor.SuitSensorUid == prevTrackedEntity)
- castSensor.RemoveStyleClass(StyleNano.StyleClassButtonColorGreen);
+ castSensor.RemoveStyleClass(StyleClass.Positive);
else if (castSensor.SuitSensorUid == currTrackedEntity)
- castSensor.AddStyleClass(StyleNano.StyleClassButtonColorGreen);
+ castSensor.AddStyleClass(StyleClass.Positive);
if (castSensor?.Coordinates == null)
continue;
{
RobustXamlLoader.Load(this);
- Clear.StyleClasses.Add(StyleBase.ButtonOpenLeft);
- Clear.StyleClasses.Add(StyleNano.StyleClassButtonColorRed);
+ Clear.StyleClasses.Add(StyleClass.ButtonOpenLeft);
+ Clear.StyleClasses.Add(StyleClass.Negative);
DeviceList.OnRemoveAddress += args =>
{
OnRemoveAddress?.Invoke(args);
<ScrollContainer xmlns="https://spacestation14.io"
HorizontalExpand="True"
VerticalExpand="True">
- <Control VerticalExpand="True">
- <PanelContainer StyleClasses="PanelBackgroundBaseDark"></PanelContainer>
+ <PanelContainer StyleClasses="PanelDark" VerticalExpand="True">
<BoxContainer Orientation="Vertical" Name="DeviceList" VerticalExpand="True" SeparationOverride="4">
</BoxContainer>
- </Control>
+ </PanelContainer>
</ScrollContainer>
FooterPanel.PanelOverride = footerStyleBox;
MainPanel.PanelOverride = new StyleBoxFlat(Color.FromHex(PanelBgColor));
- ButtonClear.AddStyleClass("ButtonColorRed");
+ ButtonClear.AddStyleClass("negative");
ButtonLinkDefault.Disabled = true;
_links = new LinksRender(ButtonContainerLeft, ButtonContainerRight);
{
_configurator = configurator;
_keyBindingName = keyBindingName;
- _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
+ _label = new RichTextLabel { StyleClasses = { StyleClass.ItemStatus } };
AddChild(_label);
}
<Button Name="ArmButton"
Text="{Loc 'nuke-user-interface-arm-button'}"
Access="Public"
- StyleClasses="Caution"/>
+ StyleClasses="negative"/>
</BoxContainer>
</BoxContainer>
</BoxContainer>
Access="Public" />
<Button Name="WarButton"
Text="{Loc 'war-declarator-ui-try-war-button'}"
- StyleClasses="Caution"
+ StyleClasses="negative"
Access="Public"/>
<BoxContainer Orientation="Vertical" HorizontalExpand="True">
<Label Name="StatusLabel"
WarButton.Disabled = true;
StatusLabel.Text = Loc.GetString("war-declarator-boost-declared");
UpdateTimer();
- StatusLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateLow);
+ StatusLabel.SetOnlyStyleClass(StyleClass.Highlight);
break;
case WarConditionStatus.YesWar:
WarButton.Text = Loc.GetString("war-declarator-ui-war-button");
StatusLabel.Text = Loc.GetString("war-declarator-boost-possible");
UpdateTimer();
- StatusLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateGood);
+ StatusLabel.SetOnlyStyleClass(StyleClass.Positive);
break;
case WarConditionStatus.NoWarSmallCrew:
StatusLabel.Text = Loc.GetString("war-declarator-boost-impossible");
InfoLabel.Text = Loc.GetString("war-declarator-conditions-small-crew");
- StatusLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateNone);
+ StatusLabel.SetOnlyStyleClass(StyleClass.Negative);
break;
case WarConditionStatus.NoWarShuttleDeparted:
StatusLabel.Text = Loc.GetString("war-declarator-boost-impossible");
InfoLabel.Text = Loc.GetString("war-declarator-conditions-left-outpost");
- StatusLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateNone);
+ StatusLabel.SetOnlyStyleClass(StyleClass.Negative);
break;
case WarConditionStatus.NoWarTimeout:
StatusLabel.Text = Loc.GetString("war-declarator-boost-impossible");
InfoLabel.Text = Loc.GetString("war-declarator-conditions-time-out");
- StatusLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateNone);
+ StatusLabel.SetOnlyStyleClass(StyleClass.Negative);
break;
case WarConditionStatus.NoWarUnknown:
StatusLabel.Text = Loc.GetString("war-declarator-boost-impossible");
InfoLabel.Text = Loc.GetString("war-declarator-conditions-unknown");
- StatusLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateNone);
+ StatusLabel.SetOnlyStyleClass(StyleClass.Negative);
break;
default:
StatusLabel.Text = Loc.GetString("war-declarator-boost-impossible");
InfoLabel.Text = Loc.GetString("war-declarator-conditions-unknown");
- StatusLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateNone);
+ StatusLabel.SetOnlyStyleClass(StyleClass.Negative);
break;
}
}
<Button Name="ResetButton"
Text="{Loc 'ui-options-reset-all'}"
- StyleClasses="Caution" />
+ StyleClasses="negative" />
<Button Name="ApplyButton"
Text="{Loc 'ui-options-apply'}"
StyleClasses="OpenLeft" />
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
- ResetButton.StyleClasses.Add(StyleBase.ButtonOpenRight);
+ ResetButton.StyleClasses.Add(StyleClass.ButtonOpenRight);
ApplyButton.OnPressed += ApplyButtonPressed;
ResetButton.OnPressed += ResetButtonPressed;
DefaultButton.OnPressed += DefaultButtonPressed;
KeybindsContainer.AddChild(new Label
{
Text = Loc.GetString(headerContents),
- FontColorOverride = StyleNano.NanoGold,
- StyleClasses = { StyleNano.StyleClassLabelKeyText }
+ StyleClasses = { StyleClass.LabelKeyText }
});
}
HorizontalAlignment = HAlignment.Left
};
- BindButton1 = new BindButton(parent, this, StyleBase.ButtonOpenRight);
- BindButton2 = new BindButton(parent, this, StyleBase.ButtonOpenLeft);
- ResetButton = new Button { Text = Loc.GetString("ui-options-bind-reset"), StyleClasses = { StyleBase.ButtonCaution } };
+ BindButton1 = new BindButton(parent, this, StyleClass.ButtonOpenRight);
+ BindButton2 = new BindButton(parent, this, StyleClass.ButtonOpenLeft);
+ ResetButton = new Button { Text = Loc.GetString("ui-options-bind-reset"), StyleClasses = { StyleClass.Negative } };
var hBox = new BoxContainer
{
--- /dev/null
+using Content.Client.PDA;
+using Content.Client.Stylesheets;
+using Content.Client.Stylesheets.Sheetlets;
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.PDA;
+
+[CommonSheetlet]
+public sealed class PdaSheetlet : Sheetlet<NanotrasenStylesheet>
+{
+ public override StyleRule[] GetRules(NanotrasenStylesheet sheet, object config)
+ {
+ IPanelConfig panelCfg = sheet;
+ IButtonConfig btnCfg = sheet;
+
+ // TODO: This should have its own set of images, instead of using button cfg directly.
+ var angleBorderRect =
+ sheet.GetTexture(panelCfg.GeometricPanelBorderPath).IntoPatch(StyleBox.Margin.All, 10);
+
+ return
+ [
+ //PDA - Backgrounds
+ E<PanelContainer>()
+ .Class("PdaContentBackground")
+ .Prop(PanelContainer.StylePropertyPanel, StyleBoxHelpers.SquareStyleBox(sheet))
+ .Prop(Control.StylePropertyModulateSelf, Color.FromHex("#25252a")),
+
+ E<PanelContainer>()
+ .Class("PdaBackground")
+ .Prop(PanelContainer.StylePropertyPanel, StyleBoxHelpers.SquareStyleBox(sheet))
+ .Prop(Control.StylePropertyModulateSelf, Color.FromHex("#000000")),
+
+ E<PanelContainer>()
+ .Class("PdaBackgroundRect")
+ .Prop(PanelContainer.StylePropertyPanel, StyleBoxHelpers.BaseStyleBox((sheet)))
+ .Prop(Control.StylePropertyModulateSelf, Color.FromHex("#717059")),
+
+ E<PanelContainer>()
+ .Class("PdaBorderRect")
+ .Prop(PanelContainer.StylePropertyPanel, angleBorderRect),
+
+ //PDA - Buttons
+ E<PdaSettingsButton>()
+ .Pseudo(ContainerButton.StylePseudoClassNormal)
+ .Prop(PdaSettingsButton.StylePropertyBgColor, Color.FromHex(PdaSettingsButton.NormalBgColor))
+ .Prop(PdaSettingsButton.StylePropertyFgColor, Color.FromHex(PdaSettingsButton.EnabledFgColor)),
+
+ E<PdaSettingsButton>()
+ .Pseudo(ContainerButton.StylePseudoClassHover)
+ .Prop(PdaSettingsButton.StylePropertyBgColor, Color.FromHex(PdaSettingsButton.HoverColor))
+ .Prop(PdaSettingsButton.StylePropertyFgColor, Color.FromHex(PdaSettingsButton.EnabledFgColor)),
+
+ E<PdaSettingsButton>()
+ .Pseudo(ContainerButton.StylePseudoClassPressed)
+ .Prop(PdaSettingsButton.StylePropertyBgColor, Color.FromHex(PdaSettingsButton.PressedColor))
+ .Prop(PdaSettingsButton.StylePropertyFgColor, Color.FromHex(PdaSettingsButton.EnabledFgColor)),
+
+ E<PdaSettingsButton>()
+ .Pseudo(ContainerButton.StylePseudoClassDisabled)
+ .Prop(PdaSettingsButton.StylePropertyBgColor, Color.FromHex(PdaSettingsButton.NormalBgColor))
+ .Prop(PdaSettingsButton.StylePropertyFgColor, Color.FromHex(PdaSettingsButton.DisabledFgColor)),
+
+ E<PdaProgramItem>()
+ .Pseudo(ContainerButton.StylePseudoClassNormal)
+ .Prop(PdaProgramItem.StylePropertyBgColor, Color.FromHex(PdaProgramItem.NormalBgColor)),
+
+ E<PdaProgramItem>()
+ .Pseudo(ContainerButton.StylePseudoClassHover)
+ .Prop(PdaProgramItem.StylePropertyBgColor, Color.FromHex(PdaProgramItem.HoverColor)),
+
+ E<PdaProgramItem>()
+ .Pseudo(ContainerButton.StylePseudoClassPressed)
+ .Prop(PdaProgramItem.StylePropertyBgColor, Color.FromHex(PdaProgramItem.HoverColor)),
+
+ //PDA - Text
+ E<Label>()
+ .Class("PdaContentFooterText")
+ .Prop(Label.StylePropertyFont, sheet.BaseFont.GetFont(10))
+ .Prop(Label.StylePropertyFontColor, Color.FromHex("#757575")),
+
+ E<Label>()
+ .Class("PdaWindowFooterText")
+ .Prop(Label.StylePropertyFont, sheet.BaseFont.GetFont(10))
+ .Prop(Label.StylePropertyFontColor, Color.FromHex("#333d3b")),
+ ];
+ }
+}
+
if (!isValid)
{
input.Text = PreviousNoteInputs[index];
- input.AddStyleClass("Caution");
+ input.AddStyleClass("highlight");
}
else
{
PreviousNoteInputs[index] = input.Text;
- input.RemoveStyleClass("Caution");
+ input.RemoveStyleClass("highlight");
}
input.CursorPosition = input.Text.Length;
if (!IsNote(input.Text))
{
input.Text = PreviousNoteInputs[index];
- input.RemoveStyleClass("Caution");
+ input.RemoveStyleClass("highlight");
}
};
if (!IsNote(input.Text))
{
input.Text = PreviousNoteInputs[index];
- input.RemoveStyleClass("Caution");
+ input.RemoveStyleClass("highlight");
}
input.CursorPosition = input.Text.Length;
};
--- /dev/null
+using Content.Client.Resources;
+using Content.Client.Stylesheets;
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Paper.UI;
+
+[CommonSheetlet]
+public sealed class PaperSheetlet : Sheetlet<NanotrasenStylesheet>
+{
+ public override StyleRule[] GetRules(NanotrasenStylesheet sheet, object config)
+ {
+ var windowCfg = (IWindowConfig)sheet;
+
+ var paperBackground = ResCache.GetTexture("/Textures/Interface/Paper/paper_background_default.svg.96dpi.png")
+ .IntoPatch(StyleBox.Margin.All, 16);
+ var paperBox = new StyleBoxTexture
+ { Texture = sheet.GetTexture(windowCfg.TransparentWindowBackgroundBorderedPath) };
+ paperBox.SetPatchMargin(StyleBox.Margin.All, 2);
+
+ return
+ [
+ E<PanelContainer>().Identifier("PaperContainer").Panel(paperBox),
+ E<PanelContainer>()
+ .Identifier("PaperDefaultBorder")
+ .Prop(PanelContainer.StylePropertyPanel, paperBackground),
+ ];
+ }
+}
SetSize="510 660"> <!-- Provide some reasonable sizes by default. Can be changed by the component -->
<BoxContainer Name="ContentsRoot" Orientation="Vertical">
- <PanelContainer StyleClasses="AngleRect" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="6">
+ <PanelContainer StyleClasses="BackgroundPanel" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="6">
<TextureButton Name="CloseButton" StyleClasses="windowCloseButton"/>
</PanelContainer>
- <PanelContainer Name="PaperBackground" StyleClasses="PaperDefaultBorder" VerticalExpand="True" HorizontalExpand="True">
+ <PanelContainer Name="PaperBackground" StyleIdentifier="PaperDefaultBorder" VerticalExpand="True" HorizontalExpand="True">
<ScrollContainer Name="ScrollingContents" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalExpand="True" VerticalExpand="True" HScrollEnabled="False">
<PanelContainer Name="PaperContent" VerticalExpand="True" HorizontalExpand="True" MaxWidth="600">
<BoxContainer Orientation="Vertical" VerticalAlignment="Stretch">
<TextureButton Name="HeaderImage" HorizontalAlignment="Center" VerticalAlignment="Top" MouseFilter="Ignore"/>
<Control Name="TextAlignmentPadding" VerticalAlignment="Top"/>
- <RichTextLabel Name="BlankPaperIndicator" StyleClasses="LabelSecondaryColor" VerticalAlignment="Top" HorizontalAlignment="Center"/>
+ <RichTextLabel Name="BlankPaperIndicator" StyleClasses="LabelWeak" VerticalAlignment="Top" HorizontalAlignment="Center"/>
<RichTextLabel StyleClasses="PaperWrittenText" Name="WrittenTextLabel" VerticalAlignment="Top"/>
- <BoxContainer Name="InputContainer" Orientation="Vertical" VerticalExpand="True" VerticalAlignment="Stretch">
+ <BoxContainer Name="InputContainer" StyleIdentifier="PaperContainer" Orientation="Vertical" VerticalExpand="True" VerticalAlignment="Stretch">
<PanelContainer StyleClasses="TransparentBorderedWindowPanel" MinHeight="100"
VerticalAlignment="Stretch" VerticalExpand="True" HorizontalExpand="True">
<TextEdit Name="Input" StyleClasses="PaperLineEdit" Access="Public" />
<paper:StampWidget xmlns="https://spacestation14.io"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:style="clr-namespace:Content.Client.Stylesheets"
- xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
- xmlns:paper="clr-namespace:Content.Client.Paper.UI" HorizontalAlignment="Center" Margin="6">
-
- <paper:StampLabel Name="StampedByLabel" StyleClasses="LabelHeadingBigger"
- FontColorOverride="{x:Static style:StyleNano.DangerousRedFore}"
- Margin="12 6 12 6"/>
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:paper="clr-namespace:Content.Client.Paper.UI"
+ HorizontalAlignment="Center"
+ Margin="6">
+ <paper:StampLabel Name="StampedByLabel" StyleClasses="LabelHeadingBigger" Margin="12 6 12 6" />
</paper:StampWidget>
var topPanel = new PanelContainer()
{
- PanelOverride = new StyleBoxFlat()
- {
- BackgroundColor = StyleNano.ButtonColorContext.WithAlpha(1f),
- BorderColor = StyleNano.PanelDark
- },
+ StyleClasses = { StyleClass.PanelDark },
VerticalExpand = false,
HorizontalExpand = true,
SetWidth = 650f,
<GridContainer Margin="10 0 0 0" Columns="2">
<!-- Power On/Off -->
<Label Text="{Loc 'apc-menu-breaker-label'}" HorizontalExpand="True"
- StyleClasses="StatusFieldTitle" MinWidth="120"/>
+ StyleClasses="highlight" MinWidth="120"/>
<BoxContainer Orientation="Horizontal" MinWidth="90">
<Button Name="BreakerButton" Text="{Loc 'apc-menu-breaker-button'}" HorizontalExpand="True" ToggleMode="True"/>
</BoxContainer>
<!--Charging Status-->
- <Label Text="{Loc 'apc-menu-external-label'}" StyleClasses="StatusFieldTitle" MinWidth="120" />
+ <Label Text="{Loc 'apc-menu-external-label'}" StyleClasses="highlight" MinWidth="120" />
<Label Name="ExternalPowerStateLabel" Text="{Loc 'apc-menu-power-state-good'}" />
<!--Battery Power-->
- <Label Text="{Loc 'apc-menu-power-label'}" StyleClasses="StatusFieldTitle" MinWidth="120" />
+ <Label Text="{Loc 'apc-menu-power-label'}" StyleClasses="highlight" MinWidth="120" />
<Label Name="PowerLabel"/>
</GridContainer>
</BoxContainer>
-using Robust.Client.AutoGenerated;
+using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML;
using Robust.Client.GameObjects;
using Robust.Shared.IoC;
using Content.Client.Stylesheets;
using Content.Shared.APC;
using Robust.Client.Graphics;
-using Robust.Client.UserInterface.Controls;
-using Robust.Shared.GameObjects;
-using Robust.Shared.Localization;
-using Robust.Shared.Maths;
using FancyWindow = Content.Client.UserInterface.Controls.FancyWindow;
namespace Content.Client.Power.APC.UI
if (PowerLabel != null)
{
- PowerLabel.Text = castState.Power + " W";
+ PowerLabel.Text = Loc.GetString("apc-menu-power-state-label-text", ("power", castState.Power));
}
if (ExternalPowerStateLabel != null)
{
case ApcExternalPowerState.None:
ExternalPowerStateLabel.Text = Loc.GetString("apc-menu-power-state-none");
- ExternalPowerStateLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateNone);
+ ExternalPowerStateLabel.SetOnlyStyleClass("negative");
break;
case ApcExternalPowerState.Low:
ExternalPowerStateLabel.Text = Loc.GetString("apc-menu-power-state-low");
- ExternalPowerStateLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateLow);
+ ExternalPowerStateLabel.SetOnlyStyleClass("highlight");
break;
case ApcExternalPowerState.Good:
ExternalPowerStateLabel.Text = Loc.GetString("apc-menu-power-state-good");
- ExternalPowerStateLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateGood);
+ ExternalPowerStateLabel.SetOnlyStyleClass("positive");
break;
default:
throw new ArgumentOutOfRangeException();
if (starting)
{
StatusLabel.Text = _loc.GetString("portable-generator-ui-status-starting");
- StatusLabel.SetOnlyStyleClass("Caution");
+ StatusLabel.SetOnlyStyleClass("negative");
StartProgress.Value = progress;
}
else if (on)
{
StatusLabel.Text = _loc.GetString("portable-generator-ui-status-running");
- StatusLabel.SetOnlyStyleClass("Good");
+ StatusLabel.SetOnlyStyleClass("positive");
}
else
{
StatusLabel.Text = _loc.GetString("portable-generator-ui-status-stopped");
- StatusLabel.SetOnlyStyleClass("Danger");
+ StatusLabel.SetOnlyStyleClass("highlight");
}
var canSwitch = _entityManager.TryGetComponent(_entity, out PowerSwitchableComponent? switchable);
("supply", netStats.Supply));
var good = netStats.Load <= netStats.Supply;
- NetworkStats.SetOnlyStyleClass(good ? "Good" : "Caution");
+ NetworkStats.SetOnlyStyleClass(good ? "positive" : "highlight");
}
else
{
-<controls:FancyWindow
+<controls:FancyWindow
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
MinSize="320 180"
<Label
Text="{Loc 'power-charge-window-power'}"
HorizontalExpand="True"
- StyleClasses="StatusFieldTitle" />
+ StyleClasses="highlight" />
<BoxContainer
Orientation="Horizontal"
<!-- Status -->
<Label
Text="{Loc 'power-charge-window-status'}"
- StyleClasses="StatusFieldTitle" />
+ StyleClasses="highlight" />
<Label Name="StatusLabel"
Text="{Loc 'power-charge-window-status-fully-charged'}" />
<!-- ETA -->
<Label
Text="{Loc 'power-charge-window-eta'}"
- StyleClasses="StatusFieldTitle" />
+ StyleClasses="highlight" />
<Label Name="EtaLabel"
Text="N/A" />
<!-- Charge -->
<Label
Text="{Loc 'power-charge-window-charge'}"
- StyleClasses="StatusFieldTitle" />
+ StyleClasses="highlight" />
<ProgressBar Name="ChargeBar"
MaxValue="255">
-using Content.Client.UserInterface.Controls;
+using Content.Client.Stylesheets.Palette;
+using Content.Client.UserInterface.Controls;
using Content.Shared.Power;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
("draw", state.PowerDraw),
("max", state.PowerDrawMax));
- PowerLabel.SetOnlyStyleClass(MathHelper.CloseTo(state.PowerDraw, state.PowerDrawMax) ? "Good" : "Caution");
+ PowerLabel.FontColorOverride = MathHelper.CloseTo(state.PowerDraw, state.PowerDrawMax)
+ ? Palettes.Status.Good
+ : Palettes.Status.Warning;
+ // TODO: blend with status colors instead of setting hard values
ChargeBar.Value = state.Charge;
ChargeText.Text = (state.Charge / 255f).ToString("P0");
_ => throw new ArgumentOutOfRangeException()
});
- StatusLabel.SetOnlyStyleClass(state.PowerStatus switch
+ StatusLabel.FontColorOverride = (state.PowerStatus switch
{
- PowerChargePowerStatus.Off => "Danger",
- PowerChargePowerStatus.Discharging => "Caution",
- PowerChargePowerStatus.Charging => "Caution",
- PowerChargePowerStatus.FullyCharged => "Good",
+ PowerChargePowerStatus.Off => Palettes.Status.Critical,
+ PowerChargePowerStatus.Discharging => Palettes.Status.Warning,
+ PowerChargePowerStatus.Charging => Palettes.Status.Warning,
+ PowerChargePowerStatus.FullyCharged => Palettes.Status.Good,
_ => throw new ArgumentOutOfRangeException()
});
? Loc.GetString("power-charge-window-eta-value", ("left", TimeSpan.FromSeconds(state.EtaSeconds)))
: Loc.GetString("power-charge-window-eta-none");
- EtaLabel.SetOnlyStyleClass(state.EtaSeconds >= 0 ? "Caution" : "Disabled");
+ EtaLabel.SetOnlyStyleClass(state.EtaSeconds >= 0 ? "highlight" : "LabelWeak");
}
}
<!-- Power overview -->
<GridContainer Columns="2">
- <Label StyleClasses="StatusFieldTitle" Text="{Loc 'power-monitoring-window-total-sources'}"/>
+ <Label StyleClasses="highlight" Text="{Loc 'power-monitoring-window-total-sources'}"/>
<Label Name="TotalSources" Text="?" Margin="10 0 0 0"/>
- <Label StyleClasses="StatusFieldTitle" Text="{Loc 'power-monitoring-window-total-battery-usage'}"/>
+ <Label StyleClasses="highlight" Text="{Loc 'power-monitoring-window-total-battery-usage'}"/>
<Label Name="TotalBatteryUsage" Text="?" Margin="10 0 0 0"/>
- <Label StyleClasses="StatusFieldTitle" Text="{Loc 'power-monitoring-window-total-loads'}"/>
+ <Label StyleClasses="highlight" Text="{Loc 'power-monitoring-window-total-loads'}"/>
<Label Name="TotalLoads" Text="?" Margin="10 0 0 0"/>
</GridContainer>
// Update button style
if (netEntity == _focusEntity)
- button.AddStyleClass(StyleNano.StyleClassButtonColorGreen);
+ button.AddStyleClass(StyleClass.Positive);
else
- button.RemoveStyleClass(StyleNano.StyleClassButtonColorGreen);
+ button.RemoveStyleClass(StyleClass.Positive);
// Update sprite
if (entry.MetaData.Value.SpritePath != string.Empty && entry.MetaData.Value.SpriteState != string.Empty)
// Toggle off button?
if (entry.NetEntity == _focusEntity)
{
- entry.Button.RemoveStyleClass(StyleNano.StyleClassButtonColorGreen);
+ entry.Button.RemoveStyleClass(StyleClass.Positive);
_focusEntity = null;
// Request an update from the power monitoring system
}
// Otherwise, toggle on
- entry.Button.AddStyleClass(StyleNano.StyleClassButtonColorGreen);
+ entry.Button.AddStyleClass(StyleClass.Positive);
ActivateAutoScrollToFocus();
{
if (sibling.NetEntity == _focusEntity)
{
- sibling.Button.RemoveStyleClass(StyleNano.StyleClassButtonColorGreen);
+ sibling.Button.RemoveStyleClass(StyleClass.Positive);
break;
}
}
public GeigerItemControl(GeigerComponent component)
{
_component = component;
- _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
+ _label = new RichTextLabel { StyleClasses = { StyleClass.ItemStatus } };
AddChild(_label);
Update();
public DoorRemoteStatusControl(Entity<DoorRemoteComponent> entity)
{
_entity = entity;
- _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
+ _label = new RichTextLabel { StyleClasses = { StyleClass.ItemStatus } };
AddChild(_label);
}
xmlns:pllax="clr-namespace:Content.Client.Parallax">
<pllax:ParallaxControl SpeedX="20"/>
<Control HorizontalAlignment="Center" VerticalAlignment="Center">
- <PanelContainer StyleClasses="AngleRect" />
+ <PanelContainer StyleClasses="BackgroundPanel" />
<BoxContainer Orientation="Vertical" SetSize="800 600" Margin="2">
<ScrollContainer Name="what" VerticalExpand="True" HScrollEnabled="False" Margin="0 0 0 2" ReturnMeasure="True">
<RichTextLabel Name="ReasonLabel" VerticalAlignment="Top" />
</ScrollContainer>
- <Button Name="RetryButton" StyleClasses="Caution" Text="{Loc 'replay-loading-retry'}" Visible="False" />
+ <Button Name="RetryButton" StyleClasses="negative" Text="{Loc 'replay-loading-retry'}" Visible="False" />
<Button Name="CancelButton" Text="{Loc 'replay-loading-cancel'}" Visible="False" />
</BoxContainer>
</Control>
};
// cant put multiple styles in xaml for some reason
- DestroyButton.StyleClasses.Add(StyleBase.ButtonCaution);
+ DestroyButton.StyleClasses.Add(StyleClass.Negative);
}
public void SetEntity(EntityUid uid)
roundEndTabs.AddChild(MakeRoundEndSummaryTab(gm, roundEnd, roundTimeSpan, roundId));
roundEndTabs.AddChild(MakePlayerManifestTab(info));
- Contents.AddChild(roundEndTabs);
+ ContentsContainer.AddChild(roundEndTabs);
OpenCenteredRight();
MoveToFront();
if (_claimed)
{
- ClaimButton.AddStyleClass(StyleBase.ButtonCaution);
+ ClaimButton.AddStyleClass(StyleClass.Negative);
ClaimButton.Text = Loc.GetString("offering-window-claimed");
}
else
{
- ClaimButton.RemoveStyleClass(StyleBase.ButtonCaution);
+ ClaimButton.RemoveStyleClass(StyleClass.Negative);
ClaimButton.Text = Loc.GetString("offering-window-claim");
}
}
offering.AddContent(new Label
{
Text = difficultyProto.RecommendedPlayers.ToString(),
- FontColorOverride = StyleNano.NanoGold,
HorizontalAlignment = Control.HAlignment.Left,
Margin = new Thickness(0f, 0f, 0f, 5f),
+ StyleClasses = { StyleClass.LabelKeyText },
});
// Details
Text = string.IsNullOrWhiteSpace(Loc.GetString(_protoManager.Index<SalvageFactionPrototype>(faction).Description))
? LogAndReturnDefaultFactionDescription(faction)
: Loc.GetString(_protoManager.Index<SalvageFactionPrototype>(faction).Description),
- FontColorOverride = StyleNano.NanoGold,
HorizontalAlignment = Control.HAlignment.Left,
Margin = new Thickness(0f, 0f, 0f, 5f),
+ StyleClasses = { StyleClass.LabelKeyText },
});
string LogAndReturnDefaultFactionDescription(string faction)
offering.AddContent(new Label
{
Text = mission.Duration.ToString(),
- FontColorOverride = StyleNano.NanoGold,
HorizontalAlignment = Control.HAlignment.Left,
Margin = new Thickness(0f, 0f, 0f, 5f),
+ StyleClasses = { StyleClass.LabelKeyText },
});
// Biome
Text = string.IsNullOrWhiteSpace(Loc.GetString(_protoManager.Index<SalvageBiomeModPrototype>(biome).Description))
? LogAndReturnDefaultBiomDescription(biome)
: Loc.GetString(_protoManager.Index<SalvageBiomeModPrototype>(biome).Description),
- FontColorOverride = StyleNano.NanoGold,
HorizontalAlignment = Control.HAlignment.Left,
Margin = new Thickness(0f, 0f, 0f, 5f),
+ StyleClasses = { StyleClass.LabelKeyText },
});
string LogAndReturnDefaultBiomDescription(string biome)
offering.AddContent(new Label
{
Text = string.Join("\n", mods.Select(o => "- " + o)).TrimEnd(),
- FontColorOverride = StyleNano.NanoGold,
HorizontalAlignment = Control.HAlignment.Left,
Margin = new Thickness(0f, 0f, 0f, 5f),
+ StyleClasses = { StyleClass.LabelKeyText },
});
offering.ClaimPressed += args =>
foreach (var sensor in _sensorData.Values)
{
- var labelName = new Label { Text = sensor.Name, StyleClasses = { StyleBase.StyleClassLabelHeading } };
+ var labelName = new Label { Text = sensor.Name, StyleClasses = { StyleClass.LabelHeading } };
var labelAddress = new Label
{
Text = sensor.Address,
Margin = new Thickness(4, 0),
VerticalAlignment = VAlignment.Bottom,
- StyleClasses = { StyleNano.StyleClassLabelSecondaryColor }
+ StyleClasses = { StyleClass.LabelWeak }
};
Asdf.AddChild(new BoxContainer
Orientation = BoxContainer.LayoutOrientation.Horizontal,
Children =
{
- new Label { Text = stream.Name, StyleClasses = { "monospace" }, HorizontalExpand = true },
+ new Label { Text = stream.Name, StyleClasses = { "Monospace" }, HorizontalExpand = true },
new Label { Text = FormatValue(stream.Unit, lastSample.Value) }
}
});
Asdf.AddChild(new GraphView(stream.Samples, startTime, curTime, maxValue * 1.1f, this) { MinHeight = 150 });
- Asdf.AddChild(new PanelContainer { StyleClasses = { StyleBase.ClassLowDivider } });
+ Asdf.AddChild(new PanelContainer { StyleClasses = { StyleClass.LowDivider } });
}
}
}
MinSize="200 200">
<BoxContainer Orientation="Vertical" HorizontalExpand="True">
<GridContainer Margin="4 0 0 0" Columns="2">
- <Label Name="ShowIFFLabel" Text="{Loc 'iff-console-show-iff-label'}" HorizontalExpand="True" StyleClasses="StatusFieldTitle" />
+ <Label Name="ShowIFFLabel" Text="{Loc 'iff-console-show-iff-label'}" HorizontalExpand="True" StyleClasses="highlight" />
<BoxContainer Orientation="Horizontal" MinWidth="120">
<Button Name="ShowIFFOnButton" Text="{Loc 'iff-console-on'}" StyleClasses="OpenRight" />
<Button Name="ShowIFFOffButton" Text="{Loc 'iff-console-off'}" StyleClasses="OpenLeft" />
</BoxContainer>
- <Label Name="ShowVesselLabel" Text="{Loc 'iff-console-show-vessel-label'}" HorizontalExpand="True" StyleClasses="StatusFieldTitle" />
+ <Label Name="ShowVesselLabel" Text="{Loc 'iff-console-show-vessel-label'}" HorizontalExpand="True" StyleClasses="highlight" />
<BoxContainer Orientation="Horizontal" MinWidth="120">
<Button Name="ShowVesselOnButton" Text="{Loc 'iff-console-on'}" StyleClasses="OpenRight" />
<Button Name="ShowVesselOffButton" Text="{Loc 'iff-console-off'}" StyleClasses="OpenLeft" />
BrainView.Visible = true;
BrainView.SetEntity(brain);
BrainButton.Disabled = false;
- BrainButton.AddStyleClass(StyleBase.ButtonOpenLeft);
+ BrainButton.AddStyleClass(StyleClass.ButtonOpenLeft);
}
else
{
BrainButton.Text = Loc.GetString("borg-ui-no-brain");
BrainButton.Disabled = true;
BrainView.Visible = false;
- BrainButton.RemoveStyleClass(StyleBase.ButtonOpenLeft);
+ BrainButton.RemoveStyleClass(StyleClass.ButtonOpenLeft);
}
}
<PanelContainer xmlns="https://spacestation14.io"
HorizontalExpand="True"
- StyleClasses="PanelBackgroundLight"
+ StyleClasses="PanelLight"
Margin="5 5 5 0">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="5 5 0 5">
<SpriteView Name="ModuleView" Margin="0 0 5 0"/>
<customControls:HSeparator Margin="0 5 0 5"/>
<RichTextLabel Name="LawLabel"/>
<BoxContainer Name="LawAnnouncementButtons" Orientation="Horizontal" HorizontalExpand="True" Margin="0 5 0 0">
- <Label Text="{Loc laws-ui-state-law}" StyleClasses="StatusFieldTitle"/>
+ <Label Text="{Loc laws-ui-state-law}" StyleClasses="highlight"/>
<Control Margin="5 0 0 0" />
<!-- Buttons are added via C# code-->
</BoxContainer>
public StatusControl(Entity<SprayPainterComponent> ent)
{
_entity = ent;
- _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
+ _label = new RichTextLabel { StyleClasses = { StyleClass.ItemStatus } };
AddChild(_label);
}
public StackStatusControl(StackComponent parent)
{
_parent = parent;
- _label = new RichTextLabel {StyleClasses = {StyleNano.StyleClassItemStatus}};
+ _label = new RichTextLabel {StyleClasses = {StyleClass.ItemStatus}};
_label.SetMarkup(Loc.GetString("comp-stack-status", ("count", _parent.Count)));
AddChild(_label);
}
public StrippingMenu()
{
var box = new BoxContainer() { Orientation = LayoutOrientation.Vertical, Margin = new Thickness(0, 8) };
- Contents.AddChild(box);
+ ContentsContainer.AddChild(box);
box.AddChild(SnareContainer);
box.AddChild(HandsContainer);
box.AddChild(InventoryContainer);
--- /dev/null
+using Content.Client.Stylesheets.Fonts;
+using Robust.Client.ResourceManagement;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using Robust.Shared.Reflection;
+using Robust.Shared.Sandboxing;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets;
+
+public abstract partial class BaseStylesheet : IStyleResources
+{
+ [Dependency] protected readonly ISandboxHelper SandboxHelper = default!;
+ [Dependency] protected readonly IReflectionManager ReflectionManager = default!;
+ [Dependency] protected internal readonly IResourceCache ResCache = default!;
+
+ public Stylesheet Stylesheet { get; init; }
+
+ public abstract NotoFontFamilyStack BaseFont { get; }
+
+ /// <summary>
+ /// Get the style rules for the given font stack, with the provided sizes.
+ /// Does not set the 'default' font, but does create rules for every combination of font kind and font size.
+ /// This is intended for font sizes you think will be common/generally useful, for less common usecases prefer specifying the font explicitly.
+ /// </summary>
+ /// <param name="prefix">The prefix for the style classes, if any.</param>
+ /// <param name="stack">Font stack to use</param>
+ /// <param name="sizes">A set of styleclasses and the associated size of font to use.</param>
+ /// <returns>A rules list containing all combinations.</returns>
+ /// <remarks>Use <see cref="M:Content.Client.Stylesheets.BaseStylesheet.GetFontClass(Content.Client.Stylesheets.Redux.Fonts.FontStack.FontKind,System.String)"/> to get the appropriate styleclass for a font choice.</remarks>
+ // god xmldoc refs are long ^^^
+ // lmao
+ protected StyleRule[] GetRulesForFont(string? prefix, NotoFontFamilyStack stack, List<(string?, int)> sizes) // TODO: NotoFontFamilyStack is temporary
+ {
+ var rules = new List<StyleRule>();
+
+ foreach (var (name, size) in sizes)
+ {
+ foreach (var kind in stack.AvailableKinds)
+ {
+ var builder = E().Class(GetFontClass(kind, prefix));
+
+ if (name is not null)
+ builder.Class(name);
+
+ builder.Prop(Label.StylePropertyFont, stack.GetFont(size, kind));
+
+ rules.Add(builder);
+ }
+ }
+
+ return rules.ToArray();
+ }
+
+ /// <summary>
+ /// Returns the appropriate styleclass for the given font configuration.
+ /// </summary>
+ /// <param name="kind"></param>
+ /// <param name="prefix"></param>
+ /// <returns></returns>
+ public static string GetFontClass(FontKind kind, string? prefix = null)
+ {
+ var kindStr = kind.ToString().ToLowerInvariant();
+ return prefix is null ? $"font-{kindStr}" : $"{prefix}-{kindStr}";
+ }
+}
--- /dev/null
+using System.Diagnostics.CodeAnalysis;
+using Robust.Client.ResourceManagement;
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets;
+
+public abstract partial class BaseStylesheet
+{
+ /// <summary>
+ /// The file roots of the stylesheet, dictates where assets get read from for the given type of resource.
+ /// Roots will be checked in order for assets, avoid having a significant number of them.
+ /// </summary>
+ /// <remarks>
+ /// Must be a constant, changes to this after construction will not be reflected.
+ /// </remarks>
+ public abstract Dictionary<Type, ResPath[]> Roots { get; }
+
+ /// <summary>
+ /// Attempts to locate a resource within the stylesheet's roots.
+ /// </summary>
+ /// <param name="target">The relative path of the target resource.</param>
+ /// <param name="resource">The discovered/cached resource, if any.</param>
+ /// <typeparam name="T">Type of the resource to read.</typeparam>
+ /// <returns>Whether <paramref name="resource"/> is null.</returns>
+ public bool TryGetResource<T>(ResPath target, [NotNullWhen(true)] out T? resource)
+ where T : BaseResource, new()
+ {
+ DebugTools.Assert(target.IsRelative,
+ "Target path must be relative. Use ResCache directly if you need an absolute file location.");
+
+ foreach (var root in Roots[typeof(T)])
+ {
+ if (ResCache.TryGetResource(root / target, out resource))
+ return true;
+ }
+
+ resource = null;
+ return false;
+ }
+
+ /// <summary>
+ /// Retrieves a resource, or throws.
+ /// </summary>
+ /// <param name="target">The relative path of the target resource.</param>
+ /// <typeparam name="T">Type of the resource to read.</typeparam>
+ /// <returns>The retrieved resource</returns>
+ /// <exception cref="MissingStyleResourceException">Thrown if the resource does not exist within the stylesheet's roots.</exception>
+ public T GetResource<T>(ResPath target)
+ where T : BaseResource, new()
+ {
+ if (TryGetResource(target, out T? res))
+ return res;
+
+ throw new MissingStyleResourceException(this, target.ToString());
+ }
+
+ /// <summary>
+ /// Retrieves a resource, or falls back to the specified root. The resource should be present at the fallback
+ /// root, or else it throws
+ /// </summary>
+ /// <remarks>
+ /// This should be used to allow common sheetlets to be generic over multiple stylesheets without forcing other
+ /// styles to have the resource present, if your sheetlet is stylesheet-specific you should not use this.
+ /// </remarks>
+ /// <param name="target">The relative path of the target resource.</param>
+ /// <param name="fallbackRoot">The root that this resource will always exist at</param>
+ /// <typeparam name="T">Type of the resource to read.</typeparam>
+ /// <returns>The retrieved resource</returns>
+ /// <exception cref="ExpectedResourceException">Thrown if the resource does not exist in the fallback root.</exception>
+ public T GetResourceOr<T>(ResPath target, ResPath fallbackRoot)
+ where T : BaseResource, new()
+ {
+ DebugTools.Assert(fallbackRoot.IsRooted,
+ "Fallback root must be absolute. Roots can be retrieved from the stylesheets.");
+
+ if (!ResCache.TryGetResource(fallbackRoot / target, out T? fallback))
+ throw new ExpectedResourceException(this, target.ToString());
+
+ return TryGetResource(target, out T? res) ? res : fallback;
+ }
+}
+
+/// <summary>
+/// Exception thrown when the never-fail helpers in <see cref="PalettedStylesheet"/> fail to locate a resource.
+/// </summary>
+/// <param name="sheet">The stylesheet </param>
+/// <param name="target"></param>
+public sealed class MissingStyleResourceException(BaseStylesheet sheet, string target) : Exception
+{
+ public override string Message =>
+ $"Failed to find any resource at \"{target}\" for {sheet}. The roots are: {sheet.Roots}";
+
+ public override string? Source => sheet.ToString();
+}
+
+/// <summary>
+/// Exception thrown when the never-fail helpers in <see cref="PalettedStylesheet"/> expect a resource at a location
+/// but do not find it.
+/// </summary>
+/// <param name="sheet">The stylesheet</param>
+/// <param name="target"></param>
+public sealed class ExpectedResourceException(BaseStylesheet sheet, string target) : Exception
+{
+ public override string Message =>
+ $"Failed to find any resource at \"{target}\" for {sheet}, when such a resource was expected.";
+
+ public override string? Source => sheet.ToString();
+}
--- /dev/null
+using Robust.Client.UserInterface;
+
+namespace Content.Client.Stylesheets;
+
+public abstract partial class BaseStylesheet
+{
+ public StyleRule[] GetSheetletRules<TSheetTy>(Type sheetletTy, StylesheetManager man)
+ {
+ Sheetlet<TSheetTy>? sheetlet = null;
+ try
+ {
+ if (sheetletTy.ContainsGenericParameters)
+ {
+ if (SandboxHelper.CreateInstance(sheetletTy.MakeGenericType(typeof(TSheetTy))) is Sheetlet<TSheetTy>
+ sheetlet1)
+ sheetlet = sheetlet1;
+ }
+ else if (SandboxHelper.CreateInstance(sheetletTy) is Sheetlet<TSheetTy> sheetlet2)
+ {
+ sheetlet = sheetlet2;
+ }
+ }
+ // thrown when `sheetletTy.MakeGenericType` is given a type that does not satisfy the type constraints of
+ // `sheetletTy`
+ catch (ArgumentException) { }
+
+ if (sheetlet is not null)
+ {
+ man.UnusedSheetlets.Remove(sheetletTy);
+ return sheetlet.GetRules((TSheetTy)(object)this, _config);
+ }
+ else
+ return [];
+ }
+
+ public StyleRule[] GetAllSheetletRules<TSheetTy, TAttrib>(StylesheetManager man)
+ where TAttrib : Attribute
+ {
+ var tys = ReflectionManager.FindTypesWithAttribute<TAttrib>();
+ var rules = new List<StyleRule>();
+
+ foreach (var ty in tys)
+ {
+ rules.AddRange(GetSheetletRules<TSheetTy>(ty, man));
+ }
+
+ return rules.ToArray();
+ }
+}
--- /dev/null
+using System.Diagnostics.CodeAnalysis;
+using Robust.Client.Graphics;
+using Robust.Client.ResourceManagement;
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets;
+
+public abstract partial class BaseStylesheet
+{
+ #region Texture helpers
+
+ /// <summary>
+ /// Attempts to locate a texture within the stylesheet's roots.
+ /// </summary>
+ /// <param name="target">The relative path of the target resource.</param>
+ /// <param name="texture">The retrieved texture, if any.</param>
+ /// <returns>Whether <paramref name="texture"/> is null.</returns>
+ public bool TryGetTexture(ResPath target, [NotNullWhen(true)] out Texture? texture)
+ {
+ if (TryGetResource(target, out TextureResource? resource))
+ {
+ texture = resource.Texture;
+ return true;
+ }
+
+ texture = null;
+ return false;
+ }
+
+ /// <summary>
+ /// Retrieves a texture, or throws.
+ /// </summary>
+ /// <param name="target">The relative path of the target texture.</param>
+ /// <returns>The retrieved texture</returns>
+ /// <exception cref="MissingStyleResourceException">Thrown if the texture does not exist within the stylesheet's roots.</exception>
+ public Texture GetTexture(ResPath target)
+ {
+ return GetResource<TextureResource>(target).Texture;
+ }
+
+ /// <summary>
+ /// Retrieves a texture, or falls back to the specified root. The resource should be present at the fallback
+ /// root, or else it throws
+ /// </summary>
+ /// <remarks>
+ /// This should be used to allow common sheetlets to be generic over multiple stylesheets without forcing other
+ /// styles to have the resource present, if your sheetlet is stylesheet-specific you should not use this.
+ /// </remarks>
+ /// <param name="target">The relative path of the target texture.</param>
+ /// <param name="fallbackRoot">The root that this resource will always exist at</param>
+ /// <returns>The retrieved texture</returns>
+ /// <exception cref="ExpectedResourceException">Thrown if the texture does not exist in the fallback root.</exception>
+ public Texture GetTextureOr(ResPath target, ResPath fallbackRoot)
+ {
+ return GetResourceOr<TextureResource>(target, fallbackRoot).Texture;
+ }
+
+ #endregion
+}
--- /dev/null
+namespace Content.Client.Stylesheets;
+
+public abstract partial class BaseStylesheet
+{
+ /// <summary>
+ /// The type used to describe a configuration for this stylesheet.
+ /// This will be constructed and passed into the constructor, and may be used for other things as well.
+ /// </summary>
+ /// <remarks>
+ /// Must be a constant, changes to this after construction will not be reflected.
+ /// TODO: this type is currently unused. It can be used to, for example, use user-defined fonts or colors.
+ /// </remarks>
+ public virtual Type StylesheetConfigType => typeof(NoConfig);
+
+ /// <remarks>
+ /// ex. "Nanotrasen", "System", "Syndicate"
+ /// </remarks>
+ public abstract string StylesheetName { get; }
+
+ public record NoConfig();
+
+ private object _config;
+
+ /// <remarks>
+ /// This constructor will not access any virtual or abstract properties, so you can set them from your config.
+ /// </remarks>
+ protected BaseStylesheet(object config)
+ {
+ IoCManager.InjectDependencies(this);
+ _config = config;
+ Stylesheet = default!;
+ }
+}
--- /dev/null
+using System.Numerics;
+using JetBrains.Annotations;
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets.Colorspace;
+
+[PublicAPI]
+public static class ColorExtensions
+{
+ /// <summary>
+ /// Adjusts the lightness of a color using the Oklab color space.
+ /// </summary>
+ public static Color WithLightness(this Color c, float lightness)
+ {
+ DebugTools.Assert(lightness is >= 0.0f and <= 1.0f);
+
+ var oklab = Color.ToLab(c);
+ oklab.X = lightness;
+
+ return Color.FromLab(oklab);
+ }
+
+ /// <summary>
+ /// Nudges the lightness (in OKLAB space) of <see cref="c" /> by <see cref="lightnessShift"/> / 100 units
+ /// </summary>
+ public static Color NudgeLightness(this Color c, float lightnessShift)
+ {
+ var oklab = Color.ToLab(c);
+ oklab.X = Math.Clamp(oklab.X + lightnessShift, 0, 1);
+
+ return Color.FromLab(oklab);
+ }
+
+ /// <summary>
+ /// Nudges the chroma (in OKLCH space) of <see cref="c"/> by <see cref="chromaShift"/> / 100 units
+ /// </summary>
+ /// <remarks>
+ /// Referenced from https://github.com/jonathantneal/convert-colors/blob/master/src/lab-lch.js
+ /// </remarks>
+ public static Color NudgeChroma(this Color c, float chromaShift)
+ {
+ var oklab = Color.ToLab(c);
+ var oklch = Color.ToLch(oklab);
+
+ oklch.Y = Math.Clamp(oklch.Y + chromaShift, 0, 1);
+
+ return Color.FromLab(Color.FromLch(oklch));
+ }
+
+ /// <summary>
+ /// Blends two colors in the Oklab color space.
+ /// </summary>
+ public static Color OkBlend(this Color from, Color to, float factor)
+ {
+ DebugTools.Assert(factor is >= 0.0f and <= 1.0f);
+
+ var okFrom = Color.ToLab(from);
+ var okTo = Color.ToLab(to);
+
+ var blended = Vector4.Lerp(okFrom, okTo, factor);
+ return Color.FromLab(blended);
+ }
+}
--- /dev/null
+using JetBrains.Annotations;
+
+namespace Content.Client.Stylesheets;
+
+/// <summary>
+/// Attribute used to mark a sheetlet class. Stylesheets can use this attribute to locate and load sheetlets.
+/// </summary>
+[PublicAPI]
+[MeansImplicitUse]
+public sealed class CommonSheetletAttribute : Attribute
+{
+
+}
--- /dev/null
+using Content.Client.Stylesheets.Palette;
+using Content.Client.Stylesheets.SheetletConfigs;
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets;
+
+public abstract class CommonStylesheet : PalettedStylesheet, IButtonConfig, IWindowConfig, IIconConfig, ITabContainerConfig,
+ ISliderConfig, IRadialMenuConfig, IPlaceholderConfig, ITooltipConfig, IPanelConfig, INanoHeadingConfig,
+ ILineEditConfig, IStripebackConfig, ICheckboxConfig
+{
+ /// <remarks>
+ /// This constructor will not access any virtual or abstract properties, so you can set them from your config.
+ /// </remarks>
+ protected CommonStylesheet(object config) : base(config) { }
+
+ ResPath ICheckboxConfig.CheckboxUncheckedPath => new("checkbox_unchecked.svg.96dpi.png");
+ ResPath ICheckboxConfig.CheckboxCheckedPath => new("checkbox_checked.svg.96dpi.png");
+
+ ResPath IStripebackConfig.StripebackPath => new("stripeback.svg.96dpi.png");
+
+ ResPath INanoHeadingConfig.NanoHeadingPath => new("nanoheading.svg.96dpi.png");
+
+ ResPath ILineEditConfig.LineEditPath => new("lineedit.png");
+
+ ResPath IPanelConfig.GeometricPanelBorderPath => new("geometric_panel_border.svg.96dpi.png");
+ ResPath IPanelConfig.BlackPanelDarkThinBorderPath => new("black_panel_dark_thin_border.png");
+
+ ResPath ITooltipConfig.TooltipBoxPath => new("tooltip.png");
+ ResPath ITooltipConfig.WhisperBoxPath => new("whisper.png");
+
+ ResPath IPlaceholderConfig.PlaceholderPath => new("placeholder.png");
+
+ ResPath IRadialMenuConfig.ButtonNormalPath => new("Radial/button_normal.png");
+ ResPath IRadialMenuConfig.ButtonHoverPath => new("Radial/button_hover.png");
+ ResPath IRadialMenuConfig.CloseNormalPath => new("Radial/close_normal.png");
+ ResPath IRadialMenuConfig.CloseHoverPath => new("Radial/close_hover.png");
+ ResPath IRadialMenuConfig.BackNormalPath => new("Radial/back_normal.png");
+ ResPath IRadialMenuConfig.BackHoverPath => new("Radial/back_hover.png");
+
+ ResPath ISliderConfig.SliderFillPath => new("slider_fill.svg.96dpi.png");
+
+ ResPath ISliderConfig.SliderOutlinePath => new("slider_outline.svg.96dpi.png");
+
+ ResPath ISliderConfig.SliderGrabber => new("slider_grabber.svg.96dpi.png");
+
+
+ ResPath ITabContainerConfig.TabContainerPanelPath => new("tabcontainer_panel.png");
+
+ ResPath IIconConfig.HelpIconPath => new("help.png");
+ ResPath IIconConfig.CrossIconPath => new("cross.svg.png");
+ ResPath IIconConfig.InvertedTriangleIconPath => new("inverted_triangle.svg.png");
+
+ ResPath IWindowConfig.WindowHeaderTexturePath => new("window_header.png");
+ ResPath IWindowConfig.WindowHeaderAlertTexturePath => new("window_header_alert.png");
+ ResPath IWindowConfig.WindowBackgroundPath => new("window_background.png");
+ ResPath IWindowConfig.WindowBackgroundBorderedPath => new("window_background_bordered.png");
+ ResPath IWindowConfig.TransparentWindowBackgroundBorderedPath => new("transparent_window_background_bordered.png");
+
+ ResPath IButtonConfig.BaseButtonPath => new("button.svg.96dpi.png");
+ ResPath IButtonConfig.OpenLeftButtonPath => new("button.svg.96dpi.png");
+ ResPath IButtonConfig.OpenRightButtonPath => new("button.svg.96dpi.png");
+ ResPath IButtonConfig.OpenBothButtonPath => new("button.svg.96dpi.png");
+ ResPath IButtonConfig.SmallButtonPath => new("button_small.svg.96dpi.png");
+ ResPath IButtonConfig.RoundedButtonPath => new("rounded_button.svg.96dpi.png");
+ ResPath IButtonConfig.RoundedButtonBorderedPath => new("rounded_button_bordered.svg.96dpi.png");
+
+ ColorPalette IButtonConfig.ButtonPalette => PrimaryPalette with { PressedElement = PositivePalette.PressedElement };
+ ColorPalette IButtonConfig.PositiveButtonPalette => PositivePalette;
+ ColorPalette IButtonConfig.NegativeButtonPalette => NegativePalette;
+}
--- /dev/null
+namespace Content.Client.Stylesheets.Fonts;
+
+/// <summary>
+/// The available kinds of font.
+/// </summary>
+public enum FontKind
+{
+ Regular,
+ Bold,
+ Italic,
+ BoldItalic,
+}
+
+public static class FontKindExtensions
+{
+ internal static string AsFileName(this FontKind kind)
+ {
+ return kind switch
+ {
+ FontKind.Regular => "Regular",
+ FontKind.Bold => "Bold",
+ FontKind.Italic => "Italic",
+ FontKind.BoldItalic => "BoldItalic",
+ _ => throw new ArgumentOutOfRangeException(nameof(kind), kind, null),
+ };
+ }
+
+ internal static bool IsBold(this FontKind kind)
+ {
+ return kind is FontKind.Bold or FontKind.BoldItalic;
+ }
+
+ internal static bool IsItalic(this FontKind kind)
+ {
+ return kind is FontKind.Italic or FontKind.BoldItalic;
+ }
+
+ internal static FontKind SimplifyCompound(this FontKind kind)
+ {
+ return kind switch
+ {
+ FontKind.BoldItalic => FontKind.Bold,
+ _ => kind,
+ };
+ }
+
+
+ internal static FontKind RegularOr(this FontKind kind, FontKind other)
+ {
+ return kind switch
+ {
+ FontKind.Regular => FontKind.Regular,
+ _ => other,
+ };
+ }
+}
+
--- /dev/null
+using Content.Client.Resources;
+using JetBrains.Annotations;
+using Robust.Client.Graphics;
+using Robust.Client.ResourceManagement;
+
+namespace Content.Client.Stylesheets.Fonts;
+
+/// <summary>
+/// This class should have a base type. The whole font system is currently kind of bad and completely temporary.
+/// This class is just here because it does sort of work.
+/// TODO: fix (once engine support is added for font properties?)
+/// </summary>
+/// <param name="resCache"></param>
+/// <param name="variant"></param>
+[PublicAPI]
+public sealed class NotoFontFamilyStack(IResourceCache resCache, string variant = "")
+{
+ /// <summary>
+ /// The primary font path, with string substitution markers.
+ /// </summary>
+ /// <remarks>
+ /// If using the default GetFontPaths function, the substitutions are as follows:
+ /// 0 is the font kind.
+ /// 1 is the font kind with BoldItalic replaced with Bold when it occurs.
+ /// </remarks>
+ private string _fontPrimary = $"/Fonts/NotoSans{variant}/NotoSans{variant}-{{0}}.ttf";
+
+ /// <summary>
+ /// The symbols font path, with string substitution markers.
+ /// </summary>
+ /// <remarks>
+ /// If using the default GetFontPaths function, the substitutions are as follows:
+ /// 0 is the font kind.
+ /// 1 is the font kind with BoldItalic replaced with Bold when it occurs.
+ /// </remarks>
+ private string _fontSymbols = "/Fonts/NotoSans/NotoSansSymbols-{2}.ttf";
+
+ /// <summary>
+ /// The fallback font path, exactly. (no string substitutions.)
+ /// </summary>
+ private string[] _extras = new[] { "/Fonts/NotoSans/NotoSansSymbols2-Regular.ttf" };
+
+ public HashSet<FontKind> AvailableKinds = [FontKind.Regular, FontKind.Bold, FontKind.Italic, FontKind.BoldItalic];
+
+ /// <summary>
+ /// This should return the paths of every font in this stack given the abstract members.
+ /// </summary>
+ /// <param name="kind">Which font kind to use.</param>
+ /// <returns>An array of </returns>
+ private string[] GetFontPaths(FontKind kind)
+ {
+ if (!AvailableKinds.Contains(kind))
+ {
+ if (kind == FontKind.BoldItalic && AvailableKinds.Contains(FontKind.Bold))
+ {
+ kind = FontKind.Bold;
+ }
+ else
+ {
+ kind = FontKind.Regular;
+ }
+ }
+
+ var simpleKindStr = kind.SimplifyCompound().AsFileName();
+ var boldOrRegularStr = kind.RegularOr(FontKind.Bold).AsFileName();
+
+ var kindStr = kind.AsFileName();
+ var fontList = new List<string>()
+ {
+ string.Format(_fontPrimary, kindStr, simpleKindStr, boldOrRegularStr),
+ string.Format(_fontSymbols, kindStr, simpleKindStr, boldOrRegularStr),
+ };
+ fontList.AddRange(_extras);
+ return fontList.ToArray();
+ }
+
+ /// <summary>
+ /// Retrieves an in-style font, of the provided size and kind.
+ /// </summary>
+ /// <param name="size">Size of the font to provide.</param>
+ /// <param name="kind">Optional font kind. Defaults to Regular.</param>
+ /// <returns>A Font resource.</returns>
+ public Font GetFont(int size, FontKind kind = FontKind.Regular)
+ {
+ //ALDebugTools.AssertContains(AvailableKinds, kind);
+ var paths = GetFontPaths(kind);
+
+ return resCache.GetFont(paths, size);
+ }
+}
--- /dev/null
+namespace Content.Client.Stylesheets;
+
+public interface ISheetletConfig : IStyleResources
+{
+ // For access.
+}
--- /dev/null
+using System.Diagnostics.CodeAnalysis;
+using Robust.Client.Graphics;
+using Robust.Client.ResourceManagement;
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets;
+
+public interface IStyleResources
+{
+ /// <summary>
+ /// The file roots of the stylesheet, dictates where assets get read from for the given type of resource.
+ /// Roots will be checked in order for assets, avoid having a significant number of them.
+ /// </summary>
+ /// <remarks>
+ /// Must be a constant, changes to this after construction will not be reflected.
+ /// </remarks>
+ Dictionary<Type, ResPath[]> Roots { get; }
+
+ /// <summary>
+ /// Attempts to locate a resource within the stylesheet's roots.
+ /// </summary>
+ /// <param name="target">The relative path of the target resource.</param>
+ /// <param name="resource">The discovered/cached resource, if any.</param>
+ /// <typeparam name="T">Type of the resource to read.</typeparam>
+ /// <returns>Whether <paramref name="resource"/> is null.</returns>
+ bool TryGetResource<T>(ResPath target, [NotNullWhen(true)] out T? resource)
+ where T : BaseResource, new();
+
+ /// <summary>
+ /// Retrieves a resource, or throws.
+ /// </summary>
+ /// <param name="target">The relative path of the target resource.</param>
+ /// <typeparam name="T">Type of the resource to read.</typeparam>
+ /// <returns>The retrieved resource</returns>
+ /// <exception cref="MissingStyleResourceException">Thrown if the resource does not exist within the stylesheet's roots.</exception>
+ T GetResource<T>(ResPath target)
+ where T : BaseResource, new();
+
+ /// <summary>
+ /// Retrieves a resource, or falls back to the specified root. The resource should be present at the fallback
+ /// root, or else it throws
+ /// </summary>
+ /// <remarks>
+ /// This should be used to allow common sheetlets to be generic over multiple stylesheets without forcing other
+ /// styles to have the resource present, if your sheetlet is stylesheet-specific you should not use this.
+ /// </remarks>
+ /// <param name="target">The relative path of the target resource.</param>
+ /// <param name="fallbackRoot">The root that this resource will always exist at</param>
+ /// <typeparam name="T">Type of the resource to read.</typeparam>
+ /// <returns>The retrieved resource</returns>
+ /// <exception cref="ExpectedResourceException">Thrown if the resource does not exist in the fallback root.</exception>
+ T GetResourceOr<T>(ResPath target, ResPath fallbackRoot)
+ where T : BaseResource, new();
+
+ /// <summary>
+ /// Attempts to locate a texture within the stylesheet's roots.
+ /// </summary>
+ /// <param name="target">The relative path of the target resource.</param>
+ /// <param name="texture">The retrieved texture, if any.</param>
+ /// <returns>Whether <paramref name="texture"/> is null.</returns>
+ bool TryGetTexture(ResPath target, [NotNullWhen(true)] out Texture? texture);
+
+ /// <summary>
+ /// Retrieves a texture, or throws.
+ /// </summary>
+ /// <param name="target">The relative path of the target texture.</param>
+ /// <returns>The retrieved texture</returns>
+ /// <exception cref="MissingStyleResourceException">Thrown if the texture does not exist within the stylesheet's roots.</exception>
+ Texture GetTexture(ResPath target);
+
+ /// <summary>
+ /// Retrieves a texture, or falls back to the specified root. The resource should be present at the fallback
+ /// root, or else it throws
+ /// </summary>
+ /// <remarks>
+ /// This should be used to allow common sheetlets to be generic over multiple stylesheets without forcing other
+ /// styles to have the resource present, if your sheetlet is stylesheet-specific you should not use this.
+ /// </remarks>
+ /// <param name="target">The relative path of the target texture.</param>
+ /// <param name="fallbackRoot">The root that this resource will always exist at</param>
+ /// <returns>The retrieved texture</returns>
+ /// <exception cref="ExpectedResourceException">Thrown if the texture does not exist in the fallback root.</exception>
+ Texture GetTextureOr(ResPath target, ResPath fallbackRoot);
+}
+using System.Diagnostics.CodeAnalysis;
using Robust.Client.UserInterface;
-namespace Content.Client.Stylesheets
+namespace Content.Client.Stylesheets;
+
+public interface IStylesheetManager
{
- public interface IStylesheetManager
- {
- Stylesheet SheetNano { get; }
- Stylesheet SheetSpace { get; }
+ /// Nanotrasen styles: the default style! Use this for most UIs
+ Stylesheet SheetNanotrasen { get; }
+
+ ///
+ /// System styles: use this for any admin / debug menus, and any odds and ends (like the changelog for some reason)
+ ///
+ Stylesheet SheetSystem { get; }
+
+
+ [Obsolete("Update to use SheetNanotrasen instead")]
+ Stylesheet SheetNano { get; }
+
+ [Obsolete("Update to use SheetSystem instead")]
+ Stylesheet SheetSpace { get; }
+
+ /// get a stylesheet by name
+ public bool TryGetStylesheet(string name, [MaybeNullWhen(false)] out Stylesheet stylesheet);
+
+ void Initialize();
- void Initialize();
- }
+ ///
+ /// Sheetlets marked with CommonSheetlet that have not satisfied the type constraints of any stylesheet
+ ///
+ public HashSet<Type> UnusedSheetlets { get; }
}
--- /dev/null
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Content.Client.UserInterface.Controls;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.NTSheetlets;
+
+/// Not NTHeading because NanoHeading is the name of the element
+[CommonSheetlet]
+public sealed class NanoHeadingSheetlet : Sheetlet<NanotrasenStylesheet>
+{
+ public override StyleRule[] GetRules(NanotrasenStylesheet sheet, object config)
+ {
+ INanoHeadingConfig nanoHeadingCfg = sheet;
+
+ var nanoHeadingTex = sheet.GetTexture(nanoHeadingCfg.NanoHeadingPath);
+ var nanoHeadingBox = new StyleBoxTexture
+ {
+ Texture = nanoHeadingTex,
+ PatchMarginRight = 10,
+ PatchMarginTop = 10,
+ ContentMarginTopOverride = 2,
+ ContentMarginLeftOverride = 10,
+ PaddingTop = 4,
+ };
+ nanoHeadingBox.SetPatchMargin(StyleBox.Margin.Left | StyleBox.Margin.Bottom, 2);
+
+ return
+ [
+ E<NanoHeading>().ParentOf(E<PanelContainer>()).Panel(nanoHeadingBox),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.Colorspace;
+
+// ReSharper disable MemberCanBePrivate.Global
+
+namespace Content.Client.Stylesheets.Palette;
+
+/// <remarks>
+/// Don't be afraid to add a lot of fields here! This class is made for readability.
+/// </remarks>
+public record ColorPalette(
+ Color Base,
+
+ float LightnessShift,
+ float ChromaShift,
+
+ Color Element,
+ Color HoveredElement,
+ Color PressedElement,
+ Color DisabledElement,
+
+ Color Background,
+ Color BackgroundLight,
+ Color BackgroundDark,
+
+ Color Text,
+ Color TextDark
+)
+{
+ /// <summary>
+ /// Helper method for generating a ColorPalette from a specified base hex string, with the
+ /// option to override specific parts of the palette
+ /// </summary>
+ public static ColorPalette FromHexBase(
+ string hex,
+ float lightnessShift = 0.06f,
+ float chromaShift = 0.00f,
+ Color? element = null,
+ Color? background = null,
+ Color? text = null
+ )
+ {
+ var @base = Color.FromHex(hex);
+
+ element ??= Shift(@base, lightnessShift, chromaShift, -1); // Shift(@base, -1)
+ var hoveredElement = Shift(element.Value, lightnessShift, chromaShift, 1); // Shift(@base, 0)
+ var pressedElement = Shift(element.Value, lightnessShift, chromaShift, -1); // Shift(@base, -2)
+ var disabledElement = Shift(element.Value, lightnessShift, chromaShift, -2) // Shift(@base, -3)
+ .NudgeChroma(-chromaShift * 2);
+
+ background ??= Shift(@base, lightnessShift, chromaShift, -3); // Shift(@base, -3)
+ var backgroundLight = Shift(background.Value, lightnessShift, chromaShift, 1); // Shift(@base, -2)
+ var backgroundDark = Shift(background.Value, lightnessShift, chromaShift, -1); // Shift(@base, -4)
+
+ text ??= @base; // Shift(@base, 0)
+ var textDark = Shift(text.Value, lightnessShift, chromaShift, -1); // Shift(@base, -1)
+
+ return new ColorPalette(
+ Base: @base,
+
+ LightnessShift: lightnessShift,
+ ChromaShift: chromaShift,
+
+ Element: element.Value,
+ HoveredElement: hoveredElement,
+ PressedElement: pressedElement,
+ DisabledElement: disabledElement,
+
+ Background: background.Value,
+ BackgroundLight: backgroundLight,
+ BackgroundDark: backgroundDark,
+
+ Text: text.Value,
+ TextDark: textDark
+ );
+ }
+
+ private static Color Shift(Color from, float lightnessShift, float chromaShift, float factor)
+ {
+ return from.NudgeLightness(lightnessShift * factor).NudgeChroma(chromaShift * factor);
+ }
+}
--- /dev/null
+namespace Content.Client.Stylesheets.Palette;
+
+/// <summary>
+/// Stores all style palettes in one accessible location
+/// </summary>
+/// <remarks>
+/// Technically not limited to only colors, can store like, standard padding amounts, and font sizes, maybe?
+/// </remarks>
+public static class Palettes
+{
+ // muted tones
+ public static readonly ColorPalette Navy = ColorPalette.FromHexBase("#4f5376", lightnessShift: 0.05f, chromaShift: 0.0045f);
+ public static readonly ColorPalette Cyan = ColorPalette.FromHexBase("#42586a", lightnessShift: 0.05f, chromaShift: 0.0045f);
+ public static readonly ColorPalette Slate = ColorPalette.FromHexBase("#545562");
+ public static readonly ColorPalette Neutral = ColorPalette.FromHexBase("#555555");
+
+ // status tones
+ public static readonly ColorPalette Red = ColorPalette.FromHexBase("#b62124", chromaShift: 0.02f);
+ public static readonly ColorPalette Amber = ColorPalette.FromHexBase("#c18e36");
+ public static readonly ColorPalette Green = ColorPalette.FromHexBase("#3c854a");
+ public static readonly StatusPalette Status = new([Red.Base, Amber.Base, Green.Base]);
+
+ // highlight tones
+ public static readonly ColorPalette Gold = ColorPalette.FromHexBase("#a88b5e");
+ public static readonly ColorPalette Maroon = ColorPalette.FromHexBase("#9b2236");
+
+ // Intended to be used with `ModulateSelf` to darken / lighten something
+ public static readonly ColorPalette AlphaModulate = ColorPalette.FromHexBase("#ffffff");
+
+}
--- /dev/null
+using Content.Client.Stylesheets.Colorspace;
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets.Palette;
+
+public sealed class StatusPalette
+{
+ /// The status colors to blend between, these are equally spaced from 0 to 1 with 0 being StatusColors[0], and 1 being
+ /// StatusColors.Last()
+ ///
+ /// Traditionally, something like { Red, Yellow, Green }
+ public readonly Color[] StatusColors;
+
+ /// <code>StatusPalette.GetStatusColor(1.0f)</code>
+ public readonly Color Good;
+ /// <code>StatusPalette.GetStatusColor(0.75f)</code>
+ public readonly Color Okay;
+ /// <code>StatusPalette.GetStatusColor(0.5f)</code>
+ public readonly Color Warning;
+ /// <code>StatusPalette.GetStatusColor(0.25f)</code>
+ public readonly Color Bad;
+ /// <code>StatusPalette.GetStatusColor(0.0f)</code>
+ public readonly Color Critical;
+
+ public StatusPalette(Color[] statusColors)
+ {
+ StatusColors = statusColors;
+ Good = GetStatusColor(1.0f);
+ Okay = GetStatusColor(0.75f);
+ Warning = GetStatusColor(0.5f);
+ Bad = GetStatusColor(0.25f);
+ Critical = GetStatusColor(0.0f);
+ }
+
+ /// <param name="factor">The severity of this status from 0 to 1. Traditionally, 1 will be green and 0 red</param>
+ /// <returns>The color for this status, linearly Oklab blended between equal intervals of the colors in StatusColor</returns>
+ public Color GetStatusColor(float factor)
+ {
+ DebugTools.Assert(factor >= 0.0 && factor <= 1.0);
+ DebugTools.Assert(StatusColors.Length >= 1);
+
+ if (StatusColors.Length == 1)
+ return StatusColors[0];
+
+ var intervals = StatusColors.Length - 1;
+
+ var fromIdx = (int) Math.Floor(factor * intervals);
+ if (factor is 1.0f or 0.0f)
+ return StatusColors[fromIdx];
+
+ var from = StatusColors[fromIdx];
+ var to = StatusColors[fromIdx + 1];
+ var f = (factor - (float) fromIdx / intervals) * intervals;
+
+ return from.OkBlend(to, f);
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.Palette;
+
+namespace Content.Client.Stylesheets;
+
+public abstract partial class PalettedStylesheet
+{
+ public abstract ColorPalette PrimaryPalette { get; }
+ public abstract ColorPalette SecondaryPalette { get; }
+ public abstract ColorPalette PositivePalette { get; }
+ public abstract ColorPalette NegativePalette { get; }
+ public abstract ColorPalette HighlightPalette { get; }
+}
--- /dev/null
+using JetBrains.Annotations;
+
+namespace Content.Client.Stylesheets;
+
+/// <summary>
+/// The base class for all stylesheets, providing core functionality and helpers.
+/// </summary>
+[PublicAPI]
+public abstract partial class PalettedStylesheet : BaseStylesheet
+{
+ protected PalettedStylesheet(object config) : base(config)
+ {
+ }
+}
--- /dev/null
+using Robust.Client.ResourceManagement;
+using Robust.Client.UserInterface;
+
+namespace Content.Client.Stylesheets;
+
+public abstract class Sheetlet<T>
+{
+ [Dependency] protected readonly IResourceCache ResCache = default!;
+
+ protected Sheetlet()
+ {
+ IoCManager.InjectDependencies(this);
+ }
+
+ public abstract StyleRule[] GetRules(T sheet, object config);
+}
--- /dev/null
+using Content.Client.Stylesheets.Palette;
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets.SheetletConfigs;
+
+public interface IButtonConfig : ISheetletConfig
+{
+ public ResPath BaseButtonPath { get; }
+ public ResPath OpenLeftButtonPath { get; }
+ public ResPath OpenRightButtonPath { get; }
+ public ResPath OpenBothButtonPath { get; }
+ public ResPath SmallButtonPath { get; }
+ public ResPath RoundedButtonPath { get; }
+ public ResPath RoundedButtonBorderedPath { get; }
+
+ public ColorPalette ButtonPalette { get; }
+ public ColorPalette PositiveButtonPalette { get; }
+ public ColorPalette NegativeButtonPalette { get; }
+}
--- /dev/null
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets.SheetletConfigs;
+
+public interface ICheckboxConfig
+{
+ public ResPath CheckboxUncheckedPath { get; }
+ public ResPath CheckboxCheckedPath { get; }
+}
+
--- /dev/null
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets.SheetletConfigs;
+
+public interface IIconConfig : ISheetletConfig
+{
+ public ResPath HelpIconPath { get; }
+ public ResPath CrossIconPath { get; }
+ public ResPath InvertedTriangleIconPath { get; }
+
+
+}
--- /dev/null
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets.SheetletConfigs;
+
+public interface ILineEditConfig : ISheetletConfig
+{
+ public ResPath LineEditPath { get; }
+}
--- /dev/null
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets.SheetletConfigs;
+
+public interface INanoHeadingConfig : ISheetletConfig
+{
+ public ResPath NanoHeadingPath { get; }
+}
+
--- /dev/null
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets.SheetletConfigs;
+
+public interface IPanelConfig : ISheetletConfig
+{
+ public ResPath GeometricPanelBorderPath { get; }
+ public ResPath BlackPanelDarkThinBorderPath { get; }
+}
--- /dev/null
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets.SheetletConfigs;
+
+public interface IPlaceholderConfig : ISheetletConfig
+{
+ public ResPath PlaceholderPath { get; }
+}
+
--- /dev/null
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets.SheetletConfigs;
+
+public interface IRadialMenuConfig : ISheetletConfig
+{
+ public ResPath ButtonNormalPath { get; }
+ public ResPath ButtonHoverPath { get; }
+ public ResPath CloseNormalPath { get; }
+ public ResPath CloseHoverPath { get; }
+ public ResPath BackNormalPath { get; }
+ public ResPath BackHoverPath { get; }
+}
--- /dev/null
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets.SheetletConfigs;
+
+public interface ISliderConfig : ISheetletConfig
+{
+ public ResPath SliderFillPath { get; }
+ public ResPath SliderOutlinePath { get; }
+ public ResPath SliderGrabber { get; }
+}
--- /dev/null
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets.SheetletConfigs;
+
+public interface IStripebackConfig : ISheetletConfig
+{
+ public ResPath StripebackPath { get; }
+}
--- /dev/null
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets.SheetletConfigs;
+
+public interface ITabContainerConfig : ISheetletConfig
+{
+ public ResPath TabContainerPanelPath { get; }
+}
--- /dev/null
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets.SheetletConfigs;
+
+public interface ITooltipConfig : ISheetletConfig
+{
+ public ResPath TooltipBoxPath { get; }
+ public ResPath WhisperBoxPath { get; }
+}
--- /dev/null
+using Robust.Shared.Utility;
+
+namespace Content.Client.Stylesheets.SheetletConfigs;
+
+public interface IWindowConfig : ISheetletConfig
+{
+ public ResPath WindowHeaderTexturePath { get; }
+ public ResPath WindowHeaderAlertTexturePath { get; }
+ public ResPath WindowBackgroundPath { get; }
+ public ResPath WindowBackgroundBorderedPath { get; }
+ public ResPath TransparentWindowBackgroundBorderedPath { get; }
+}
--- /dev/null
+using System.Numerics;
+using Content.Client.Stylesheets.Palette;
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class ButtonSheetlet<T> : Sheetlet<T> where T : PalettedStylesheet, IButtonConfig, IIconConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ IButtonConfig buttonCfg = sheet;
+ IIconConfig iconCfg = sheet;
+
+ var crossTex = sheet.GetTextureOr(iconCfg.CrossIconPath, NanotrasenStylesheet.TextureRoot);
+
+ var rules = new List<StyleRule>
+ {
+ // Set textures for the kinds of buttons
+ CButton()
+ .Box(StyleBoxHelpers.BaseStyleBox(sheet)),
+ CButton()
+ .Class(StyleClass.ButtonOpenLeft)
+ .Box(StyleBoxHelpers.OpenLeftStyleBox(sheet)),
+ CButton()
+ .Class(StyleClass.ButtonOpenRight)
+ .Box(StyleBoxHelpers.OpenRightStyleBox(sheet)),
+ CButton()
+ .Class(StyleClass.ButtonOpenBoth)
+ .Box(StyleBoxHelpers.SquareStyleBox(sheet)),
+ CButton()
+ .Class(StyleClass.ButtonSquare)
+ .Box(StyleBoxHelpers.SquareStyleBox(sheet)),
+ CButton()
+ .Class(StyleClass.ButtonSmall)
+ .Box(StyleBoxHelpers.SmallStyleBox(sheet)),
+ CButton()
+ .Class(StyleClass.ButtonSmall)
+ .ParentOf(E<Label>())
+ .Font(sheet.BaseFont.GetFont(8)),
+ CButton().Class(StyleClass.ButtonBig).ParentOf(E<Label>()).Font(sheet.BaseFont.GetFont(16)),
+
+ // Cross Button (Red)
+ E<TextureButton>()
+ .Class(StyleClass.CrossButtonRed)
+ .Prop(TextureButton.StylePropertyTexture, crossTex),
+
+ // Ensure labels in buttons are aligned.
+ E<Label>()
+ // ReSharper disable once AccessToStaticMemberViaDerivedType
+ .Class(Button.StyleClassButton)
+ .AlignMode(Label.AlignMode.Center),
+
+ // Have disabled button's text be faded
+ CButton().PseudoDisabled().ParentOf(E<Label>()).FontColor(Color.FromHex("#E5E5E581")),
+ CButton().PseudoDisabled().ParentOf(E()).ParentOf(E<Label>()).FontColor(Color.FromHex("#E5E5E581")),
+ };
+ // Texture button modulation
+ MakeButtonRules<TextureButton>(rules, Palettes.AlphaModulate, null);
+ MakeButtonRules<TextureButton>(rules, sheet.NegativePalette, StyleClass.CrossButtonRed);
+
+ MakeButtonRules(rules, buttonCfg.ButtonPalette, null);
+ MakeButtonRules(rules, buttonCfg.PositiveButtonPalette, StyleClass.Positive);
+ MakeButtonRules(rules, buttonCfg.NegativeButtonPalette, StyleClass.Negative);
+
+ return rules.ToArray();
+ }
+
+ public static void MakeButtonRules<TC>(
+ List<StyleRule> rules,
+ ColorPalette palette,
+ string? styleclass)
+ where TC : Control
+ {
+ rules.AddRange([
+ E<TC>().MaybeClass(styleclass).PseudoNormal().Modulate(palette.Element),
+ E<TC>().MaybeClass(styleclass).PseudoHovered().Modulate(palette.HoveredElement),
+ E<TC>().MaybeClass(styleclass).PseudoPressed().Modulate(palette.PressedElement),
+ E<TC>().MaybeClass(styleclass).PseudoDisabled().Modulate(palette.DisabledElement),
+ ]);
+ }
+
+ public static void MakeButtonRules(
+ List<StyleRule> rules,
+ ColorPalette palette,
+ string? styleclass)
+ {
+ rules.AddRange([
+ E().MaybeClass(styleclass).PseudoNormal().Prop(Control.StylePropertyModulateSelf, palette.Element),
+ E().MaybeClass(styleclass).PseudoHovered().Prop(Control.StylePropertyModulateSelf, palette.HoveredElement),
+ E().MaybeClass(styleclass).PseudoPressed().Prop(Control.StylePropertyModulateSelf, palette.PressedElement),
+ E()
+ .MaybeClass(styleclass)
+ .PseudoDisabled()
+ .Prop(Control.StylePropertyModulateSelf, palette.DisabledElement),
+ ]);
+ }
+
+ private static MutableSelectorElement CButton()
+ {
+ return E<ContainerButton>().Class(ContainerButton.StyleClassButton);
+ }
+}
+
+// this is currently the only other "helper" type class, if any more crop up consider making a specific directory for them
+public static class StyleBoxHelpers
+{
+ // TODO: Figure out a nicer way to store/represent these hardcoded margins. This is icky.
+ public static StyleBoxTexture BaseStyleBox<T>(T sheet) where T : PalettedStylesheet, IButtonConfig
+ {
+ var baseBox = new StyleBoxTexture
+ {
+ Texture = sheet.GetTextureOr(sheet.BaseButtonPath, NanotrasenStylesheet.TextureRoot),
+ };
+ baseBox.SetPatchMargin(StyleBox.Margin.All, 10);
+ baseBox.SetPadding(StyleBox.Margin.All, 1);
+ baseBox.SetContentMarginOverride(StyleBox.Margin.Vertical, 2);
+ baseBox.SetContentMarginOverride(StyleBox.Margin.Horizontal, 14);
+ return baseBox;
+ }
+
+ public static StyleBoxTexture OpenLeftStyleBox<T>(T sheet) where T : PalettedStylesheet, IButtonConfig
+ {
+ var openLeftBox = new StyleBoxTexture(BaseStyleBox(sheet))
+ {
+ Texture = new AtlasTexture(sheet.GetTextureOr(sheet.OpenLeftButtonPath, NanotrasenStylesheet.TextureRoot),
+ UIBox2.FromDimensions(new Vector2(10, 0), new Vector2(14, 24))),
+ };
+ openLeftBox.SetPatchMargin(StyleBox.Margin.Left, 0);
+ openLeftBox.SetContentMarginOverride(StyleBox.Margin.Left, 8);
+ // openLeftBox.SetPadding(StyleBox.Margin.Left, 1);
+ return openLeftBox;
+ }
+
+ public static StyleBoxTexture OpenRightStyleBox<T>(T sheet) where T : PalettedStylesheet, IButtonConfig
+ {
+ var openRightBox = new StyleBoxTexture(BaseStyleBox(sheet))
+ {
+ Texture = new AtlasTexture(sheet.GetTextureOr(sheet.OpenRightButtonPath, NanotrasenStylesheet.TextureRoot),
+ UIBox2.FromDimensions(new Vector2(0, 0), new Vector2(14, 24))),
+ };
+ openRightBox.SetPatchMargin(StyleBox.Margin.Right, 0);
+ openRightBox.SetContentMarginOverride(StyleBox.Margin.Right, 8);
+ openRightBox.SetPadding(StyleBox.Margin.Right, 1);
+ return openRightBox;
+ }
+
+ public static StyleBoxTexture SquareStyleBox<T>(T sheet) where T : PalettedStylesheet, IButtonConfig
+ {
+ var openBothBox = new StyleBoxTexture(BaseStyleBox(sheet))
+ {
+ Texture = new AtlasTexture(sheet.GetTextureOr(sheet.OpenBothButtonPath, NanotrasenStylesheet.TextureRoot),
+ UIBox2.FromDimensions(new Vector2(10, 0), new Vector2(3, 24))),
+ };
+ openBothBox.SetPatchMargin(StyleBox.Margin.Horizontal, 0);
+ openBothBox.SetContentMarginOverride(StyleBox.Margin.Horizontal, 8);
+ openBothBox.SetPadding(StyleBox.Margin.Horizontal, 1);
+ return openBothBox;
+ }
+
+ public static StyleBoxTexture SmallStyleBox<T>(T sheet) where T : PalettedStylesheet, IButtonConfig
+ {
+ var smallBox = new StyleBoxTexture
+ {
+ Texture = sheet.GetTextureOr(sheet.SmallButtonPath, NanotrasenStylesheet.TextureRoot),
+ };
+ return smallBox;
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class CheckboxSheetlet<T> : Sheetlet<T> where T : PalettedStylesheet, ICheckboxConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ ICheckboxConfig checkboxCfg = sheet;
+
+ var uncheckedTex = sheet.GetTextureOr(checkboxCfg.CheckboxUncheckedPath, NanotrasenStylesheet.TextureRoot);
+ var checkedTex = sheet.GetTextureOr(checkboxCfg.CheckboxCheckedPath, NanotrasenStylesheet.TextureRoot);
+
+ return
+ [
+ E<TextureRect>()
+ .Class(CheckBox.StyleClassCheckBox)
+ .Prop(TextureRect.StylePropertyTexture, uncheckedTex),
+ E<TextureRect>()
+ .Class(CheckBox.StyleClassCheckBox)
+ .Class(CheckBox.StyleClassCheckBoxChecked)
+ .Prop(TextureRect.StylePropertyTexture, checkedTex),
+ E<BoxContainer>()
+ .Class(CheckBox.StyleClassCheckBox)
+ .Prop(BoxContainer.StylePropertySeparation, 10),
+ ];
+ }
+}
--- /dev/null
+using System.Numerics;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class DividersSheetlet : Sheetlet<PalettedStylesheet>
+{
+ public override StyleRule[] GetRules(PalettedStylesheet sheet, object config)
+ {
+ var boxHighDivider = new StyleBoxFlat
+ {
+ BackgroundColor = sheet.HighlightPalette.Base,
+ ContentMarginBottomOverride = 2,
+ ContentMarginLeftOverride = 2,
+ };
+
+ var boxLowDivider = new StyleBoxFlat(sheet.SecondaryPalette.TextDark);
+
+ // high divider and low divider styles are VERY inconsistent but its too much of a pain to change right now (also HighDivider has its own Control ???)
+ // i dont think theres a good resolution to this besides just deleting HighDivider. HighDivider is barely used but LowDivider is used everywhere.
+ return
+ [
+ E<PanelContainer>()
+ .Class(StyleClass.LowDivider)
+ .Panel(boxLowDivider)
+ .MinSize(new Vector2(2, 2)),
+ E<PanelContainer>().Class(StyleClass.HighDivider).Panel(boxHighDivider),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.UserInterface.Controls.FancyTree;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class FancyTreeSheetlet : Sheetlet<PalettedStylesheet>
+{
+ public override StyleRule[] GetRules(PalettedStylesheet sheet, object config)
+ {
+ return
+ [
+ E<ContainerButton>()
+ .Identifier(TreeItem.StyleIdentifierTreeButton)
+ .Class(TreeItem.StyleClassEvenRow)
+ .Prop(ContainerButton.StylePropertyStyleBox, new StyleBoxFlat(sheet.SecondaryPalette.BackgroundLight)),
+ E<ContainerButton>()
+ .Identifier(TreeItem.StyleIdentifierTreeButton)
+ .Class(TreeItem.StyleClassOddRow)
+ .Prop(ContainerButton.StylePropertyStyleBox, new StyleBoxFlat(sheet.SecondaryPalette.Background)),
+
+ E<ContainerButton>()
+ .Identifier(TreeItem.StyleIdentifierTreeButton)
+ .Class(TreeItem.StyleClassSelected)
+ .Prop(ContainerButton.StylePropertyStyleBox, new StyleBoxFlat(sheet.PrimaryPalette.Element)),
+
+ E<ContainerButton>()
+ .Identifier(TreeItem.StyleIdentifierTreeButton)
+ .Pseudo(ContainerButton.StylePseudoClassHover)
+ .Prop(ContainerButton.StylePropertyStyleBox, new StyleBoxFlat(sheet.PrimaryPalette.HoveredElement)),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.UserInterface.Controls;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class HLineSheetlet : Sheetlet<PalettedStylesheet>
+{
+ public override StyleRule[] GetRules(PalettedStylesheet sheet, object config)
+ {
+ return
+ [
+ E<HLine>()
+ .Class(StyleClass.Positive)
+ .Panel(new StyleBoxFlat(sheet.PositivePalette.Text)),
+ E<HLine>()
+ .Class(StyleClass.Highlight)
+ .Panel(new StyleBoxFlat(sheet.HighlightPalette.Text)),
+ E<HLine>()
+ .Class(StyleClass.Negative)
+ .Panel(new StyleBoxFlat(sheet.NegativePalette.Text)),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.Resources;
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Content.Client.UserInterface.Systems.Actions.Controls;
+using Content.Client.UserInterface.Systems.Actions.Windows;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets.Hud;
+
+[CommonSheetlet]
+public sealed class ActionSheetlet<T> : Sheetlet<T> where T: PalettedStylesheet, IPanelConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ IPanelConfig panelCfg = sheet;
+
+ // TODO: absolute texture access
+ var handSlotHighlightTex = ResCache.GetTexture("/Textures/Interface/Inventory/hand_slot_highlight.png");
+ var handSlotHighlight = new StyleBoxTexture
+ {
+ Texture = handSlotHighlightTex,
+ };
+ handSlotHighlight.SetPatchMargin(StyleBox.Margin.All, 2);
+
+ var actionSearchBoxTex =
+ sheet.GetTextureOr(panelCfg.BlackPanelDarkThinBorderPath, NanotrasenStylesheet.TextureRoot);
+ var actionSearchBox = new StyleBoxTexture
+ {
+ Texture = actionSearchBoxTex,
+ };
+ actionSearchBox.SetPatchMargin(StyleBox.Margin.All, 3);
+ actionSearchBox.SetContentMarginOverride(StyleBox.Margin.Horizontal, 5);
+
+ return
+ [
+ E<PanelContainer>().Class(ActionButton.StyleClassActionHighlightRect).Panel(handSlotHighlight),
+ E<LineEdit>().Class(ActionsWindow.StyleClassActionSearchBox).Box(actionSearchBox),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.UserInterface.Screens;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets.Hud;
+
+[CommonSheetlet]
+public sealed class ChatGameScreenSheetlet : Sheetlet<PalettedStylesheet>
+{
+ public override StyleRule[] GetRules(PalettedStylesheet sheet, object config)
+ {
+ return
+ [
+ E()
+ .Class(SeparatedChatGameScreen.StyleClassChatContainer)
+ .Panel(new StyleBoxFlat(sheet.SecondaryPalette.Background)),
+ E<OutputPanel>()
+ .Class(SeparatedChatGameScreen.StyleClassChatOutput)
+ .Panel(new StyleBoxFlat(sheet.SecondaryPalette.BackgroundDark)),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Content.Client.UserInterface.Systems.Chat.Controls;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets.Hud;
+
+[CommonSheetlet]
+public sealed class ChatSheetlet<T> : Sheetlet<T> where T: PalettedStylesheet, IButtonConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ IButtonConfig btnCfg = sheet;
+
+ var chatColor = sheet.SecondaryPalette.Background.WithAlpha(221.0f / 255.0f);
+ var chatBg = new StyleBoxFlat(chatColor);
+
+ var chatChannelButtonTex =
+ sheet.GetTextureOr(btnCfg.RoundedButtonBorderedPath, NanotrasenStylesheet.TextureRoot);
+ var chatChannelButton = new StyleBoxTexture
+ {
+ Texture = chatChannelButtonTex,
+ };
+ chatChannelButton.SetPatchMargin(StyleBox.Margin.All, 5);
+ chatChannelButton.SetPadding(StyleBox.Margin.All, 2);
+
+ var chatFilterButtonTex =
+ sheet.GetTextureOr(btnCfg.RoundedButtonBorderedPath, NanotrasenStylesheet.TextureRoot);
+ var chatFilterButton = new StyleBoxTexture
+ {
+ Texture = chatFilterButtonTex,
+ };
+ chatFilterButton.SetPatchMargin(StyleBox.Margin.All, 5);
+ chatFilterButton.SetPadding(StyleBox.Margin.All, 2);
+
+ return
+ [
+ E<PanelContainer>()
+ .Class(ChatInputBox.StyleClassChatPanel)
+ .Panel(chatBg),
+ E<LineEdit>()
+ .Class(ChatInputBox.StyleClassChatLineEdit)
+ .Prop(LineEdit.StylePropertyStyleBox, new StyleBoxEmpty()),
+ E<Button>().Class(ChatInputBox.StyleClassChatFilterOptionButton).Box(chatChannelButton),
+ E<ContainerButton>().Class(ChatInputBox.StyleClassChatFilterOptionButton).Box(chatFilterButton),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.ContextMenu.UI;
+using Content.Client.Resources;
+using Content.Client.Stylesheets.Fonts;
+using Content.Client.Stylesheets.Palette;
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Content.Client.Verbs.UI;
+using Content.Shared.Verbs;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets.Hud;
+
+[CommonSheetlet]
+public sealed class ContextMenuSheetlet<T> : Sheetlet<T>
+ where T : PalettedStylesheet, IWindowConfig, IButtonConfig, IIconConfig
+{
+ // TODO: make this not hardcoded (I am too scared to change the context menu colors)
+ private static readonly ColorPalette ContextButtonPalette = ColorPalette.FromHexBase("#000000") with
+ {
+ HoveredElement = Color.DarkSlateGray,
+ Element = Color.FromHex("#1119"),
+ PressedElement = Color.LightSlateGray,
+ };
+
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ IWindowConfig windowCfg = sheet;
+
+ var borderedWindowBackground = new StyleBoxTexture
+ {
+ Texture = sheet.GetTextureOr(windowCfg.WindowBackgroundBorderedPath, NanotrasenStylesheet.TextureRoot),
+ };
+ borderedWindowBackground.SetPatchMargin(StyleBox.Margin.All, ContextMenuElement.ElementMargin);
+ var buttonContext = new StyleBoxTexture { Texture = Texture.White };
+ var contextMenuExpansionTexture = ResCache.GetTexture("/Textures/Interface/VerbIcons/group.svg.192dpi.png");
+ var verbMenuConfirmationTexture = ResCache.GetTexture("/Textures/Interface/VerbIcons/group.svg.192dpi.png");
+
+ var rules = new List<StyleRule>
+ {
+ // Context Menu window
+ E<PanelContainer>()
+ .Class(ContextMenuPopup.StyleClassContextMenuPopup)
+ .Panel(borderedWindowBackground),
+
+ // Context menu buttons
+ E<ContextMenuElement>()
+ .Class(ContextMenuElement.StyleClassContextMenuButton)
+ .Prop(ContainerButton.StylePropertyStyleBox, buttonContext),
+
+ // Context Menu Labels
+ E<RichTextLabel>()
+ .Class(InteractionVerb.DefaultTextStyleClass)
+ .Font(sheet.BaseFont.GetFont(12, FontKind.BoldItalic)),
+ E<RichTextLabel>()
+ .Class(ActivationVerb.DefaultTextStyleClass)
+ .Font(sheet.BaseFont.GetFont(12, FontKind.Bold)),
+ E<RichTextLabel>()
+ .Class(AlternativeVerb.DefaultTextStyleClass)
+ .Font(sheet.BaseFont.GetFont(12, FontKind.Italic)),
+ E<RichTextLabel>()
+ .Class(Verb.DefaultTextStyleClass)
+ .Font(sheet.BaseFont.GetFont(12)),
+ E<TextureRect>()
+ .Class(ContextMenuElement.StyleClassContextMenuExpansionTexture)
+ .Prop(TextureRect.StylePropertyTexture, contextMenuExpansionTexture),
+ E<TextureRect>()
+ .Class(VerbMenuElement.StyleClassVerbMenuConfirmationTexture)
+ .Prop(TextureRect.StylePropertyTexture, verbMenuConfirmationTexture),
+
+ // Context menu confirm buttons
+ E<ContextMenuElement>()
+ .Class(ConfirmationMenuElement.StyleClassConfirmationContextMenuButton)
+ .Prop(ContainerButton.StylePropertyStyleBox, buttonContext),
+ };
+
+ ButtonSheetlet<T>.MakeButtonRules<ContextMenuElement>(rules,
+ ContextButtonPalette,
+ ContextMenuElement.StyleClassContextMenuButton);
+ ButtonSheetlet<T>.MakeButtonRules<ContextMenuElement>(rules,
+ sheet.NegativePalette,
+ ConfirmationMenuElement.StyleClassConfirmationContextMenuButton);
+
+ return rules.ToArray();
+ }
+}
--- /dev/null
+using Content.Client.Examine;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets.Hud;
+
+[CommonSheetlet]
+public sealed class ExamineButtonSheetlet : Sheetlet<PalettedStylesheet>
+{
+ // Examine button colors
+ // TODO: FIX!!
+ private static readonly Color ExamineButtonColorContext = Color.Transparent;
+ private static readonly Color ExamineButtonColorContextHover = Color.DarkSlateGray;
+ private static readonly Color ExamineButtonColorContextPressed = Color.LightSlateGray;
+ private static readonly Color ExamineButtonColorContextDisabled = Color.FromHex("#5A5A5A");
+
+ public override StyleRule[] GetRules(PalettedStylesheet sheet, object config)
+ {
+ var buttonContext = new StyleBoxTexture { Texture = Texture.White };
+
+ return
+ [
+ E<ExamineButton>()
+ .Class(ExamineButton.StyleClassExamineButton)
+ .Prop(ContainerButton.StylePropertyStyleBox, buttonContext),
+ E<ExamineButton>()
+ .Class(ExamineButton.StyleClassExamineButton)
+ .PseudoNormal()
+ .Prop(Control.StylePropertyModulateSelf, ExamineButtonColorContext),
+ E<ExamineButton>()
+ .Class(ExamineButton.StyleClassExamineButton)
+ .PseudoHovered()
+ .Prop(Control.StylePropertyModulateSelf, ExamineButtonColorContextHover),
+ E<ExamineButton>()
+ .Class(ExamineButton.StyleClassExamineButton)
+ .PseudoPressed()
+ .Prop(Control.StylePropertyModulateSelf, ExamineButtonColorContextPressed),
+ E<ExamineButton>()
+ .Class(ExamineButton.StyleClassExamineButton)
+ .PseudoDisabled()
+ .Prop(Control.StylePropertyModulateSelf, ExamineButtonColorContextDisabled),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.Fonts;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets.Hud;
+
+[CommonSheetlet]
+public sealed class ItemStatusSheetlet : Sheetlet<PalettedStylesheet>
+{
+ public override StyleRule[] GetRules(PalettedStylesheet sheet, object config)
+ {
+ return
+ [
+ E()
+ .Class(StyleClass.ItemStatus)
+ .Prop("font", sheet.BaseFont.GetFont(10)),
+
+ E()
+ .Class(StyleClass.ItemStatusNotHeld)
+ .Prop("font", sheet.BaseFont.GetFont(10, FontKind.Italic))
+ .Prop("font-color", Color.Gray),
+
+ E<RichTextLabel>()
+ .Class(StyleClass.ItemStatus)
+ .Prop(nameof(RichTextLabel.LineHeightScale), 0.7f)
+ .Prop(nameof(Control.Margin), new Thickness(0, 0, 0, -6)),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.Examine;
+using Content.Client.Stylesheets.Fonts;
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.CustomControls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets.Hud;
+
+[CommonSheetlet]
+public sealed class TooltipSheetlet<T> : Sheetlet<T> where T: PalettedStylesheet, ITooltipConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ ITooltipConfig tooltipCfg = sheet;
+
+ var tooltipBox = sheet.GetTextureOr(tooltipCfg.TooltipBoxPath, NanotrasenStylesheet.TextureRoot)
+ .IntoPatch(StyleBox.Margin.All, 2);
+ tooltipBox.SetContentMarginOverride(StyleBox.Margin.Horizontal, 7);
+
+ var whisperBox = sheet.GetTextureOr(tooltipCfg.WhisperBoxPath, NanotrasenStylesheet.TextureRoot)
+ .IntoPatch(StyleBox.Margin.All, 2);
+ whisperBox.SetContentMarginOverride(StyleBox.Margin.Horizontal, 7);
+
+ return
+ [
+ E<PanelContainer>()
+ .Class(StyleClass.TooltipPanel)
+ .Modulate(Color.Gray.WithAlpha(0.9f)) // TODO: you know the drill by now
+ .Panel(tooltipBox),
+ E<RichTextLabel>()
+ .Class(StyleClass.TooltipTitle)
+ .Font(sheet.BaseFont.GetFont(14, FontKind.Bold)),
+ E<RichTextLabel>()
+ .Class(StyleClass.TooltipDesc)
+ .Font(sheet.BaseFont.GetFont(12)),
+
+ E<Tooltip>()
+ // ReSharper disable once AccessToStaticMemberViaDerivedType
+ .Prop(Tooltip.StylePropertyPanel, tooltipBox),
+ E<PanelContainer>()
+ .Class(ExamineSystem.StyleClassEntityTooltip)
+ .Panel(tooltipBox),
+ E<PanelContainer>()
+ .Class("speechBox", "sayBox")
+ .Panel(tooltipBox),
+ E<PanelContainer>()
+ .Class("speechBox", "whisperBox")
+ .Panel(whisperBox),
+
+ E<PanelContainer>()
+ .Class("speechBox", "whisperBox")
+ .ParentOf(E<RichTextLabel>().Class("bubbleContent"))
+ .Prop(Label.StylePropertyFont, sheet.BaseFont.GetFont(12, FontKind.Italic)),
+ E<PanelContainer>()
+ .Class("speechBox", "emoteBox")
+ .ParentOf(E<RichTextLabel>().Class("bubbleContent"))
+ .Prop(Label.StylePropertyFont, sheet.BaseFont.GetFont(12, FontKind.Italic)),
+ ];
+ }
+}
--- /dev/null
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class ItemListSheetlet : Sheetlet<PalettedStylesheet>
+{
+ private static StyleBoxFlat Box(Color c)
+ {
+ return new StyleBoxFlat(c)
+ // TODO: dont hardcode these maybe
+ {
+ ContentMarginLeftOverride = 4,
+ ContentMarginTopOverride = 2,
+ ContentMarginRightOverride = 4,
+ ContentMarginBottomOverride = 2,
+ };
+ }
+
+ public override StyleRule[] GetRules(PalettedStylesheet sheet, object config)
+ {
+ var boxBackground = new StyleBoxFlat { BackgroundColor = sheet.PrimaryPalette.Background };
+ var boxItemBackground = Box(sheet.PrimaryPalette.Background);
+ var boxSelected = Box(sheet.PrimaryPalette.Element);
+ var boxDisabled = Box(sheet.PrimaryPalette.BackgroundDark);
+
+ return
+ [
+ E<ItemList>()
+ .Prop(ItemList.StylePropertyBackground, boxBackground)
+ .Prop(ItemList.StylePropertyItemBackground, boxItemBackground)
+ .Prop(ItemList.StylePropertyDisabledItemBackground, boxDisabled)
+ .Prop(ItemList.StylePropertySelectedItemBackground, boxSelected),
+
+ // these styles seem to be unused now
+ // E<ItemList>().Class("transparentItemList")
+ // .Prop(ItemList.StylePropertyBackground, boxTransparent)
+ // .Prop(ItemList.StylePropertyItemBackground, boxTransparent)
+ // .Prop(ItemList.StylePropertyDisabledItemBackground, boxDisabled)
+ // .Prop(ItemList.StylePropertySelectedItemBackground, boxItemBackground),
+ //
+ // E<ItemList>().Class("transparentBackgroundItemList")
+ // .Prop(ItemList.StylePropertyBackground, boxTransparent)
+ // .Prop(ItemList.StylePropertyItemBackground, boxBackground)
+ // .Prop(ItemList.StylePropertyDisabledItemBackground, boxItemBackground)
+ // .Prop(ItemList.StylePropertySelectedItemBackground, boxSelected),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.Fonts;
+using Content.Client.Stylesheets.Palette;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class LabelSheetlet : Sheetlet<PalettedStylesheet>
+{
+ public override StyleRule[] GetRules(PalettedStylesheet sheet, object config)
+ {
+ return
+ [
+ E<Label>()
+ .Class(StyleClass.LabelHeading)
+ .Font(sheet.BaseFont.GetFont(16, FontKind.Bold))
+ .FontColor(sheet.HighlightPalette.Text),
+ E<Label>()
+ .Class(StyleClass.LabelHeadingBigger)
+ .Font(sheet.BaseFont.GetFont(20, FontKind.Bold))
+ .FontColor(sheet.HighlightPalette.Text),
+ E<Label>()
+ .Class(StyleClass.LabelSubText)
+ .Font(sheet.BaseFont.GetFont(10))
+ .FontColor(Color.DarkGray),
+ E<Label>()
+ .Class(StyleClass.LabelKeyText)
+ .Font(sheet.BaseFont.GetFont(12, FontKind.Bold))
+ .FontColor(sheet.HighlightPalette.Text),
+ E<Label>()
+ .Class(StyleClass.LabelWeak)
+ .FontColor(Color.DarkGray), // TODO: you know the drill by now
+
+ E<Label>()
+ .Class(StyleClass.Positive)
+ .FontColor(sheet.PositivePalette.Text),
+ E<Label>()
+ .Class(StyleClass.Negative)
+ .FontColor(sheet.NegativePalette.Text),
+ E<Label>()
+ .Class(StyleClass.Highlight)
+ .FontColor(sheet.HighlightPalette.Text),
+
+ E<Label>()
+ .Class(StyleClass.StatusGood)
+ .FontColor(Palettes.Status.Good),
+ E<Label>()
+ .Class(StyleClass.StatusOkay)
+ .FontColor(Palettes.Status.Okay),
+ E<Label>()
+ .Class(StyleClass.StatusWarning)
+ .FontColor(Palettes.Status.Warning),
+ E<Label>()
+ .Class(StyleClass.StatusBad)
+ .FontColor(Palettes.Status.Bad),
+ E<Label>()
+ .Class(StyleClass.StatusCritical)
+ .FontColor(Palettes.Status.Critical),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class LineEditSheetlet<T> : Sheetlet<T> where T : PalettedStylesheet, ILineEditConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ ILineEditConfig lineEditCfg = sheet;
+
+ var lineEditStylebox = sheet.GetTextureOr(lineEditCfg.LineEditPath, NanotrasenStylesheet.TextureRoot)
+ .IntoPatch(StyleBox.Margin.All, 3);
+ lineEditStylebox.SetContentMarginOverride(StyleBox.Margin.Horizontal, 5);
+
+ return
+ [
+ E<LineEdit>()
+ .Prop(LineEdit.StylePropertyStyleBox, lineEditStylebox),
+ // TODO: Hardcoded colors bad, kill.
+ E<LineEdit>()
+ .Class(LineEdit.StyleClassLineEditNotEditable)
+ .Prop("font-color", new Color(192, 192, 192)),
+ E<LineEdit>()
+ .Pseudo(LineEdit.StylePseudoClassPlaceholder)
+ .Prop("font-color", Color.Gray),
+ E<TextEdit>()
+ .Pseudo(TextEdit.StylePseudoClassPlaceholder)
+ .Prop("font-color", Color.Gray),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.UserInterface.Controls;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class ListContainerSheetlet<T> : Sheetlet<T> where T : PalettedStylesheet, IButtonConfig, IIconConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ IButtonConfig buttonCfg = sheet;
+
+ var box = new StyleBoxFlat() { BackgroundColor = Color.White };
+
+ var rules = new List<StyleRule>(
+ [
+ E<ContainerButton>()
+ .Class(ListContainer.StyleClassListContainerButton)
+ .Box(box),
+ ]);
+ ButtonSheetlet<T>.MakeButtonRules<ContainerButton>(rules,
+ buttonCfg.ButtonPalette,
+ ListContainer.StyleClassListContainerButton);
+
+ return rules.ToArray();
+ }
+}
--- /dev/null
+using System.Numerics;
+using Content.Client.Stylesheets.Fonts;
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Content.Client.UserInterface.Controls;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class MenuButtonSheetlet<T> : Sheetlet<T> where T : PalettedStylesheet, IButtonConfig, IIconConfig
+{
+ private static MutableSelectorElement CButton()
+ {
+ return E<MenuButton>();
+ }
+
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ IButtonConfig cfg = sheet;
+
+ var buttonTex = sheet.GetTextureOr(cfg.BaseButtonPath, NanotrasenStylesheet.TextureRoot);
+ var topButtonBase = new StyleBoxTexture
+ {
+ Texture = buttonTex,
+ };
+ topButtonBase.SetPatchMargin(StyleBox.Margin.All, 10);
+ topButtonBase.SetPadding(StyleBox.Margin.All, 0);
+ topButtonBase.SetContentMarginOverride(StyleBox.Margin.All, 0);
+
+ var topButtonOpenRight = new StyleBoxTexture(topButtonBase)
+ {
+ Texture = new AtlasTexture(buttonTex, UIBox2.FromDimensions(new Vector2(0, 0), new Vector2(14, 24))),
+ };
+ topButtonOpenRight.SetPatchMargin(StyleBox.Margin.Right, 0);
+
+ var topButtonOpenLeft = new StyleBoxTexture(topButtonBase)
+ {
+ Texture = new AtlasTexture(buttonTex, UIBox2.FromDimensions(new Vector2(10, 0), new Vector2(14, 24))),
+ };
+ topButtonOpenLeft.SetPatchMargin(StyleBox.Margin.Left, 0);
+
+ var topButtonSquare = new StyleBoxTexture(topButtonBase)
+ {
+ Texture = new AtlasTexture(buttonTex, UIBox2.FromDimensions(new Vector2(10, 0), new Vector2(3, 24))),
+ };
+ topButtonSquare.SetPatchMargin(StyleBox.Margin.Horizontal, 0);
+
+ var rules = new List<StyleRule>
+ {
+ CButton().Class(StyleClass.ButtonSquare).Box(topButtonSquare),
+ CButton().Class(StyleClass.ButtonOpenLeft).Box(topButtonOpenLeft),
+ CButton().Class(StyleClass.ButtonOpenRight).Box(topButtonOpenRight),
+ CButton().Box(StyleBoxHelpers.BaseStyleBox(sheet)),
+ CButton()
+ .Class(StyleClass.ButtonOpenLeft)
+ .Prop(ContainerButton.StylePropertyStyleBox, StyleBoxHelpers.OpenLeftStyleBox(sheet)),
+ CButton()
+ .Class(StyleClass.ButtonOpenRight)
+ .Prop(ContainerButton.StylePropertyStyleBox, StyleBoxHelpers.OpenRightStyleBox(sheet)),
+ CButton()
+ .Class(StyleClass.ButtonOpenBoth)
+ .Prop(ContainerButton.StylePropertyStyleBox, StyleBoxHelpers.SquareStyleBox(sheet)),
+ CButton()
+ .Class(StyleClass.ButtonSquare)
+ .Prop(ContainerButton.StylePropertyStyleBox, StyleBoxHelpers.SquareStyleBox(sheet)),
+ E<Label>()
+ .Class(MenuButton.StyleClassLabelTopButton)
+ .Prop(Label.StylePropertyFont, sheet.BaseFont.GetFont(14, FontKind.Bold)),
+ // new StyleProperty(Label.StylePropertyFont, notoSansDisplayBold14),
+ };
+
+ ButtonSheetlet<T>.MakeButtonRules<MenuButton>(rules, cfg.ButtonPalette, null);
+
+ return rules.ToArray();
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class OptionButtonSheetlet<T> : Sheetlet<T> where T : PalettedStylesheet, IIconConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ IIconConfig iconCfg = sheet;
+
+ var invertedTriangleTex =
+ sheet.GetTextureOr(iconCfg.InvertedTriangleIconPath, NanotrasenStylesheet.TextureRoot);
+
+ return
+ [
+ E<TextureRect>()
+ .Class(OptionButton.StyleClassOptionTriangle)
+ .Prop(TextureRect.StylePropertyTexture, invertedTriangleTex),
+ E<Label>().Class(OptionButton.StyleClassOptionButton).AlignMode(Label.AlignMode.Center),
+ E<PanelContainer>()
+ .Class(OptionButton.StyleClassOptionsBackground)
+ .Panel(new StyleBoxFlat(sheet.PrimaryPalette.Background)),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.SheetletConfigs;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class PanelSheetlet<T> : Sheetlet<T> where T : PalettedStylesheet, IButtonConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ IButtonConfig buttonCfg = sheet;
+
+ var boxLight = new StyleBoxFlat()
+ {
+ BackgroundColor = sheet.SecondaryPalette.BackgroundLight,
+ };
+ var boxDark = new StyleBoxFlat()
+ {
+ BackgroundColor = sheet.SecondaryPalette.BackgroundDark,
+ };
+ var boxPositive = new StyleBoxFlat { BackgroundColor = sheet.PositivePalette.Background };
+ var boxNegative = new StyleBoxFlat { BackgroundColor = sheet.NegativePalette.Background };
+ var boxHighlight = new StyleBoxFlat { BackgroundColor = sheet.HighlightPalette.Background };
+
+ return
+ [
+ E<PanelContainer>().Class(StyleClass.PanelLight).Panel(boxLight),
+ E<PanelContainer>().Class(StyleClass.PanelDark).Panel(boxDark),
+
+ E<PanelContainer>().Class(StyleClass.Positive).Panel(boxPositive),
+ E<PanelContainer>().Class(StyleClass.Negative).Panel(boxNegative),
+ E<PanelContainer>().Class(StyleClass.Highlight).Panel(boxHighlight),
+
+ // TODO: this should probably be cleaned up but too many UIs rely on this hardcoded color so I'm scared to touch it
+ E<PanelContainer>()
+ .Class("BackgroundDark")
+ .Prop(PanelContainer.StylePropertyPanel, new StyleBoxFlat(Color.FromHex("#25252A"))),
+
+ // panels that have the same corner bezels as buttons
+ E()
+ .Class(StyleClass.BackgroundPanel)
+ .Prop(PanelContainer.StylePropertyPanel, StyleBoxHelpers.BaseStyleBox(sheet))
+ .Modulate(sheet.SecondaryPalette.Background),
+ E()
+ .Class(StyleClass.BackgroundPanelOpenLeft)
+ .Prop(PanelContainer.StylePropertyPanel, StyleBoxHelpers.OpenLeftStyleBox(sheet))
+ .Modulate(sheet.SecondaryPalette.Background),
+ E()
+ .Class(StyleClass.BackgroundPanelOpenRight)
+ .Prop(PanelContainer.StylePropertyPanel, StyleBoxHelpers.OpenRightStyleBox(sheet))
+ .Modulate(sheet.SecondaryPalette.Background),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Content.Client.UserInterface.Controls;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class PlaceholderSheetlet<T> : Sheetlet<T> where T: PalettedStylesheet, IPlaceholderConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ IPlaceholderConfig placeholderCfg = sheet;
+
+ var placeholderBox = sheet.GetTextureOr(placeholderCfg.PlaceholderPath, NanotrasenStylesheet.TextureRoot)
+ .IntoPatch(StyleBox.Margin.All, 19);
+ placeholderBox.SetExpandMargin(StyleBox.Margin.All, -5);
+ placeholderBox.Mode = StyleBoxTexture.StretchMode.Tile;
+
+ return
+ [
+ E<Placeholder>()
+ // ReSharper disable once AccessToStaticMemberViaDerivedType
+ .Prop(Placeholder.StylePropertyPanel, placeholderBox),
+ E<Label>()
+ .Class(Placeholder.StyleClassPlaceholderText)
+ .Font(sheet.BaseFont.GetFont(16))
+ .FontColor(new Color(103, 103, 103, 128)), // TODO: fix hardcoded color
+ ];
+ }
+}
--- /dev/null
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class ProgressBarSheetlet : Sheetlet<PalettedStylesheet>
+{
+ public override StyleRule[] GetRules(PalettedStylesheet sheet, object config)
+ {
+ // TODO: 1) hardcoded colors, 2) yuck
+ var progressBarBackground = new StyleBoxFlat
+ {
+ BackgroundColor = new Color(0.25f, 0.25f, 0.25f),
+ };
+ progressBarBackground.SetContentMarginOverride(StyleBox.Margin.Vertical, 14.5f);
+ var progressBarForeground = new StyleBoxFlat
+ {
+ BackgroundColor = new Color(0.25f, 0.50f, 0.25f),
+ };
+ progressBarForeground.SetContentMarginOverride(StyleBox.Margin.Vertical, 14.5f);
+
+ return
+ [
+ E<ProgressBar>()
+ .Prop(ProgressBar.StylePropertyBackground, progressBarBackground)
+ .Prop(ProgressBar.StylePropertyForeground, progressBarForeground),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class RadialMenuSheetlet<T> : Sheetlet<T> where T: PalettedStylesheet, IRadialMenuConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ IRadialMenuConfig radialCfg = sheet;
+
+ var btnNormalTex = sheet.GetTextureOr(radialCfg.ButtonNormalPath, NanotrasenStylesheet.TextureRoot);
+ var btnHoverTex = sheet.GetTextureOr(radialCfg.ButtonHoverPath, NanotrasenStylesheet.TextureRoot);
+ var closeNormalTex = sheet.GetTextureOr(radialCfg.CloseNormalPath, NanotrasenStylesheet.TextureRoot);
+ var closeHoverTex = sheet.GetTextureOr(radialCfg.CloseHoverPath, NanotrasenStylesheet.TextureRoot);
+ var backNormalTex = sheet.GetTextureOr(radialCfg.BackNormalPath, NanotrasenStylesheet.TextureRoot);
+ var backHoverTex = sheet.GetTextureOr(radialCfg.BackHoverPath, NanotrasenStylesheet.TextureRoot);
+
+ return
+ [
+ // TODO: UNHARDCODE
+ E<TextureButton>()
+ .Class("RadialMenuButton")
+ .Prop(TextureButton.StylePropertyTexture, btnNormalTex),
+ E<TextureButton>()
+ .Class("RadialMenuButton")
+ .Pseudo(TextureButton.StylePseudoClassHover)
+ .Prop(TextureButton.StylePropertyTexture, btnHoverTex),
+
+ E<TextureButton>()
+ .Class("RadialMenuCloseButton")
+ .Prop(TextureButton.StylePropertyTexture, closeNormalTex),
+ E<TextureButton>()
+ .Class("RadialMenuCloseButton")
+ .Pseudo(TextureButton.StylePseudoClassHover)
+ .Prop(TextureButton.StylePropertyTexture, closeHoverTex),
+
+ E<TextureButton>()
+ .Class("RadialMenuBackButton")
+ .Prop(TextureButton.StylePropertyTexture, backNormalTex),
+ E<TextureButton>()
+ .Class("RadialMenuBackButton")
+ .Pseudo(TextureButton.StylePseudoClassHover)
+ .Prop(TextureButton.StylePropertyTexture, backHoverTex),
+ ];
+ }
+}
--- /dev/null
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class ScrollbarSheetlet : Sheetlet<PalettedStylesheet>
+{
+ public const int DefaultGrabberSize = 10;
+
+ public override StyleRule[] GetRules(PalettedStylesheet sheet, object config)
+ {
+ // TODO: hardcoded colors!!!
+ var vScrollBarGrabberNormal = new StyleBoxFlat
+ {
+ BackgroundColor = Color.Gray.WithAlpha(0.35f), ContentMarginLeftOverride = DefaultGrabberSize,
+ ContentMarginTopOverride = DefaultGrabberSize,
+ };
+ var vScrollBarGrabberHover = new StyleBoxFlat
+ {
+ BackgroundColor = new Color(140, 140, 140).WithAlpha(0.35f), ContentMarginLeftOverride = DefaultGrabberSize,
+ ContentMarginTopOverride = DefaultGrabberSize,
+ };
+
+ var vScrollBarGrabberGrabbed = new StyleBoxFlat
+ {
+ BackgroundColor = new Color(160, 160, 160).WithAlpha(0.35f), ContentMarginLeftOverride = DefaultGrabberSize,
+ ContentMarginTopOverride = DefaultGrabberSize,
+ };
+
+ var hScrollBarGrabberNormal = new StyleBoxFlat
+ {
+ BackgroundColor = Color.Gray.WithAlpha(0.35f), ContentMarginTopOverride = DefaultGrabberSize,
+ };
+
+ var hScrollBarGrabberHover = new StyleBoxFlat
+ {
+ BackgroundColor = new Color(140, 140, 140).WithAlpha(0.35f), ContentMarginTopOverride = DefaultGrabberSize,
+ };
+
+ var hScrollBarGrabberGrabbed = new StyleBoxFlat
+ {
+ BackgroundColor = new Color(160, 160, 160).WithAlpha(0.35f), ContentMarginTopOverride = DefaultGrabberSize,
+ };
+
+ return
+ [
+ E<VScrollBar>().Prop(ScrollBar.StylePropertyGrabber, vScrollBarGrabberNormal),
+ E<VScrollBar>().PseudoHovered().Prop(ScrollBar.StylePropertyGrabber, vScrollBarGrabberHover),
+ E<VScrollBar>().PseudoPressed().Prop(ScrollBar.StylePropertyGrabber, vScrollBarGrabberGrabbed),
+ E<HScrollBar>().Prop(ScrollBar.StylePropertyGrabber, hScrollBarGrabberNormal),
+ E<HScrollBar>().PseudoHovered().Prop(ScrollBar.StylePropertyGrabber, hScrollBarGrabberHover),
+ E<HScrollBar>().PseudoPressed().Prop(ScrollBar.StylePropertyGrabber, hScrollBarGrabberGrabbed),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class SliderSheetlet<T> : Sheetlet<T> where T: PalettedStylesheet, ISliderConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ ISliderConfig sliderCfg = sheet;
+
+ var sliderFillTex = sheet.GetTextureOr(sliderCfg.SliderFillPath, NanotrasenStylesheet.TextureRoot);
+
+ var sliderFillBox = new StyleBoxTexture
+ {
+ Texture = sliderFillTex,
+ Modulate = sheet.PositivePalette.TextDark,
+ };
+
+ var sliderBackBox = new StyleBoxTexture
+ {
+ Texture = sliderFillTex,
+ Modulate = sheet.SecondaryPalette.BackgroundDark,
+ };
+
+ var sliderForeBox = new StyleBoxTexture
+ {
+ Texture = sheet.GetTextureOr(sliderCfg.SliderOutlinePath, NanotrasenStylesheet.TextureRoot),
+ Modulate = Color.FromHex("#494949") // TODO: Unhardcode.
+ };
+
+ var sliderGrabBox = new StyleBoxTexture
+ {
+ Texture = sheet.GetTextureOr(sliderCfg.SliderGrabber, NanotrasenStylesheet.TextureRoot),
+ };
+
+ sliderFillBox.SetPatchMargin(StyleBox.Margin.All, 12);
+ sliderBackBox.SetPatchMargin(StyleBox.Margin.All, 12);
+ sliderForeBox.SetPatchMargin(StyleBox.Margin.All, 12);
+ sliderGrabBox.SetPatchMargin(StyleBox.Margin.All, 12);
+
+ // var sliderFillGreen = new StyleBoxTexture(sliderFillBox) { Modulate = Color.LimeGreen };
+ // var sliderFillRed = new StyleBoxTexture(sliderFillBox) { Modulate = Color.Red };
+ // var sliderFillBlue = new StyleBoxTexture(sliderFillBox) { Modulate = Color.Blue };
+ // var sliderFillWhite = new StyleBoxTexture(sliderFillBox) { Modulate = Color.White };
+
+ return new StyleRule[]
+ {
+ E<Slider>()
+ .Prop(Slider.StylePropertyBackground, sliderBackBox)
+ .Prop(Slider.StylePropertyForeground, sliderForeBox)
+ .Prop(Slider.StylePropertyGrabber, sliderGrabBox)
+ .Prop(Slider.StylePropertyFill, sliderFillBox),
+ // these styles seem to be unused now
+ // E<ColorableSlider>()
+ // .Prop(ColorableSlider.StylePropertyFillWhite, sliderFillWhite)
+ // .Prop(ColorableSlider.StylePropertyBackgroundWhite, sliderFillWhite),
+ //
+ // E<Slider>().Class(StyleClass.StyleClassSliderRed)
+ // .Prop(Slider.StylePropertyFill, sliderFillRed),
+ // E<Slider>().Class(StyleClass.StyleClassSliderBlue)
+ // .Prop(Slider.StylePropertyFill, sliderFillBlue),
+ // E<Slider>().Class(StyleClass.StyleClassSliderGreen)
+ // .Prop(Slider.StylePropertyFill, sliderFillGreen),
+ // E<Slider>().Class(StyleClass.StyleClassSliderWhite)
+ // .Prop(Slider.StylePropertyFill, sliderFillWhite),
+ };
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Content.Client.UserInterface.Controls;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class StripebackSheetlet<T> : Sheetlet<T> where T : PalettedStylesheet, IStripebackConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ IStripebackConfig stripebackCfg = sheet;
+
+ var stripeBack = new StyleBoxTexture
+ {
+ Texture = sheet.GetTextureOr(stripebackCfg.StripebackPath, NanotrasenStylesheet.TextureRoot),
+ Mode = StyleBoxTexture.StretchMode.Tile,
+ };
+
+ return
+ [
+ E<StripeBack>()
+ .Prop(StripeBack.StylePropertyBackground, stripeBack),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class TabContainerSheetlet<T> : Sheetlet<T> where T: PalettedStylesheet, ITabContainerConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ ITabContainerConfig tabCfg = sheet;
+
+ var tabContainerPanel = sheet.GetTextureOr(tabCfg.TabContainerPanelPath, NanotrasenStylesheet.TextureRoot)
+ .IntoPatch(StyleBox.Margin.All, 2);
+
+ var tabContainerBoxActive = new StyleBoxFlat(sheet.SecondaryPalette.Element);
+ tabContainerBoxActive.SetContentMarginOverride(StyleBox.Margin.Horizontal, 5);
+ var tabContainerBoxInactive = new StyleBoxFlat(sheet.SecondaryPalette.Background);
+ tabContainerBoxInactive.SetContentMarginOverride(StyleBox.Margin.Horizontal, 5);
+
+ return
+ [
+ E<TabContainer>()
+ .Prop(TabContainer.StylePropertyPanelStyleBox, tabContainerPanel)
+ .Prop(TabContainer.StylePropertyTabStyleBox, tabContainerBoxActive)
+ .Prop(TabContainer.StylePropertyTabStyleBoxInactive, tabContainerBoxInactive),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.Resources;
+using Content.Client.Stylesheets.Fonts;
+using Robust.Client.UserInterface;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+/// These are not in `LabelSheetlet` because a label is not the only thing you might want to be monospaced.
+[CommonSheetlet]
+public sealed class TextSheetlet : Sheetlet<PalettedStylesheet>
+{
+ public override StyleRule[] GetRules(PalettedStylesheet sheet, object config)
+ {
+ // TODO: once fonts are reworked, change this!
+ var mono = ResCache.GetFont("/EngineFonts/NotoSans/NotoSansMono-Regular.ttf", 12);
+
+ return
+ [
+ E().Class(StyleClass.Monospace).Font(mono),
+ E().Class(StyleClass.Italic).Font(sheet.BaseFont.GetFont(12, FontKind.Italic)),
+ E().Class(StyleClass.FontLarge).Font(sheet.BaseFont.GetFont(14)),
+ E().Class(StyleClass.FontSmall).Font(sheet.BaseFont.GetFont(10)),
+ ];
+ }
+}
--- /dev/null
+using Content.Client.Resources;
+using Content.Client.Stylesheets.Fonts;
+using Content.Client.Stylesheets.Palette;
+using Content.Client.Stylesheets.SheetletConfigs;
+using Content.Client.Stylesheets.Stylesheets;
+using Content.Client.UserInterface.Controls;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.CustomControls;
+using static Content.Client.Stylesheets.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Sheetlets;
+
+[CommonSheetlet]
+public sealed class WindowSheetlet<T> : Sheetlet<T>
+ where T : PalettedStylesheet, IButtonConfig, IWindowConfig, IIconConfig
+{
+ public override StyleRule[] GetRules(T sheet, object config)
+ {
+ IButtonConfig buttonCfg = sheet;
+ IWindowConfig windowCfg = sheet;
+ IIconConfig iconCfg = sheet;
+
+ var headerStylebox = new StyleBoxTexture
+ {
+ Texture = sheet.GetTextureOr(windowCfg.WindowHeaderTexturePath, NanotrasenStylesheet.TextureRoot),
+ PatchMarginBottom = 3,
+ ExpandMarginBottom = 3,
+ ContentMarginBottomOverride = 0,
+ };
+ // TODO: This would probably be better palette-based but we can leave it for now.
+ var headerAlertStylebox = new StyleBoxTexture
+ {
+ Texture = sheet.GetTextureOr(windowCfg.WindowHeaderAlertTexturePath, NanotrasenStylesheet.TextureRoot),
+ PatchMarginBottom = 3,
+ ExpandMarginBottom = 3,
+ ContentMarginBottomOverride = 0,
+ };
+ var backgroundBox = new StyleBoxTexture()
+ {
+ Texture = sheet.GetTextureOr(windowCfg.WindowBackgroundPath, NanotrasenStylesheet.TextureRoot),
+ };
+ backgroundBox.SetPatchMargin(StyleBox.Margin.Horizontal | StyleBox.Margin.Bottom, 2);
+ backgroundBox.SetExpandMargin(StyleBox.Margin.Horizontal | StyleBox.Margin.Bottom, 2);
+ var borderedBackgroundBox = new StyleBoxTexture
+ {
+ Texture = sheet.GetTextureOr(windowCfg.WindowBackgroundBorderedPath, NanotrasenStylesheet.TextureRoot),
+ };
+ borderedBackgroundBox.SetPatchMargin(StyleBox.Margin.All, 2);
+ var closeButtonTex = sheet.GetTextureOr(iconCfg.CrossIconPath, NanotrasenStylesheet.TextureRoot);
+
+ var leftPanel = StyleBoxHelpers.OpenLeftStyleBox(sheet);
+ leftPanel.SetPadding(StyleBox.Margin.All, 0.0f);
+
+ // TODO: maybe also change everything here to `NanoWindow` or something
+ return
+ [
+ // TODO: KILL DEFAULT WINDOW (in a bit)
+ E<Label>()
+ .Class(DefaultWindow.StyleClassWindowTitle)
+ .FontColor(sheet.HighlightPalette.Text)
+ .Font(sheet.BaseFont.GetFont(14, FontKind.Bold)),
+ E<Label>()
+ .Class("windowTitleAlert")
+ .FontColor(Color.White)
+ .Font(sheet.BaseFont.GetFont(14, FontKind.Bold)),
+ // TODO: maybe also change everything here to `NanoWindow` or something
+ E()
+ .Class(DefaultWindow.StyleClassWindowPanel)
+ .Panel(backgroundBox),
+ E()
+ .Class(DefaultWindow.StyleClassWindowHeader)
+ .Panel(headerStylebox),
+ E()
+ .Class(StyleClass.AlertWindowHeader)
+ .Panel(headerAlertStylebox),
+ E()
+ .Class(StyleClass.BorderedWindowPanel)
+ .Panel(borderedBackgroundBox),
+
+ // Close button
+ E<TextureButton>()
+ .Class(DefaultWindow.StyleClassWindowCloseButton)
+ .Prop(TextureButton.StylePropertyTexture, closeButtonTex)
+ .Margin(3),
+ E<TextureButton>()
+ .Class(DefaultWindow.StyleClassWindowCloseButton)
+ .PseudoNormal()
+ .Modulate(Palettes.Neutral.Element),
+ E<TextureButton>()
+ .Class(DefaultWindow.StyleClassWindowCloseButton)
+ .PseudoHovered()
+ .Modulate(Palettes.Red.HoveredElement),
+ E<TextureButton>()
+ .Class(DefaultWindow.StyleClassWindowCloseButton)
+ .PseudoPressed()
+ .Modulate(Palettes.Red.PressedElement),
+ E<TextureButton>()
+ .Class(DefaultWindow.StyleClassWindowCloseButton)
+ .PseudoDisabled()
+ .Modulate(Palettes.Red.DisabledElement),
+
+ // Title
+ E<Label>()
+ .Class("FancyWindowTitle") // TODO: hardcoding class name
+ .Font(ResCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13)) // TODO: hardcoding font
+ .FontColor(sheet.HighlightPalette.Text),
+
+ // Help Button
+ E<TextureButton>()
+ .Class(FancyWindow.StyleClassWindowHelpButton)
+ .Prop(TextureButton.StylePropertyTexture,
+ sheet.GetTextureOr(iconCfg.HelpIconPath, NanotrasenStylesheet.TextureRoot))
+ .Prop(Control.StylePropertyModulateSelf, sheet.PrimaryPalette.Element),
+ E<TextureButton>()
+ .Class(FancyWindow.StyleClassWindowHelpButton)
+ .Pseudo(ContainerButton.StylePseudoClassHover)
+ .Prop(Control.StylePropertyModulateSelf, sheet.PrimaryPalette.HoveredElement),
+ E<TextureButton>()
+ .Class(FancyWindow.StyleClassWindowHelpButton)
+ .Pseudo(ContainerButton.StylePseudoClassPressed)
+ .Prop(Control.StylePropertyModulateSelf, sheet.PrimaryPalette.PressedElement),
+
+ // Footer
+ E<Label>()
+ .Class("WindowFooterText") // TODO: hardcoding font
+ .Prop(Label.StylePropertyFont, sheet.BaseFont.GetFont(8))
+ .Prop(Label.StylePropertyFontColor, Color.FromHex("#757575")),
+ ];
+ }
+}
namespace Content.Client.Stylesheets
{
+ [Obsolete("Please use the new sheetlet system to define styles, and remove all references to this class as it may be deleted in the future")]
public abstract class StyleBase
{
- public const string ClassHighDivider = "HighDivider";
- public const string ClassLowDivider = "LowDivider";
- public const string StyleClassLabelHeading = "LabelHeading";
- public const string StyleClassLabelSubText = "LabelSubText";
- public const string StyleClassItalic = "Italic";
-
- public const string ClassAngleRect = "AngleRect";
-
- public const string ButtonOpenRight = "OpenRight";
- public const string ButtonOpenLeft = "OpenLeft";
- public const string ButtonOpenBoth = "OpenBoth";
- public const string ButtonSquare = "ButtonSquare";
-
- public const string ButtonCaution = "Caution";
-
- public const int DefaultGrabberSize = 10;
-
public abstract Stylesheet Stylesheet { get; }
protected StyleRule[] BaseRules { get; }
};
AngleBorderRect.SetPatchMargin(StyleBox.Margin.All, 10);
- var vScrollBarGrabberNormal = new StyleBoxFlat
- {
- BackgroundColor = Color.Gray.WithAlpha(0.35f), ContentMarginLeftOverride = DefaultGrabberSize,
- ContentMarginTopOverride = DefaultGrabberSize
- };
- var vScrollBarGrabberHover = new StyleBoxFlat
- {
- BackgroundColor = new Color(140, 140, 140).WithAlpha(0.35f), ContentMarginLeftOverride = DefaultGrabberSize,
- ContentMarginTopOverride = DefaultGrabberSize
- };
- var vScrollBarGrabberGrabbed = new StyleBoxFlat
- {
- BackgroundColor = new Color(160, 160, 160).WithAlpha(0.35f), ContentMarginLeftOverride = DefaultGrabberSize,
- ContentMarginTopOverride = DefaultGrabberSize
- };
-
- var hScrollBarGrabberNormal = new StyleBoxFlat
- {
- BackgroundColor = Color.Gray.WithAlpha(0.35f), ContentMarginTopOverride = DefaultGrabberSize
- };
- var hScrollBarGrabberHover = new StyleBoxFlat
- {
- BackgroundColor = new Color(140, 140, 140).WithAlpha(0.35f), ContentMarginTopOverride = DefaultGrabberSize
- };
- var hScrollBarGrabberGrabbed = new StyleBoxFlat
- {
- BackgroundColor = new Color(160, 160, 160).WithAlpha(0.35f), ContentMarginTopOverride = DefaultGrabberSize
- };
-
BaseRules = new[]
{
// Default font.
new StyleRule(
- new SelectorElement(null, new[] {StyleClassItalic}, null, null),
+ new SelectorElement(null, new[] {StyleClass.Italic}, null, null),
new[]
{
new StyleProperty("font", notoSans12Italic),
{
new StyleProperty(Control.StylePropertyModulateSelf, Color.FromHex("#753131")),
}),
-
- // Scroll bars
- new StyleRule(new SelectorElement(typeof(VScrollBar), null, null, null),
- new[]
- {
- new StyleProperty(ScrollBar.StylePropertyGrabber,
- vScrollBarGrabberNormal),
- }),
-
- new StyleRule(
- new SelectorElement(typeof(VScrollBar), null, null, new[] {ScrollBar.StylePseudoClassHover}),
- new[]
- {
- new StyleProperty(ScrollBar.StylePropertyGrabber,
- vScrollBarGrabberHover),
- }),
-
- new StyleRule(
- new SelectorElement(typeof(VScrollBar), null, null, new[] {ScrollBar.StylePseudoClassGrabbed}),
- new[]
- {
- new StyleProperty(ScrollBar.StylePropertyGrabber,
- vScrollBarGrabberGrabbed),
- }),
-
- new StyleRule(new SelectorElement(typeof(HScrollBar), null, null, null),
- new[]
- {
- new StyleProperty(ScrollBar.StylePropertyGrabber,
- hScrollBarGrabberNormal),
- }),
-
- new StyleRule(
- new SelectorElement(typeof(HScrollBar), null, null, new[] {ScrollBar.StylePseudoClassHover}),
- new[]
- {
- new StyleProperty(ScrollBar.StylePropertyGrabber,
- hScrollBarGrabberHover),
- }),
-
- new StyleRule(
- new SelectorElement(typeof(HScrollBar), null, null, new[] {ScrollBar.StylePseudoClassGrabbed}),
- new[]
- {
- new StyleProperty(ScrollBar.StylePropertyGrabber,
- hScrollBarGrabberGrabbed),
- }),
};
}
}
--- /dev/null
+namespace Content.Client.Stylesheets;
+
+///
+/// <summary>
+/// A collection of public reusable style classes. These should be general purpose (Not specific to only one element
+/// or Ui).
+/// </summary>
+/// <remarks>
+/// It is named `StyleClass` as opposed to `StyleClasses` because `StyleClasses` is a field on `Control` so it made
+/// it a pain to reference this class from a `Control`. (Weird name is worth typing `StyleClass.OpenBoth` vs.
+/// `Stylesheets.Styleclasses.OpenBoth`)
+/// </remarks>
+public static class StyleClass
+{
+ // These style classes affect more than one type of element
+ public const string Positive = "positive";
+ public const string Negative = "negative";
+ public const string Highlight = "highlight";
+
+ public const string StatusGood = "status-good"; // Status.GetStatusColor(1.0f)
+ public const string StatusOkay = "status-okay"; // Status.GetStatusColor(0.75f)
+ public const string StatusWarning = "status-warning"; // Status.GetStatusColor(0.5f)
+ public const string StatusBad = "status-bad"; // Status.GetStatusColor(0.25f)
+ public const string StatusCritical = "status-critical"; // Status.GetStatusColor(0.0f)
+
+ public const string FontLarge = "font-large";
+ public const string FontSmall = "font-small";
+ public const string Italic = "italic";
+ public const string Monospace = "monospace";
+
+ public const string BorderedWindowPanel = "BorderedWindowPanel";
+ public const string AlertWindowHeader = "windowHeaderAlert";
+ public const string WindowContentsContainer = "WindowContentsContainer";
+
+ public const string HighDivider = "HighDivider";
+ public const string LowDivider = "LowDivider";
+
+ public const string LabelHeading = "LabelHeading";
+ public const string LabelHeadingBigger = "LabelHeadingBigger";
+ public const string LabelSubText = "LabelSubText";
+ public const string LabelKeyText = "LabelKeyText";
+ public const string LabelWeak = "LabelWeak"; // replaces `LabelSecondaryColor`
+
+ public const string BackgroundPanel = "BackgroundPanel"; // replaces `AngleRect`
+ public const string BackgroundPanelOpenLeft = "BackgroundPanelOpenLeft"; // replaces `BackgroundOpenLeft`
+ public const string BackgroundPanelOpenRight = "BackgroundPanelOpenRight"; // replaces `BackgroundOpenRight`
+
+ public const string PanelDark = "PanelDark";
+ public const string PanelLight = "PanelLight";
+
+ public const string ButtonOpenRight = "OpenRight";
+ public const string ButtonOpenLeft = "OpenLeft";
+ public const string ButtonOpenBoth = "OpenBoth";
+ public const string ButtonSquare = "ButtonSquare";
+ public const string ButtonSmall = "ButtonSmall";
+ public const string ButtonBig = "ButtonBig";
+
+ public const string CrossButtonRed = "CrossButtonRed";
+
+ public const string ItemStatus = "ItemStatus";
+ public const string ItemStatusNotHeld = "ItemStatusNotHeld";
+
+ public const string TooltipPanel = "TooltipPanel";
+ public const string TooltipTitle = "TooltipTitle";
+ public const string TooltipDesc = "TooltipDesc";
+}
}
// STLYE SHEETS WERE A MISTAKE. KILL ALL OF THIS WITH FIRE
+ [Obsolete("Please use the new sheetlet system to define styles, and remove all references to this class as it may be deleted in the future")]
+ // i did :)
public sealed class StyleNano : StyleBase
{
public const string StyleClassBorderedWindowPanel = "BorderedWindowPanel";
public const string StyleClassPinButtonPinned = "pinButtonPinned";
public const string StyleClassPinButtonUnpinned = "pinButtonUnpinned";
+ // i'm not sure what the missing symbols were referencing, and this is getting obseleted anyway so:
+ public const string ButtonOpenRight = "OpenRight";
+ public const string ButtonOpenLeft = "OpenLeft";
+ public const string ButtonOpenBoth = "OpenBoth";
+ public const string ButtonSquare = "OpenBoth";
+ public const string ButtonCaution = "negative";
+ public const string StyleClassLabelHeading = "LabelHeading";
+ public const string StyleClassLabelSubText = "LabelSubText";
+ public const string StyleClassRedTopButton = "negative";
+ public const string ClassHighDivider = "HighDivider";
+ public const string ClassLowDivider = "LowDivider";
+ public const string ClassAngleRect = "AngleRect";
+
public override Stylesheet Stylesheet { get; }
itemListItemBackgroundTransparent.SetContentMarginOverride(StyleBox.Margin.Vertical, 2);
itemListItemBackgroundTransparent.SetContentMarginOverride(StyleBox.Margin.Horizontal, 4);
- var squareTex = resCache.GetTexture("/Textures/Interface/Nano/square.png");
- var listContainerButton = new StyleBoxTexture
+ var listContainerButton = new StyleBoxFlat
{
- Texture = squareTex,
ContentMarginLeftOverride = 10
};
}),
// small number for the entity counter in the entity menu
- new StyleRule(new SelectorElement(typeof(Label), new[] {ContextMenuElement.StyleClassEntityMenuIconLabel}, null, null), new[]
- {
- new StyleProperty("font", notoSans10),
- new StyleProperty(Label.StylePropertyAlignMode, Label.AlignMode.Right),
- }),
+ // new StyleRule(new SelectorElement(typeof(Label), new[] {ContextMenuElement.StyleClassEntityMenuIconLabel}, null, null), new[]
+ // {
+ // new StyleProperty("font", notoSans10),
+ // new StyleProperty(Label.StylePropertyAlignMode, Label.AlignMode.Right),
+ // }),
// hotbar slot
new StyleRule(new SelectorElement(typeof(RichTextLabel), new[] {StyleClassHotbarSlotNumber}, null, null), new[]
new StyleProperty(Button.StylePropertyModulateSelf, ButtonColorDefault),
}),
- new StyleRule(
- new SelectorElement(typeof(MenuButton), new[] {MenuButton.StyleClassRedTopButton}, null, new[] {Button.StylePseudoClassNormal}),
- new[]
- {
- new StyleProperty(Button.StylePropertyModulateSelf, ButtonColorDefaultRed),
- }),
-
new StyleRule(
new SelectorElement(typeof(MenuButton), null, null, new[] {Button.StylePseudoClassNormal}),
new[]
new StyleProperty(Button.StylePropertyModulateSelf, ButtonColorHovered),
}),
- new StyleRule(
- new SelectorElement(typeof(MenuButton), new[] {MenuButton.StyleClassRedTopButton}, null, new[] {Button.StylePseudoClassHover}),
- new[]
- {
- new StyleProperty(Button.StylePropertyModulateSelf, ButtonColorHoveredRed),
- }),
-
- new StyleRule(
- new SelectorElement(typeof(Label), new[] {MenuButton.StyleClassLabelTopButton}, null, null),
- new[]
- {
- new StyleProperty(Label.StylePropertyFont, notoSansDisplayBold14),
- }),
-
// MonotoneButton (unfilled)
new StyleRule(
new SelectorElement(typeof(MonotoneButton), null, null, null),
--- /dev/null
+namespace Content.Client.Stylesheets;
+
+public sealed class StyleProperties
+{
+ public const string PrimaryPalette = "palette-primary";
+ public const string SecondaryPalette = "palette-secondary";
+ public const string PositivePalette = "palette-positive";
+ public const string NegativePalette = "palette-negative";
+ public const string HighlightPalette = "palette-highlight";
+}
namespace Content.Client.Stylesheets
{
+ [Obsolete("Please use the new sheetlet system to define styles, and remove all references to this class as it may be deleted in the future")]
public sealed class StyleSpace : StyleBase
{
public static readonly Color SpaceRed = Color.FromHex("#9b2236");
Stylesheet = new Stylesheet(BaseRules.Concat(new StyleRule[]
{
- Element<Label>().Class(StyleClassLabelHeading)
+ Element<Label>().Class(StyleClass.LabelHeading)
.Prop(Label.StylePropertyFont, notoSansBold16)
.Prop(Label.StylePropertyFontColor, SpaceRed),
- Element<Label>().Class(StyleClassLabelSubText)
+ Element<Label>().Class(StyleClass.LabelSubText)
.Prop(Label.StylePropertyFont, notoSans10)
.Prop(Label.StylePropertyFontColor, Color.DarkGray),
- Element<PanelContainer>().Class(ClassHighDivider)
+ Element<PanelContainer>().Class(StyleClass.HighDivider)
.Prop(PanelContainer.StylePropertyPanel, new StyleBoxFlat
{
BackgroundColor = SpaceRed, ContentMarginBottomOverride = 2, ContentMarginLeftOverride = 2
}),
- Element<PanelContainer>().Class(ClassLowDivider)
+ Element<PanelContainer>().Class(StyleClass.LowDivider)
.Prop(PanelContainer.StylePropertyPanel, new StyleBoxFlat
{
BackgroundColor = Color.FromHex("#444"),
.Prop(ContainerButton.StylePropertyStyleBox, BaseButton),
Element<ContainerButton>().Class(ContainerButton.StyleClassButton)
- .Class(ButtonOpenRight)
+ .Class(StyleClass.ButtonOpenRight)
.Prop(ContainerButton.StylePropertyStyleBox, BaseButtonOpenRight),
Element<ContainerButton>().Class(ContainerButton.StyleClassButton)
- .Class(ButtonOpenLeft)
+ .Class(StyleClass.ButtonOpenLeft)
.Prop(ContainerButton.StylePropertyStyleBox, BaseButtonOpenLeft),
Element<ContainerButton>().Class(ContainerButton.StyleClassButton)
- .Class(ButtonOpenBoth)
+ .Class(StyleClass.ButtonOpenBoth)
.Prop(ContainerButton.StylePropertyStyleBox, BaseButtonOpenBoth),
Element<ContainerButton>().Class(ContainerButton.StyleClassButton)
- .Class(ButtonSquare)
+ .Class(StyleClass.ButtonSquare)
.Prop(ContainerButton.StylePropertyStyleBox, BaseButtonSquare),
// Colors for the buttons.
.Prop(Control.StylePropertyModulateSelf, ButtonColorDisabled),
// Colors for the caution buttons.
- Element<ContainerButton>().Class(ContainerButton.StyleClassButton).Class(ButtonCaution)
+ Element<ContainerButton>().Class(ContainerButton.StyleClassButton).Class(StyleClass.Negative)
.Pseudo(ContainerButton.StylePseudoClassNormal)
.Prop(Control.StylePropertyModulateSelf, ButtonColorCautionDefault),
- Element<ContainerButton>().Class(ContainerButton.StyleClassButton).Class(ButtonCaution)
+ Element<ContainerButton>().Class(ContainerButton.StyleClassButton).Class(StyleClass.Negative)
.Pseudo(ContainerButton.StylePseudoClassHover)
.Prop(Control.StylePropertyModulateSelf, ButtonColorCautionHovered),
- Element<ContainerButton>().Class(ContainerButton.StyleClassButton).Class(ButtonCaution)
+ Element<ContainerButton>().Class(ContainerButton.StyleClassButton).Class(StyleClass.Negative)
.Pseudo(ContainerButton.StylePseudoClassPressed)
.Prop(Control.StylePropertyModulateSelf, ButtonColorCautionPressed),
- Element<ContainerButton>().Class(ContainerButton.StyleClassButton).Class(ButtonCaution)
+ Element<ContainerButton>().Class(ContainerButton.StyleClassButton).Class(StyleClass.Negative)
.Pseudo(ContainerButton.StylePseudoClassDisabled)
.Prop(Control.StylePropertyModulateSelf, ButtonColorCautionDisabled),
Element<Label>().Class(ContainerButton.StyleClassButton)
.Prop(Label.StylePropertyAlignMode, Label.AlignMode.Center),
- Element<PanelContainer>().Class(ClassAngleRect)
+ Element<PanelContainer>().Class(StyleClass.BackgroundPanel)
.Prop(PanelContainer.StylePropertyPanel, BaseAngleRect)
.Prop(Control.StylePropertyModulateSelf, Color.FromHex("#202030")),
--- /dev/null
+using System.Numerics;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using static Robust.Client.UserInterface.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets;
+
+public static class StylesheetHelpers
+{
+ public static MutableSelector Modulate(this MutableSelector selector, Color modulate)
+ {
+ return selector.Prop(Control.StylePropertyModulateSelf, modulate);
+ }
+
+ public static MutableSelector Margin(this MutableSelector selector, Thickness margin)
+ {
+ return selector.Prop(nameof(Control.Margin), margin);
+ }
+
+ public static MutableSelector Margin(this MutableSelector selector, float margin)
+ {
+ return selector.Margin(new Thickness(margin));
+ }
+
+ public static MutableSelector MinWidth(this MutableSelector selector, float width)
+ {
+ return selector.Prop(nameof(Control.MinWidth), width);
+ }
+
+ public static MutableSelector MinHeight(this MutableSelector selector, float height)
+ {
+ return selector.Prop(nameof(Control.MinHeight), height);
+ }
+
+ public static MutableSelector MinSize(this MutableSelector selector, Vector2 size)
+ {
+ return selector.MinWidth(size.X).MinHeight(size.Y);
+ }
+
+ public static MutableSelector MaxWidth(this MutableSelector selector, float width)
+ {
+ return selector.Prop(nameof(Control.MaxWidth), width);
+ }
+
+ public static MutableSelector MaxHeight(this MutableSelector selector, float height)
+ {
+ return selector.Prop(nameof(Control.MaxHeight), height);
+ }
+
+ public static MutableSelector MaxSize(this MutableSelector selector, Vector2 size)
+ {
+ return selector.MaxWidth(size.X).MaxHeight(size.Y);
+ }
+
+ public static MutableSelector SetWidth(this MutableSelector selector, float width)
+ {
+ return selector.Prop(nameof(Control.SetWidth), width);
+ }
+
+ public static MutableSelector SetHeight(this MutableSelector selector, float height)
+ {
+ return selector.Prop(nameof(Control.SetHeight), height);
+ }
+
+ public static MutableSelector SetSize(this MutableSelector selector, Vector2 size)
+ {
+ return selector.SetWidth(size.X).SetHeight(size.Y);
+ }
+
+ public static MutableSelector HorizontalExpand(this MutableSelector selector, bool val)
+ {
+ return selector.Prop(nameof(Control.HorizontalExpand), val);
+ }
+
+ public static MutableSelector VerticalExpand(this MutableSelector selector, bool val)
+ {
+ return selector.Prop(nameof(Control.VerticalExpand), val);
+ }
+
+ public static MutableSelector HorizontalAlignment(this MutableSelector selector, Control.HAlignment val)
+ {
+ return selector.Prop(nameof(Control.HorizontalExpand), val);
+ }
+
+ public static MutableSelector VerticalAlignment(this MutableSelector selector, Control.VAlignment val)
+ {
+ return selector.Prop(nameof(Control.VerticalExpand), val);
+ }
+
+ public static MutableSelector AlignMode(this MutableSelector selector, Label.AlignMode mode)
+ {
+ return selector.Prop(Label.StylePropertyAlignMode, mode);
+ }
+
+ // Pseudo class helpers
+
+ public static MutableSelectorElement PseudoNormal(this MutableSelectorElement selector)
+ {
+ return selector.Pseudo(ContainerButton.StylePseudoClassNormal);
+ }
+
+ public static MutableSelectorElement PseudoHovered(this MutableSelectorElement selector)
+ {
+ return selector.Pseudo(ContainerButton.StylePseudoClassHover);
+ }
+
+ public static MutableSelectorElement PseudoPressed(this MutableSelectorElement selector)
+ {
+ return selector.Pseudo(ContainerButton.StylePseudoClassPressed);
+ }
+
+ public static MutableSelectorElement PseudoDisabled(this MutableSelectorElement selector)
+ {
+ return selector.Pseudo(ContainerButton.StylePseudoClassDisabled);
+ }
+
+ public static MutableSelectorElement MaybeClass(this MutableSelectorElement selector, string? styleclass)
+ {
+ if (styleclass is { } c)
+ return selector.Class(c);
+
+ return selector;
+ }
+
+ public static MutableSelectorElement E<T>() where T : Control
+ {
+ return new MutableSelectorElement { Type = typeof(T) };
+ }
+
+ public static MutableSelectorElement E()
+ {
+ return new MutableSelectorElement();
+ }
+
+ public static MutableSelector Panel(this MutableSelector selector, StyleBox panel)
+ {
+ return selector.Prop(PanelContainer.StylePropertyPanel, panel);
+ }
+
+ public static MutableSelector Box(this MutableSelector selector, StyleBox box)
+ {
+ return selector.Prop(ContainerButton.StylePropertyStyleBox, box);
+ }
+
+ public static MutableSelector Font(this MutableSelector selector, Font font)
+ {
+ return selector.Prop(Label.StylePropertyFont, font);
+ }
+
+ public static MutableSelector FontColor(this MutableSelector selector, Color fontColor)
+ {
+ return selector.Prop(Label.StylePropertyFontColor, fontColor);
+ }
+
+ public static StyleBoxTexture IntoPatch(this Texture texture, StyleBox.Margin patchMargin, float amount)
+ {
+ var stylebox = new StyleBoxTexture
+ {
+ Texture = texture,
+ };
+ stylebox.SetPatchMargin(patchMargin, amount);
+
+ return stylebox;
+ }
+
+ public static MutableSelectorChild ParentOf(this MutableSelector selector, MutableSelector other)
+ {
+ return Child().Parent(selector).Child(other);
+ }
+}
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using Content.Client.Stylesheets.Stylesheets;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface;
-using Robust.Shared.IoC;
+using Robust.Shared.Reflection;
namespace Content.Client.Stylesheets
{
public sealed class StylesheetManager : IStylesheetManager
{
+ [Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
- [Dependency] private readonly IResourceCache _resourceCache = default!;
+ [Dependency] private readonly IReflectionManager _reflection = default!;
+ [Dependency]
+ private readonly IResourceCache
+ _resCache = default!; // TODO: REMOVE (obsolete; used to construct StyleNano/StyleSpace)
+
+ public Stylesheet SheetNanotrasen { get; private set; } = default!;
+ public Stylesheet SheetSystem { get; private set; } = default!;
+
+ [Obsolete("Update to use SheetNanotrasen instead")]
public Stylesheet SheetNano { get; private set; } = default!;
+
+ [Obsolete("Update to use SheetSystem instead")]
public Stylesheet SheetSpace { get; private set; } = default!;
+ private Dictionary<string, Stylesheet> Stylesheets { get; set; } = default!;
+
+ public bool TryGetStylesheet(string name, [MaybeNullWhen(false)] out Stylesheet stylesheet)
+ {
+ return Stylesheets.TryGetValue(name, out stylesheet);
+ }
+
+ public HashSet<Type> UnusedSheetlets { get; private set; } = [];
+
public void Initialize()
{
- SheetNano = new StyleNano(_resourceCache).Stylesheet;
- SheetSpace = new StyleSpace(_resourceCache).Stylesheet;
+ var sawmill = _logManager.GetSawmill("style");
+ sawmill.Debug("Initializing Stylesheets...");
+ var sw = Stopwatch.StartNew();
- _userInterfaceManager.Stylesheet = SheetNano;
+ // add all sheetlets to the hashset
+ var tys = _reflection.FindTypesWithAttribute<CommonSheetletAttribute>();
+ UnusedSheetlets = [..tys];
+
+ Stylesheets = new Dictionary<string, Stylesheet>();
+ SheetNanotrasen = Init(new NanotrasenStylesheet(new BaseStylesheet.NoConfig(), this));
+ SheetSystem = Init(new SystemStylesheet(new BaseStylesheet.NoConfig(), this));
+ SheetNano = new StyleNano(_resCache).Stylesheet; // TODO: REMOVE (obsolete)
+ SheetSpace = new StyleSpace(_resCache).Stylesheet; // TODO: REMOVE (obsolete)
+
+ _userInterfaceManager.Stylesheet = SheetNanotrasen;
+
+ // warn about unused sheetlets
+ if (UnusedSheetlets.Count > 0)
+ {
+ var sheetlets = UnusedSheetlets.AsEnumerable()
+ .Take(5)
+ .Select(t => t.FullName ?? "<could not get FullName>")
+ .ToArray();
+ sawmill.Error($"There are unloaded sheetlets: {string.Join(", ", sheetlets)}");
+ }
+
+ sawmill.Debug($"Initialized {_styleRuleCount} style rules in {sw.Elapsed}");
+ }
+
+ private int _styleRuleCount;
+
+ private Stylesheet Init(BaseStylesheet baseSheet)
+ {
+ Stylesheets.Add(baseSheet.StylesheetName, baseSheet.Stylesheet);
+ _styleRuleCount += baseSheet.Stylesheet.Rules.Count;
+ return baseSheet.Stylesheet;
}
}
}
--- /dev/null
+using Content.Client.Stylesheets.Palette;
+
+namespace Content.Client.Stylesheets.Stylesheets;
+
+public sealed partial class NanotrasenStylesheet
+{
+ public override ColorPalette PrimaryPalette => Palettes.Navy;
+ public override ColorPalette SecondaryPalette => Palettes.Slate;
+ public override ColorPalette PositivePalette => Palettes.Green;
+ public override ColorPalette NegativePalette => Palettes.Red;
+ public override ColorPalette HighlightPalette => Palettes.Gold;
+}
--- /dev/null
+using System.Linq;
+using Content.Client.Stylesheets.Fonts;
+using Robust.Client.ResourceManagement;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using Robust.Shared.Utility;
+using static Robust.Client.UserInterface.StylesheetHelpers;
+
+namespace Content.Client.Stylesheets.Stylesheets;
+
+[Virtual]
+public partial class NanotrasenStylesheet : CommonStylesheet
+{
+ public override string StylesheetName => "Nanotrasen";
+
+ public override NotoFontFamilyStack BaseFont { get; } // TODO: NotoFontFamilyStack is temporary
+
+
+ public static readonly ResPath TextureRoot = new("/Textures/Interface/Nano");
+
+ public override Dictionary<Type, ResPath[]> Roots => new()
+ {
+ { typeof(TextureResource), [TextureRoot] },
+ };
+
+ private const int PrimaryFontSize = 12;
+ private const int FontSizeStep = 2;
+
+ // why? see InterfaceStylesheet.cs
+ // ReSharper disable once UseCollectionExpression
+ private readonly List<(string?, int)> _commonFontSizes = new()
+ {
+ (null, PrimaryFontSize),
+ (StyleClass.FontSmall, PrimaryFontSize - FontSizeStep),
+ (StyleClass.FontLarge, PrimaryFontSize + FontSizeStep),
+ };
+
+ public NanotrasenStylesheet(object config, StylesheetManager man) : base(config)
+ {
+ BaseFont = new NotoFontFamilyStack(ResCache);
+ var rules = new[]
+ {
+ // Set up important rules that need to go first.
+ GetRulesForFont(null, BaseFont, _commonFontSizes),
+ // Set up our core rules.
+ [
+ // Declare the default font.
+ Element().Prop(Label.StylePropertyFont, BaseFont.GetFont(PrimaryFontSize)),
+ // Branding.
+ Element<TextureRect>()
+ .Class("NTLogoDark")
+ .Prop(TextureRect.StylePropertyTexture, GetTexture(new ResPath("ntlogo.svg.png")))
+ .Prop(Control.StylePropertyModulateSelf, Color.FromHex("#757575")),
+ ],
+ // Finally, load all the other sheetlets.
+ GetAllSheetletRules<PalettedStylesheet, CommonSheetletAttribute>(man),
+ GetAllSheetletRules<NanotrasenStylesheet, CommonSheetletAttribute>(man),
+ };
+
+ Stylesheet = new Stylesheet(rules.SelectMany(x => x).ToArray());
+ }
+}
--- /dev/null
+using Content.Client.Stylesheets.Palette;
+
+namespace Content.Client.Stylesheets.Stylesheets;
+
+public partial class SystemStylesheet
+{
+ public override ColorPalette PrimaryPalette => Palettes.Cyan;
+ public override ColorPalette SecondaryPalette => Palettes.Neutral;
+ public override ColorPalette PositivePalette => Palettes.Green;
+ public override ColorPalette NegativePalette => Palettes.Red;
+ public override ColorPalette HighlightPalette => Palettes.Maroon;
+}
--- /dev/null
+using System.Linq;
+using Content.Client.Stylesheets.Fonts;
+using Robust.Client.ResourceManagement;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using Robust.Shared.Utility;
+using static Robust.Client.UserInterface.StylesheetHelpers;
+
+
+namespace Content.Client.Stylesheets.Stylesheets;
+
+[Virtual]
+public partial class SystemStylesheet : CommonStylesheet
+{
+ public override string StylesheetName => "System";
+
+ public override NotoFontFamilyStack BaseFont { get; } // TODO: NotoFontFamilyStack is temporary
+
+ public override Dictionary<Type, ResPath[]> Roots => new()
+ {
+ { typeof(TextureResource), [] },
+ };
+
+ private const int PrimaryFontSize = 12;
+ private const int FontSizeStep = 2;
+
+ // for some GOD FORSAKEN REASON if I use a collection expression here it throws a sandbox error
+ // Thanks ReSharper, this was very fun to find in the ~40 files I last committed
+ // ReSharper disable once UseCollectionExpression
+ private readonly List<(string?, int)> _commonFontSizes = new()
+ {
+ (null, PrimaryFontSize),
+ (StyleClass.FontSmall, PrimaryFontSize - FontSizeStep),
+ (StyleClass.FontLarge, PrimaryFontSize + FontSizeStep),
+ };
+
+ public SystemStylesheet(object config, StylesheetManager man) : base(config)
+ {
+ BaseFont = new NotoFontFamilyStack(ResCache);
+ var rules = new[]
+ {
+ // Set up important rules that need to go first.
+ GetRulesForFont(null, BaseFont, _commonFontSizes),
+ // Set up our core rules.
+ [
+ // Declare the default font.
+ Element().Prop(Label.StylePropertyFont, BaseFont.GetFont(PrimaryFontSize)),
+ ],
+ // Finally, load all the other sheetlets.
+ GetAllSheetletRules<PalettedStylesheet, CommonSheetletAttribute>(man),
+ GetAllSheetletRules<SystemStylesheet, CommonSheetletAttribute>(man),
+ };
+
+ Stylesheet = new Stylesheet(rules.SelectMany(x => x).ToArray());
+ }
+}
private float _timePassed; // Time passed since last update sent to the server.
private EntityUid? _draggedEntity; // Entity being dragged
private ScalingViewport? _viewport; // Viewport currently being used
- private DefaultWindow? _window; // Current open tabletop window (only allow one at a time)
+ private BaseWindow? _window; // Current open tabletop window (only allow one at a time)
private EntityUid? _table; // The table entity of the currently open game session
public override void Initialize()
</PanelContainer.PanelOverride>
<BoxContainer Orientation="Vertical" HorizontalExpand="True">
<GridContainer Margin="5" Columns="2" MinSize="600 0">
- <Label Name="SetName" Text="Set" StyleClasses="StatusFieldTitle"></Label>
+ <Label Name="SetName" Text="Set" StyleClasses="highlight"></Label>
<Button Margin="0 10" Name="SetButton" Text="Select" StyleClasses="OpenRight" Access="Public" HorizontalAlignment="Right"/>
</GridContainer>
<controls:HLine Color="#404040" Thickness="1" Margin="0 5"/>
public MultipleToolStatusControl(MultipleToolComponent parent)
{
_parent = parent;
- _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
+ _label = new RichTextLabel { StyleClasses = { StyleClass.ItemStatus } };
_label.SetMarkup(_parent.StatusShowBehavior ? _parent.CurrentQualityName : string.Empty);
AddChild(_label);
}
_parent = parent;
_entityManager = entityManager;
_toolSystem = toolSystem;
- _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
+ _label = new RichTextLabel { StyleClasses = { StyleClass.ItemStatus } };
AddChild(_label);
UpdateDraw();
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
MouseFilter="Stop"
MinWidth="200" MinHeight="150">
- <PanelContainer StyleClasses="AngleRect" />
+ <PanelContainer StyleClasses="BackgroundPanel" />
<BoxContainer Orientation="Vertical">
<Control>
- <PanelContainer StyleClasses="WindowHeadingBackground" />
- <BoxContainer Margin="4 2 8 0" Orientation="Horizontal">
+ <PanelContainer StyleClasses="WindowHeadingBackground" Name="WindowHeader" />
+ <BoxContainer Margin="4 2 4 0" Orientation="Horizontal">
<Label Name="WindowTitle"
HorizontalExpand="True" VAlign="Center" StyleClasses="FancyWindowTitle" ClipText="true" />
<TextureButton Name="HelpButton" StyleClasses="windowHelpButton" VerticalAlignment="Center" Disabled="True" Visible="False" Access="Public" />
</BoxContainer>
</Control>
<PanelContainer StyleClasses="LowDivider" />
- <Control Access="Public" Name="ContentsContainer" Margin="0 2" RectClipContent="True" VerticalExpand="true" />
+ <Control Access="Public" Name="ContentsContainer" StyleClasses="WindowContentsContainer" RectClipContent="True" VerticalExpand="true" />
</BoxContainer>
</controls:FancyWindow>
using System.Numerics;
using Content.Client.Guidebook;
using Content.Client.Guidebook.Components;
+using Content.Client.Stylesheets;
using Content.Shared.Guidebook;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.CustomControls;
public partial class FancyWindow : BaseWindow
{
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
+ [Dependency] private readonly IStylesheetManager _styleMan = default!;
private GuidebookSystem? _guidebookSystem;
private const int DRAG_MARGIN_SIZE = 7;
+
public const string StyleClassWindowHelpButton = "windowHelpButton";
+ public const string StyleClassWindowCloseButton = "windowCloseButton";
public FancyWindow()
{
RobustXamlLoader.Load(this);
+ IoCManager.InjectDependencies(this);
CloseButton.OnPressed += _ => Close();
HelpButton.OnPressed += _ => Help();
set => WindowTitle.Text = value;
}
+ private string? _stylesheet;
+
+ public new string? Stylesheet
+ {
+ get => _stylesheet;
+ set
+ {
+ _stylesheet = value;
+ if (value is not null && _styleMan.TryGetStylesheet(value, out var stylesheet))
+ base.Stylesheet = stylesheet;
+ }
+ }
+
private List<ProtoId<GuideEntryPrototype>>? _helpGuidebookIds;
+
public List<ProtoId<GuideEntryPrototype>>? HelpGuidebookIds
{
get => _helpGuidebookIds;
return mode;
}
+
+ public string HeaderClass { set => WindowHeader.SetOnlyStyleClass(value); }
+ public string TitleClass { set => WindowTitle.SetOnlyStyleClass(value); }
}
/// <summary>
namespace Content.Client.UserInterface.Controls;
-public sealed class HLine : Container
+public sealed class HLine : PanelContainer
{
public Color? Color
{
get
{
- if (_line.PanelOverride is StyleBoxFlat styleBox) return styleBox.BackgroundColor;
- return null;
- }
- set
- {
- if (_line.PanelOverride is StyleBoxFlat styleBox) styleBox.BackgroundColor = value!.Value;
- }
- }
+ StyleBox box;
+ if (PanelOverride != null)
+ box = PanelOverride;
+ if (TryGetStyleProperty<StyleBox>(StylePropertyPanel, out var _box))
+ box = _box;
+ else
+ return null;
- public float? Thickness {
- get
- {
- if (_line.PanelOverride is StyleBoxFlat styleBox) return styleBox.ContentMarginTopOverride;
+ if (box is StyleBoxFlat boxFlat)
+ return boxFlat.BackgroundColor;
return null;
}
- set
- {
- if (_line.PanelOverride is StyleBoxFlat styleBox) styleBox.ContentMarginTopOverride = value!.Value;
- }
+ set =>
+ // should use style classes instead in ui code but keeping this functionality for consistency
+ PanelOverride = new StyleBoxFlat() { BackgroundColor = value!.Value };
}
- private readonly PanelContainer _line;
+ public float? Thickness
+ {
+ get => MinHeight;
+ set => MinHeight = value!.Value;
+ }
public HLine()
{
- _line = new PanelContainer();
- _line.PanelOverride = new StyleBoxFlat();
- _line.PanelOverride.ContentMarginTopOverride = Thickness;
- AddChild(_line);
}
-
}
{
public HighDivider()
{
- Children.Add(new PanelContainer {StyleClasses = {StyleBase.ClassHighDivider}});
+ Children.Add(new PanelContainer {StyleClasses = {StyleClass.HighDivider}});
}
}
}
using System.Linq;
using System.Numerics;
using JetBrains.Annotations;
+using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Input;
AddStyleClass(StyleClassButton);
Data = data;
Index = index;
+ StyleBoxOverride = new StyleBoxFlat(Color.White);
// AddChild(Background = new PanelContainer
// {
// HorizontalExpand = true,
{
[Dependency] private readonly IInputManager _inputManager = default!;
public const string StyleClassLabelTopButton = "topButtonLabel";
- public const string StyleClassRedTopButton = "topButtonLabel";
+ // public const string StyleClassRedTopButton = "topButtonLabel";
- private static readonly Color ColorNormal = Color.FromHex("#7b7e9e");
- private static readonly Color ColorRedNormal = Color.FromHex("#FEFEFE");
- private static readonly Color ColorHovered = Color.FromHex("#9699bb");
- private static readonly Color ColorRedHovered = Color.FromHex("#FFFFFF");
- private static readonly Color ColorPressed = Color.FromHex("#789B8C");
+ // TODO: KIIIIIILLLLLLLLLLLLLLLLLLLLLLLLLLL --kaylie.
+ private static readonly Color ColorNormal = Color.FromHex("#99a7b3"); // primary color[0] + 0.24 L
+ private static readonly Color ColorHovered = Color.FromHex("#acbac6"); // primary color[0] + 0.30 L
+ private static readonly Color ColorPressed = Color.FromHex("#75838e"); // primary color[0] + 0.12 L
- private const float VertPad = 8f;
- private Color NormalColor => HasStyleClass(StyleClassRedTopButton) ? ColorRedNormal : ColorNormal;
- private Color HoveredColor => HasStyleClass(StyleClassRedTopButton) ? ColorRedHovered : ColorHovered;
+ private const float VertPad = 4f;
private BoundKeyFunction? _function;
private readonly BoxContainer _root;
VerticalAlignment = VAlignment.Center,
VerticalExpand = true,
Margin = new Thickness(0, VertPad),
- ModulateSelfOverride = NormalColor,
+ ModulateSelfOverride = ColorNormal,
Stretch = TextureRect.StretchMode.KeepCentered
};
_buttonLabel = new Label
{
Text = "",
HorizontalAlignment = HAlignment.Center,
- ModulateSelfOverride = NormalColor,
+ ModulateSelfOverride = ColorNormal,
StyleClasses = {StyleClassLabelTopButton}
};
_root = new BoxContainer
switch (DrawMode)
{
case DrawModeEnum.Normal:
- _buttonIcon.ModulateSelfOverride = NormalColor;
- _buttonLabel.ModulateSelfOverride = NormalColor;
+ _buttonIcon.ModulateSelfOverride = ColorNormal;
+ _buttonLabel.ModulateSelfOverride = ColorNormal;
break;
case DrawModeEnum.Pressed:
break;
case DrawModeEnum.Hover:
- _buttonIcon.ModulateSelfOverride = HoveredColor;
- _buttonLabel.ModulateSelfOverride = HoveredColor;
+ _buttonIcon.ModulateSelfOverride = ColorHovered;
+ _buttonLabel.ModulateSelfOverride = ColorHovered;
break;
case DrawModeEnum.Disabled:
{
Children = {(_label = new Label
{
- StyleClasses = {StyleNano.StyleClassLabelHeading}
+ StyleClasses = {StyleClass.LabelHeading}
})}
};
AddChild(_panel);
</LayoutContainer>
<BoxContainer Name="TopLeft" Access="Protected" Orientation="Vertical">
<BoxContainer Orientation="Horizontal">
- <menuBar:GameTopMenuBar Name="TopBar" Access="Protected" />
+ <menuBar:GameTopMenuBar Name="TopBar" Access="Public" />
<!-- Buffer so big votes don't skew it -->
<Control/>
</BoxContainer>
</PanelContainer.PanelOverride>
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SeparationOverride="10" Margin="10">
- <menuBar:GameTopMenuBar Name="TopBar" HorizontalExpand="True" Access="Protected" />
- <chat:ChatBox VerticalExpand="True" HorizontalExpand="True" Name="Chat" Access="Protected" MinSize="0 0"/>
+ <menuBar:GameTopMenuBar Name="TopBar" HorizontalExpand="True" Access="Public" />
+ <chat:ChatBox StyleClasses="ChatOutput" VerticalExpand="True" HorizontalExpand="True" Name="Chat" Access="Protected" MinSize="0 0"/>
</BoxContainer>
</PanelContainer>
</SplitContainer>
using System.Numerics;
+using Content.Client.Stylesheets;
using Content.Client.UserInterface.Systems.Chat.Widgets;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
[GenerateTypedNameReferences]
public sealed partial class SeparatedChatGameScreen : InGameScreen
{
+ public const string StyleClassChatContainer = "ChatContainer";
+ public const string StyleClassChatOutput = "ChatOutput";
+
public SeparatedChatGameScreen()
{
RobustXamlLoader.Load(this);
public sealed class ActionButton : Control, IEntityControl
{
+ public const string StyleClassActionHighlightRect = "ActionHighlightRect";
+
private IEntityManager _entities;
private IPlayerManager _player;
private SpriteSystem? _spriteSys;
};
HighlightRect = new PanelContainer
{
- StyleClasses = {StyleNano.StyleClassHandSlotHighlight},
+ StyleClasses = { StyleClassActionHighlightRect },
MinSize = new Vector2(32, 32),
Visible = false
};
+++ /dev/null
-<controls:ActionTooltip
- xmlns="https://spacestation14.io"
- xmlns:controls="clr-namespace:Content.Client.UserInterface.Systems.Actions.Controls"
- StyleClasses="StyleClassTooltipPanel">
- <BoxContainer Orientation="Vertical" RectClipContent="True">
- <RichTextLabel MaxWidth="350" StyleClasses="StyleClassTooltipActionTitle"/>
- <RichTextLabel MaxWidth="350" StyleClasses="StyleClassTooltipActionDescription"/>
- <RichTextLabel MaxWidth="350" StyleClasses="StyleClassTooltipActionCharges"/>
- </BoxContainer>
-</controls:ActionTooltip>
+++ /dev/null
-using Robust.Client.AutoGenerated;
-using Robust.Client.UserInterface.Controls;
-using Robust.Client.UserInterface.XAML;
-
-namespace Content.Client.UserInterface.Systems.Actions.Controls;
-
-[GenerateTypedNameReferences]
-public sealed partial class ActionTooltip : PanelContainer
-{
- public ActionTooltip()
- {
- RobustXamlLoader.Load(this);
- }
-}
[GenerateTypedNameReferences]
public sealed partial class ActionsWindow : DefaultWindow
{
+ public const string StyleClassActionSearchBox = "actionSearchBox";
+
public MultiselectOptionButton<Filters> FilterButton { get; private set; }
/// <summary>
_topLabel = new Label
{
FontOverride = font,
- FontColorOverride = StyleNano.NanoGold,
+ StyleClasses = { StyleClass.LabelKeyText },
VerticalAlignment = VAlignment.Center,
HorizontalExpand = true,
HorizontalAlignment = HAlignment.Left,
private void UnreadAHelpReceived()
{
- GameAHelpButton?.StyleClasses.Add(MenuButton.StyleClassRedTopButton);
- LobbyAHelpButton?.StyleClasses.Add(StyleNano.StyleClassButtonColorRed);
+ GameAHelpButton?.StyleClasses.Add(StyleClass.Negative);
+ LobbyAHelpButton?.StyleClasses.Add(StyleClass.Negative);
_hasUnreadAHelp = true;
}
private void UnreadAHelpRead()
{
- GameAHelpButton?.StyleClasses.Remove(MenuButton.StyleClassRedTopButton);
- LobbyAHelpButton?.StyleClasses.Remove(StyleNano.StyleClassButtonColorRed);
+ GameAHelpButton?.StyleClasses.Remove(StyleClass.Negative);
+ LobbyAHelpButton?.StyleClasses.Remove(StyleClass.Negative);
_hasUnreadAHelp = false;
}
var objectiveLabel = new RichTextLabel
{
- StyleClasses = { StyleNano.StyleClassTooltipActionTitle }
+ StyleClasses = { StyleClass.TooltipTitle }
};
objectiveLabel.SetMessage(objectiveText);
&& style is StyleBoxFlat propStyleBoxFlat)
color = propStyleBoxFlat.BackgroundColor;
else
- color = StyleNano.ChatBackgroundColor;
+ color = Color.FromHex("#25252ADD");
panel.PanelOverride = new StyleBoxFlat
{
public sealed class ChannelSelectorItemButton : Button
{
+ public const string StyleClassChatSelectorOptionButton = "ChatSelectorOptionButton";
+
+
public readonly ChatSelectChannel Channel;
public bool IsHidden => Parent == null;
public ChannelSelectorItemButton(ChatSelectChannel selector)
{
Channel = selector;
- AddStyleClass(StyleNano.StyleClassChatChannelSelectorButton);
+ AddStyleClass(StyleClassChatSelectorOptionButton);
Text = ChannelSelectorButton.ChannelSelectorName(selector);
-using Content.Client.Stylesheets;
-using Content.Shared.Chat;
+using Content.Shared.Chat;
using Content.Shared.Input;
using Robust.Client.UserInterface.Controls;
[Virtual]
public class ChatInputBox : PanelContainer
{
+ public const string StyleClassChatPanel = "ChatPanel";
+ public const string StyleClassChatLineEdit = "ChatLineEdit";
+ public const string StyleClassChatFilterOptionButton = "ChatFilterOptionButton";
+
public readonly ChannelSelectorButton ChannelSelector;
public readonly HistoryLineEdit Input;
public readonly ChannelFilterButton FilterButton;
{
Name = "ChannelSelector",
ToggleMode = true,
- StyleClasses = {"chatSelectorOptionButton"},
+ StyleClasses = { ChannelSelectorItemButton.StyleClassChatSelectorOptionButton },
MinWidth = 75
};
Container.AddChild(ChannelSelector);
Name = "Input",
PlaceHolder = GetChatboxInfoPlaceholder(),
HorizontalExpand = true,
- StyleClasses = {"chatLineEdit"}
+ StyleClasses = { StyleClassChatLineEdit }
};
Container.AddChild(Input);
FilterButton = new ChannelFilterButton
{
Name = "FilterButton",
- StyleClasses = {"chatFilterOptionButton"}
+ StyleClasses = { StyleClassChatFilterOptionButton }
};
Container.AddChild(FilterButton);
- AddStyleClass(StyleNano.StyleClassChatSubPanel);
+ AddStyleClass(StyleClassChatPanel);
ChannelSelector.OnChannelSelect += UpdateActiveChannel;
}
private static string GetChatboxInfoPlaceholder()
{
- return (BoundKeyHelper.IsBound(ContentKeyFunctions.FocusChat), BoundKeyHelper.IsBound(ContentKeyFunctions.CycleChatChannelForward)) switch
- {
- (true, true) => Loc.GetString("hud-chatbox-info", ("talk-key", BoundKeyHelper.ShortKeyName(ContentKeyFunctions.FocusChat)), ("cycle-key", BoundKeyHelper.ShortKeyName(ContentKeyFunctions.CycleChatChannelForward))),
- (true, false) => Loc.GetString("hud-chatbox-info-talk", ("talk-key", BoundKeyHelper.ShortKeyName(ContentKeyFunctions.FocusChat))),
- (false, true) => Loc.GetString("hud-chatbox-info-cycle", ("cycle-key", BoundKeyHelper.ShortKeyName(ContentKeyFunctions.CycleChatChannelForward))),
- (false, false) => Loc.GetString("hud-chatbox-info-unbound")
- };
+ return (BoundKeyHelper.IsBound(ContentKeyFunctions.FocusChat),
+ BoundKeyHelper.IsBound(ContentKeyFunctions.CycleChatChannelForward)) switch
+ {
+ (true, true) => Loc.GetString("hud-chatbox-info",
+ ("talk-key", BoundKeyHelper.ShortKeyName(ContentKeyFunctions.FocusChat)),
+ ("cycle-key", BoundKeyHelper.ShortKeyName(ContentKeyFunctions.CycleChatChannelForward))),
+ (true, false) => Loc.GetString("hud-chatbox-info-talk",
+ ("talk-key", BoundKeyHelper.ShortKeyName(ContentKeyFunctions.FocusChat))),
+ (false, true) => Loc.GetString("hud-chatbox-info-cycle",
+ ("cycle-key", BoundKeyHelper.ShortKeyName(ContentKeyFunctions.CycleChatChannelForward))),
+ (false, false) => Loc.GetString("hud-chatbox-info-unbound")
+ };
}
}
GhostWarpButton.OnPressed += _ => RequestWarpsPressed?.Invoke();
ReturnToBodyButton.OnPressed += _ => ReturnToBodyPressed?.Invoke();
GhostRolesButton.OnPressed += _ => GhostRolesPressed?.Invoke();
- GhostRolesButton.OnPressed += _ => GhostRolesButton.StyleClasses.Remove(StyleBase.ButtonCaution);
+ GhostRolesButton.OnPressed += _ => GhostRolesButton.StyleClasses.Remove(StyleClass.Negative);
}
public void Hide()
if (roles > _prevNumberRoles)
{
- GhostRolesButton.StyleClasses.Add(StyleBase.ButtonCaution);
+ GhostRolesButton.StyleClasses.Add(StyleClass.Negative);
}
_prevNumberRoles = (int)roles;
ToolTip="{Loc 'game-hud-open-escape-menu-button-tooltip'}"
MinSize="70 64"
HorizontalExpand="True"
- AppendStyleClass="{x:Static style:StyleBase.ButtonOpenRight}"
+ AppendStyleClass="{x:Static style:StyleClass.ButtonOpenRight}"
/>
<ui:MenuButton
Name="GuidebookButton"
BoundKey = "{x:Static is:ContentKeyFunctions.OpenGuidebook}"
MinSize="42 64"
HorizontalExpand="True"
- AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
+ AppendStyleClass="{x:Static style:StyleClass.ButtonSquare}"
/>
<ui:MenuButton
Name="CharacterButton"
BoundKey = "{x:Static is:ContentKeyFunctions.OpenCharacterMenu}"
MinSize="42 64"
HorizontalExpand="True"
- AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
+ AppendStyleClass="{x:Static style:StyleClass.ButtonSquare}"
/>
<ui:MenuButton
Name="EmotesButton"
BoundKey = "{x:Static is:ContentKeyFunctions.OpenEmotesMenu}"
MinSize="42 64"
HorizontalExpand="True"
- AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
+ AppendStyleClass="{x:Static style:StyleClass.ButtonSquare}"
/>
<ui:MenuButton
Name="CraftingButton"
ToolTip="{Loc 'game-hud-open-crafting-menu-button-tooltip'}"
MinSize="42 64"
HorizontalExpand="True"
- AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
+ AppendStyleClass="{x:Static style:StyleClass.ButtonSquare}"
/>
<ui:MenuButton
Name="ActionButton"
ToolTip="{Loc 'game-hud-open-actions-menu-button-tooltip'}"
MinSize="42 64"
HorizontalExpand="True"
- AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
+ AppendStyleClass="{x:Static style:StyleClass.ButtonSquare}"
/>
<ui:MenuButton
Name="AdminButton"
ToolTip="{Loc 'game-hud-open-admin-menu-button-tooltip'}"
MinSize="42 64"
HorizontalExpand="True"
- AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
+ AppendStyleClass="{x:Static style:StyleClass.ButtonSquare}"
/>
<ui:MenuButton
Name="SandboxButton"
ToolTip="{Loc 'game-hud-open-sandbox-menu-button-tooltip'}"
MinSize="42 64"
HorizontalExpand="True"
- AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
+ AppendStyleClass="{x:Static style:StyleClass.ButtonSquare}"
/>
<ui:MenuButton
Name="AHelpButton"
ToolTip="{Loc 'ui-options-function-open-a-help'}"
MinSize="42 64"
HorizontalExpand="True"
- AppendStyleClass="{x:Static style:StyleBase.ButtonOpenLeft}"
+ AppendStyleClass="{x:Static style:StyleClass.ButtonOpenLeft}"
/>
</widgets:GameTopMenuBar>
using Content.Client.SubFloor;
+using Content.Client.Stylesheets;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using System.Linq;
using System.Numerics;
+using Content.Client.Stylesheets;
using Content.Shared.VendingMachines;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
var item = new VendingMachineItem(protoID, text);
_listItems[protoID] = (button, item);
button.AddChild(item);
- button.AddStyleClass("ButtonSquare");
+ button.AddStyleClass(StyleClass.ButtonSquare);
button.Disabled = !_enabled || _amounts[protoID] == 0;
}
xmlns:ui="clr-namespace:Content.Client.Voting.UI"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
MouseFilter="Stop" MinSize="350 200">
- <PanelContainer StyleClasses="AngleRect" />
+ <PanelContainer StyleClasses="BackgroundPanel" />
<BoxContainer Orientation="Vertical">
<BoxContainer Margin="8 0" Orientation="Horizontal">
<Label Text="{Loc 'ui-vote-create-title'}"
<BoxContainer Orientation="Vertical" Margin="8 2 8 0" VerticalExpand="True" VerticalAlignment="Top">
<BoxContainer Orientation="Vertical">
<OptionButton Margin="2 1" Name="VoteTypeButton" HorizontalExpand="False" />
- <BoxContainer Name="VoteOptionsButtonContainer" HorizontalExpand="False" Orientation="Vertical">
+ <BoxContainer Name="VoteOptionsButtonContainer" HorizontalExpand="False" Orientation="Vertical">
</BoxContainer>
<Button Margin="64 4" Name="FollowButton" Text="{Loc 'ui-vote-follow-button'}" Visible="False" />
<Label Margin="2 2" Name="VoteNotTrustedLabel" Text="{Loc 'ui-vote-trusted-users-notice'}" Visible="False" />
</BoxContainer>
<Label Margin="8 2" Name="VoteTypeTimeoutLabel" Visible="False" />
</BoxContainer>
-
+
<Button Margin="8 32 8 2" Name="CreateButton" Text="{Loc 'ui-vote-create-button'}" />
<PanelContainer StyleClasses="LowDivider" />
RobustXamlLoader.Load(this);
_votingSystem = _entityManager.System<VotingSystem>();
- Stylesheet = IoCManager.Resolve<IStylesheetManager>().SheetSpace;
+ Stylesheet = IoCManager.Resolve<IStylesheetManager>().SheetSystem;
CloseButton.OnPressed += _ => Close();
VoteNotTrustedLabel.Text = Loc.GetString("ui-vote-trusted-users-notice", ("timeReq", _cfg.GetCVar(CCVars.VotekickEligibleVoterDeathtime)));
<Control xmlns="https://spacestation14.io" MinWidth="300" MaxWidth="500">
- <PanelContainer StyleClasses="AngleRect" />
+ <PanelContainer StyleClasses="BackgroundPanel" />
<BoxContainer Margin="4" Orientation="Vertical">
<Label Name="VoteCaller" />
<RichTextLabel Name="VoteTitle" />
<Button Margin="4 4" Name="FollowVoteTarget" Text="{Loc 'ui-vote-follow-button-popup'}" Visible="False"></Button>
-
+
<GridContainer Columns="3" Name="VoteOptionsContainer"/>
<BoxContainer Orientation="Horizontal">
<ProgressBar Margin="4" HorizontalExpand="True" Name="TimeLeftBar" MinValue="0" MaxValue="1" />
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
- Stylesheet = IoCManager.Resolve<IStylesheetManager>().SheetSpace;
+ Stylesheet = IoCManager.Resolve<IStylesheetManager>().SheetSystem;
if (_vote.TargetEntity != null && _vote.TargetEntity != 0)
{
}),
(_ammoCount = new Label
{
- StyleClasses = { StyleNano.StyleClassItemStatus },
+ StyleClasses = { StyleClass.ItemStatus },
HorizontalAlignment = HAlignment.Right,
VerticalAlignment = VAlignment.Bottom
}),
(_noMagazineLabel = new Label
{
Text = "No Magazine!",
- StyleClasses = {StyleNano.StyleClassItemStatus}
+ StyleClasses = {StyleClass.ItemStatus}
})
}
},
{
(_ammoCount = new Label
{
- StyleClasses = {StyleNano.StyleClassItemStatus},
+ StyleClasses = {StyleClass.ItemStatus},
HorizontalAlignment = HAlignment.Right,
}),
(_chamberedBullet = new TextureRect
{
Text = Loc.GetString("wires-menu-name-label"),
FontOverride = font,
- FontColorOverride = StyleNano.NanoGold,
VerticalAlignment = VAlignment.Center,
+ StyleClasses = { StyleClass.LabelKeyText },
}),
(_serialLabel = new Label
{
MinSize="300 150">
<BoxContainer Orientation="Vertical" Align="Begin" Margin="8">
<Label Text="{Loc 'replay-info-title'}" Margin="4" HorizontalAlignment="Center"/>
- <controls:HLine Color="{x:Static style:StyleNano.NanoGold}" Thickness="4"/>
+ <controls:HLine StyleClasses="highlight" Thickness="4"/>
<RichTextLabel Access="Public" Name="Info"/>
</BoxContainer>
</PanelContainer>
apc-menu-power-state-good = Good
apc-menu-power-state-low = Low
apc-menu-power-state-none = None
+apc-menu-power-state-label-text = { POWERWATTS($power) }
# For the flavor text on the footer
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="24"
- height="24"
- viewBox="0 0 6.3499998 6.35"
- version="1.1"
- id="svg1055"
- inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
- sodipodi:docname="square.svg"
- inkscape:export-filename="H:\Code\GitHub\space-station-14\Resources\Nano\square.png"
- inkscape:export-xdpi="96"
- inkscape:export-ydpi="96">
- <defs
- id="defs1049" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="22.627417"
- inkscape:cx="10.246658"
- inkscape:cy="8.604338"
- inkscape:document-units="mm"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:pagecheckerboard="true"
- inkscape:window-width="1280"
- inkscape:window-height="971"
- inkscape:window-x="1432"
- inkscape:window-y="-8"
- inkscape:window-maximized="1"
- units="px"
- inkscape:snap-page="true" />
- <metadata
- id="metadata1052">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(-79.848503,-133.93878)">
- <rect
- style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:3.62899995;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect816"
- width="6.3499999"
- height="6.3499999"
- x="79.848503"
- y="133.93878" />
- </g>
-</svg>