Inverse Labels and Handlabeler menu (#6432)

Merge pull request #1120 from oooielp/label-invert (#783)

Co-authored-by: Khaomi <46065349+Khaomi@users.noreply.github.com>
Co-authored-by: Superlagg <sprambersonson@gmail.com>
This commit is contained in:
Coryn
2026-08-27 14:26:07 -05:00
committed by GitHub
co-authored by Khaomi Superlagg
parent e9f0148287
commit 03347ed416
8 changed files with 167 additions and 6 deletions
@@ -32,10 +32,10 @@ namespace Content.Client.Labels.UI
} }
_window.OnLabelChanged += OnLabelChanged; _window.OnLabelChanged += OnLabelChanged;
_window.OnLabelSelected += OnLabelSelected; // Starlight
Reload(); Reload();
_window.SetInitialLabelState(); // Must be after Reload() has set the label text _window.SetInitialLabelState(); // Must be after Reload() has set the label text
} }
private void OnLabelChanged(string newLabel) private void OnLabelChanged(string newLabel)
{ {
// Focus moment // Focus moment
@@ -45,7 +45,17 @@ namespace Content.Client.Labels.UI
SendPredictedMessage(new HandLabelerLabelChangedMessage(newLabel)); SendPredictedMessage(new HandLabelerLabelChangedMessage(newLabel));
} }
// Starlight start
private void OnLabelSelected(string label)
{
// Update UI and send message to sync with server
if (_window != null)
{
_window.SetCurrentLabel(label);
}
SendPredictedMessage(new HandLabelerLabelChangedMessage(label));
}
// Starlight End
public void Reload() public void Reload()
{ {
if (_window == null || !_entManager.TryGetComponent(Owner, out HandLabelerComponent? component)) if (_window == null || !_entManager.TryGetComponent(Owner, out HandLabelerComponent? component))
@@ -1,8 +1,10 @@
<DefaultWindow xmlns="https://spacestation14.io" <DefaultWindow xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
Title="{Loc 'hand-labeler-ui-header'}" Title="{Loc 'hand-labeler-ui-header'}"
SetWidth="400" SetWidth="400"
MinWidth="150"> MinWidth="150"
SetHeight="400"> <!-- Starlight - include gfx and set default height to include saved labels section nicely -->
<BoxContainer Orientation="Vertical" SeparationOverride="4"> <BoxContainer Orientation="Vertical" SeparationOverride="4">
<Label Name="CurrentTextLabel" Text="{Loc 'hand-labeler-current-text-label'}" /> <Label Name="CurrentTextLabel" Text="{Loc 'hand-labeler-current-text-label'}" />
<LineEdit Name="LabelLineEdit" /> <LineEdit Name="LabelLineEdit" />
@@ -10,5 +12,19 @@
<Button Name="ResetLabelButton" Text="{Loc 'hand-labeler-ui-reset-label-text'}" StyleClasses="OpenRight" /> <Button Name="ResetLabelButton" Text="{Loc 'hand-labeler-ui-reset-label-text'}" StyleClasses="OpenRight" />
<Button Name="ClearLabelButton" Text="{Loc 'hand-labeler-ui-clear-label-text'}" StyleClasses="OpenLeft" /> <Button Name="ClearLabelButton" Text="{Loc 'hand-labeler-ui-clear-label-text'}" StyleClasses="OpenLeft" />
</BoxContainer> </BoxContainer>
<!-- Starlight Begin -->
<Label Text="{Loc 'hand-labeler-saved-labels'}" />
<PanelContainer VerticalExpand="True" SizeFlagsStretchRatio="1">
<PanelContainer.PanelOverride>
<gfx:StyleBoxFlat BackgroundColor="#1B1B1E" />
</PanelContainer.PanelOverride>
<ItemList Name="SavedLabelsList" VerticalExpand="True" SelectMode="Button" />
</PanelContainer>
<BoxContainer Orientation="Horizontal" Align="Center">
<Button Name="SaveLabelButton" Text="{Loc 'hand-labeler-save-label-text'}" StyleClasses="OpenRight" />
<Button Name="DeleteLabelButton" Text="{Loc 'hand-labeler-delete-label-text'}" StyleClasses="OpenLeft" />
</BoxContainer>
<!-- Starlight end -->
</BoxContainer> </BoxContainer>
</DefaultWindow> </DefaultWindow>
@@ -1,13 +1,19 @@
using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.CustomControls;
using Robust.Client.AutoGenerated; using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML; using Robust.Client.UserInterface.XAML;
using Robust.Client.UserInterface.Controls; // Starlight
using Robust.Shared.Configuration; // Starlight
using Content.Shared.Starlight.CCVar; // Starlight
namespace Content.Client.Labels.UI namespace Content.Client.Labels.UI
{ {
[GenerateTypedNameReferences] [GenerateTypedNameReferences]
public sealed partial class HandLabelerWindow : DefaultWindow public sealed partial class HandLabelerWindow : DefaultWindow
{ {
[Dependency] private readonly IConfigurationManager _cfg = default!; // Starlight
public event Action<string>? OnLabelChanged; public event Action<string>? OnLabelChanged;
public event Action<string>? OnLabelSelected; // Starlight
/// <summary> /// <summary>
/// Is the user currently entering text into the control? /// Is the user currently entering text into the control?
@@ -17,10 +23,14 @@ namespace Content.Client.Labels.UI
private string _label = string.Empty; private string _label = string.Empty;
private string _initialLabel = string.Empty; private string _initialLabel = string.Empty;
private bool _deleteMode = false; // Starlight
private List<string> _savedLabels = []; // Starlight
public HandLabelerWindow() public HandLabelerWindow()
{ {
RobustXamlLoader.Load(this); RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this); // Starlight
LoadSavedLabelsFromCVar(); // Starlight
LabelLineEdit.OnTextChanged += e => LabelLineEdit.OnTextChanged += e =>
{ {
@@ -37,6 +47,42 @@ namespace Content.Client.Labels.UI
}; };
ResetLabelButton.OnPressed += _ => LabelLineEdit.SetText(_initialLabel, true); ResetLabelButton.OnPressed += _ => LabelLineEdit.SetText(_initialLabel, true);
ClearLabelButton.OnPressed += _ => LabelLineEdit.SetText("", true); ClearLabelButton.OnPressed += _ => LabelLineEdit.SetText("", true);
// Starlight Begin
SaveLabelButton.OnPressed += _ =>
{
if (!string.IsNullOrWhiteSpace(_label) && !_savedLabels.Contains(_label))
{
_savedLabels.Add(_label);
SaveSavedLabelsToCVar();
UpdateSavedLabels(_savedLabels);
}
};
DeleteLabelButton.OnPressed += _ =>
{
_deleteMode = !_deleteMode;
DeleteLabelButton.Pressed = _deleteMode;
UpdateButtons();
};
SavedLabelsList.OnItemSelected += args =>
{
if (_deleteMode)
{
_savedLabels.RemoveAt(args.ItemIndex);
SaveSavedLabelsToCVar();
UpdateSavedLabels(_savedLabels);
UpdateButtons();
}
else
{
if (SavedLabelsList[args.ItemIndex].Metadata is string label)
{
OnLabelSelected?.Invoke(label);
}
}
}; // Starlight End
} }
protected override void Opened() protected override void Opened()
@@ -70,15 +116,68 @@ namespace Content.Client.Labels.UI
UpdateButtons(); UpdateButtons();
} }
// Starlight begin
public void UpdateSavedLabels(List<string> labels)
{
var items = new List<ItemList.Item>();
foreach (var label in labels)
{
var item = new ItemList.Item(SavedLabelsList)
{
Text = label,
Metadata = label
};
items.Add(item);
}
SavedLabelsList.SetItems(items);
UpdateButtons();
}
// Starlight end
public void UpdateButtons() public void UpdateButtons()
{ {
ResetLabelButton.Disabled = (LabelLineEdit.Text == _initialLabel); ResetLabelButton.Disabled = (LabelLineEdit.Text == _initialLabel);
ClearLabelButton.Disabled = (LabelLineEdit.Text == ""); ClearLabelButton.Disabled = (LabelLineEdit.Text == "");
}
// Starlight begin
var labelExists = false;
foreach (var item in SavedLabelsList)
{
if ((item.Metadata as string) == _label.Trim())
{
labelExists = true;
break;
}
}
SaveLabelButton.Disabled = string.IsNullOrWhiteSpace(_label) || labelExists;
DeleteLabelButton.Text = _deleteMode
? Loc.GetString("hand-labeler-delete-mode-text")
: Loc.GetString("hand-labeler-delete-label-text");
// Starlight end
}
public void SetMaxLabelLength(int maxLength) public void SetMaxLabelLength(int maxLength)
{ {
LabelLineEdit.IsValid = s => s.Length <= maxLength; LabelLineEdit.IsValid = s => s.Length <= maxLength;
} }
// Starlight begin
private void LoadSavedLabelsFromCVar()
{
var savedLabelsStr = _cfg.GetCVar(StarlightCCVars.HandLabelerSavedLabels);
if (!string.IsNullOrEmpty(savedLabelsStr))
{
_savedLabels = new List<string>(savedLabelsStr.Split('\n', StringSplitOptions.RemoveEmptyEntries));
UpdateSavedLabels(_savedLabels);
}
}
private void SaveSavedLabelsToCVar()
{
var savedLabelsStr = string.Join('\n', _savedLabels);
_cfg.SetCVar(StarlightCCVars.HandLabelerSavedLabels, savedLabelsStr);
_cfg.SaveToFile();
}
// Starlight end
} }
} }
@@ -90,7 +90,7 @@ public sealed partial class LabelSystem : EntitySystem
private void OnRefreshNameModifiers(Entity<LabelComponent> entity, ref RefreshNameModifiersEvent args) private void OnRefreshNameModifiers(Entity<LabelComponent> entity, ref RefreshNameModifiersEvent args)
{ {
if (!string.IsNullOrEmpty(entity.Comp.CurrentLabel)) if (!string.IsNullOrEmpty(entity.Comp.CurrentLabel))
args.AddModifier("comp-label-format", extraArgs: ("label", entity.Comp.CurrentLabel)); args.AddModifier("comp-label-format", 100, extraArgs: ("label", entity.Comp.CurrentLabel)); // Coyote: add priority of 100 to reverse order of label and baseName
} }
private void OnComponentInit(Entity<PaperLabelComponent> ent, ref ComponentInit args) private void OnComponentInit(Entity<PaperLabelComponent> ent, ref ComponentInit args)
@@ -0,0 +1,10 @@
using Robust.Shared.Configuration;
using Content.Shared.CCVar.CVarAccess;
using Content.Shared.Administration;
namespace Content.Shared.Starlight.CCVar;
[CVarDefs]
public sealed partial class StarlightCCVars
{
}
@@ -0,0 +1,13 @@
using Robust.Shared.Configuration;
namespace Content.Shared.Starlight.CCVar;
public sealed partial class StarlightCCVars
{
/// <summary>
/// A newline-separated list of saved labels for the hand labeler tool
/// </summary>
public static readonly CVarDef<string> HandLabelerSavedLabels =
CVarDef.Create("interface.hand_labeler_saved_labels", "", CVar.CLIENTONLY | CVar.ARCHIVE);
}
@@ -0,0 +1,12 @@
hand-labeler-saved-labels = Saved Labels:
# The text on the button in the ui to save a label to the saved label list.
hand-labeler-save-label-text = Save Label
# The text on the button in the ui to delete a label from the saved label list.
hand-labeler-delete-label-text = Delete Label
# The text on the button when in delete mode.
hand-labeler-delete-mode-text = Deleting...
@@ -1 +1,2 @@
comp-label-format = {$baseName} ({$label}) # Coyote: reverse order of label and baseName
comp-label-format = {$label} ({$baseName})