diff --git a/Content.Client/CartridgeLoader/CartridgeLoaderBoundUserInterface.cs b/Content.Client/CartridgeLoader/CartridgeLoaderBoundUserInterface.cs new file mode 100644 index 0000000000..c07f14c6e9 --- /dev/null +++ b/Content.Client/CartridgeLoader/CartridgeLoaderBoundUserInterface.cs @@ -0,0 +1,136 @@ +using Content.Shared.CartridgeLoader; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; + +namespace Content.Client.CartridgeLoader; + + +public abstract class CartridgeLoaderBoundUserInterface : BoundUserInterface +{ + [Dependency] private readonly IEntityManager? _entityManager = default!; + + private EntityUid? _activeProgram; + private CartridgeUI? _activeCartridgeUI; + private Control? _activeUiFragment; + + protected CartridgeLoaderBoundUserInterface(ClientUserInterfaceComponent owner, Enum uiKey) : base(owner, uiKey) + { + IoCManager.InjectDependencies(this); + } + + protected override void UpdateState(BoundUserInterfaceState state) + { + base.UpdateState(state); + + if (state is not CartridgeLoaderUiState loaderUiState) + { + _activeCartridgeUI?.UpdateState(state); + return; + } + + var programs = GetCartridgeComponents(loaderUiState.Programs); + UpdateAvailablePrograms(programs); + + _activeProgram = loaderUiState.ActiveUI; + + var ui = RetrieveCartridgeUI(loaderUiState.ActiveUI); + var comp = RetrieveCartridgeComponent(loaderUiState.ActiveUI); + var control = ui?.GetUIFragmentRoot(); + + //Prevent the same UI fragment from getting disposed and attached multiple times + if (_activeUiFragment?.GetType() == control?.GetType()) + return; + + if (_activeUiFragment is not null) + DetachCartridgeUI(_activeUiFragment); + + if (control is not null && _activeProgram.HasValue) + { + AttachCartridgeUI(control, Loc.GetString(comp?.ProgramName ?? "default-program-name")); + SendCartridgeUiReadyEvent(_activeProgram.Value); + } + + _activeCartridgeUI = ui; + _activeUiFragment?.Dispose(); + _activeUiFragment = control; + } + + protected void ActivateCartridge(EntityUid cartridgeUid) + { + var message = new CartridgeLoaderUiMessage(cartridgeUid, CartridgeUiMessageAction.Activate); + SendMessage(message); + } + + protected void DeactivateActiveCartridge() + { + if (!_activeProgram.HasValue) + return; + + var message = new CartridgeLoaderUiMessage(_activeProgram.Value, CartridgeUiMessageAction.Deactivate); + SendMessage(message); + } + + protected void InstallCartridge(EntityUid cartridgeUid) + { + var message = new CartridgeLoaderUiMessage(cartridgeUid, CartridgeUiMessageAction.Install); + SendMessage(message); + } + + protected void UninstallCartridge(EntityUid cartridgeUid) + { + var message = new CartridgeLoaderUiMessage(cartridgeUid, CartridgeUiMessageAction.Uninstall); + SendMessage(message); + } + + private List<(EntityUid, CartridgeComponent)> GetCartridgeComponents(List programs) + { + var components = new List<(EntityUid, CartridgeComponent)>(); + + foreach (var program in programs) + { + var component = RetrieveCartridgeComponent(program); + if (component is not null) + components.Add((program, component)); + } + + return components; + } + + /// + /// The implementing ui needs to add the passed ui fragment as a child to itself + /// + protected abstract void AttachCartridgeUI(Control cartridgeUIFragment, string? title); + + /// + /// The implementing ui needs to remove the passed ui from itself + /// + protected abstract void DetachCartridgeUI(Control cartridgeUIFragment); + + protected abstract void UpdateAvailablePrograms(List<(EntityUid, CartridgeComponent)> programs); + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + _activeUiFragment?.Dispose(); + } + + protected CartridgeComponent? RetrieveCartridgeComponent(EntityUid? cartridgeUid) + { + return _entityManager?.GetComponentOrNull(cartridgeUid); + } + + private void SendCartridgeUiReadyEvent(EntityUid cartridgeUid) + { + var message = new CartridgeLoaderUiMessage(cartridgeUid, CartridgeUiMessageAction.UIReady); + SendMessage(message); + } + + private CartridgeUI? RetrieveCartridgeUI(EntityUid? cartridgeUid) + { + var component = _entityManager?.GetComponentOrNull(cartridgeUid); + component?.Ui?.Setup(this); + return component?.Ui; + } +} diff --git a/Content.Client/CartridgeLoader/CartridgeLoaderSystem.cs b/Content.Client/CartridgeLoader/CartridgeLoaderSystem.cs new file mode 100644 index 0000000000..46e28d9142 --- /dev/null +++ b/Content.Client/CartridgeLoader/CartridgeLoaderSystem.cs @@ -0,0 +1,15 @@ +using Content.Shared.CartridgeLoader; + +namespace Content.Client.CartridgeLoader; + +public sealed class CartridgeLoaderSystem : SharedCartridgeLoaderSystem +{ + //Empty client system for component replication +} + +[RegisterComponent] +[ComponentReference(typeof(SharedCartridgeLoaderComponent))] +public sealed class CartridgeLoaderComponent : SharedCartridgeLoaderComponent +{ + +} diff --git a/Content.Client/CartridgeLoader/CartridgeUI.cs b/Content.Client/CartridgeLoader/CartridgeUI.cs new file mode 100644 index 0000000000..7cbeb499ca --- /dev/null +++ b/Content.Client/CartridgeLoader/CartridgeUI.cs @@ -0,0 +1,25 @@ +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; + +namespace Content.Client.CartridgeLoader; + +/// +/// Cartridge ui fragments need to inherit this class. The subclass is then used in yaml to tell the cartridge loader ui to use it as the cartridges ui fragment. +/// +/// +/// This is an example from the yaml definition from the notekeeper ui +/// +/// - type: CartridgeUi +/// ui: !type:NotekeeperUi +/// +/// +[ImplicitDataDefinitionForInheritors] +public abstract class CartridgeUI +{ + public abstract Control GetUIFragmentRoot(); + + public abstract void Setup(BoundUserInterface userInterface); + + public abstract void UpdateState(BoundUserInterfaceState state); + +} diff --git a/Content.Client/CartridgeLoader/CartridgeUISerializer.cs b/Content.Client/CartridgeLoader/CartridgeUISerializer.cs new file mode 100644 index 0000000000..a107177918 --- /dev/null +++ b/Content.Client/CartridgeLoader/CartridgeUISerializer.cs @@ -0,0 +1,44 @@ +using Robust.Shared.Serialization.Manager; +using Robust.Shared.Serialization.Markdown; +using Robust.Shared.Serialization.Markdown.Validation; +using Robust.Shared.Serialization.Markdown.Value; +using Robust.Shared.Serialization.TypeSerializers.Interfaces; + +namespace Content.Client.CartridgeLoader; + +/// +/// Boilerplate serializer for defining the ui fragment used for a cartridge in yaml +/// +/// +/// This is an example from the yaml definition from the notekeeper ui +/// +/// - type: CartridgeUi +/// ui: !type:NotekeeperUi +/// +/// +public sealed class CartridgeUISerializer : ITypeSerializer +{ + public ValidationNode Validate(ISerializationManager serializationManager, ValueDataNode node, + IDependencyCollection dependencies, ISerializationContext? context = null) + { + return serializationManager.ValidateNode(node, context); + } + + public CartridgeUI Read(ISerializationManager serializationManager, ValueDataNode node, IDependencyCollection dependencies, + bool skipHook, ISerializationContext? context = null, CartridgeUI? value = default) + { + return serializationManager.Read(node, context, skipHook, value); + } + + public CartridgeUI Copy(ISerializationManager serializationManager, CartridgeUI source, CartridgeUI target, bool skipHook, + ISerializationContext? context = null) + { + return serializationManager.Copy(source, context, skipHook); + } + + public DataNode Write(ISerializationManager serializationManager, CartridgeUI value, IDependencyCollection dependencies, + bool alwaysWrite = false, ISerializationContext? context = null) + { + return serializationManager.WriteValue(value, alwaysWrite, context); + } +} diff --git a/Content.Client/CartridgeLoader/CartridgeUiComponent.cs b/Content.Client/CartridgeLoader/CartridgeUiComponent.cs new file mode 100644 index 0000000000..a4b8443ccc --- /dev/null +++ b/Content.Client/CartridgeLoader/CartridgeUiComponent.cs @@ -0,0 +1,14 @@ + +namespace Content.Client.CartridgeLoader; + +/// +/// The component used for defining which ui fragment to use for a cartridge +/// +/// +/// +[RegisterComponent] +public sealed class CartridgeUiComponent : Component +{ + [DataField("ui", true, customTypeSerializer: typeof(CartridgeUISerializer))] + public CartridgeUI? Ui = default; +} diff --git a/Content.Client/CartridgeLoader/Cartridges/NotekeeperUi.cs b/Content.Client/CartridgeLoader/Cartridges/NotekeeperUi.cs new file mode 100644 index 0000000000..df4667ed2a --- /dev/null +++ b/Content.Client/CartridgeLoader/Cartridges/NotekeeperUi.cs @@ -0,0 +1,39 @@ +using Content.Shared.CartridgeLoader; +using Content.Shared.CartridgeLoader.Cartridges; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; + +namespace Content.Client.CartridgeLoader.Cartridges; + +public sealed class NotekeeperUi : CartridgeUI +{ + private NotekeeperUiFragment? _fragment; + + + public override Control GetUIFragmentRoot() + { + return _fragment!; + } + + public override void Setup(BoundUserInterface userInterface) + { + _fragment = new NotekeeperUiFragment(); + _fragment.OnNoteRemoved += note => SendNotekeeperMessage(NotekeeperUiAction.Remove, note, userInterface); + _fragment.OnNoteAdded += note => SendNotekeeperMessage(NotekeeperUiAction.Add, note, userInterface); + } + + public override void UpdateState(BoundUserInterfaceState state) + { + if (state is not NotekeeperUiState notekeepeerState) + return; + + _fragment?.UpdateState(notekeepeerState.Notes); + } + + private void SendNotekeeperMessage(NotekeeperUiAction action, string note, BoundUserInterface userInterface) + { + var notekeeperMessage = new NotekeeperUiMessageEvent(action, note); + var message = new CartridgeUiMessage(notekeeperMessage); + userInterface.SendMessage(message); + } +} diff --git a/Content.Client/CartridgeLoader/Cartridges/NotekeeperUiFragment.xaml b/Content.Client/CartridgeLoader/Cartridges/NotekeeperUiFragment.xaml new file mode 100644 index 0000000000..ed79d0f795 --- /dev/null +++ b/Content.Client/CartridgeLoader/Cartridges/NotekeeperUiFragment.xaml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/Content.Client/CartridgeLoader/Cartridges/NotekeeperUiFragment.xaml.cs b/Content.Client/CartridgeLoader/Cartridges/NotekeeperUiFragment.xaml.cs new file mode 100644 index 0000000000..2504407fa9 --- /dev/null +++ b/Content.Client/CartridgeLoader/Cartridges/NotekeeperUiFragment.xaml.cs @@ -0,0 +1,62 @@ +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; + +namespace Content.Client.CartridgeLoader.Cartridges; + +[GenerateTypedNameReferences] +public sealed partial class NotekeeperUiFragment : BoxContainer +{ + + public event Action? OnNoteAdded; + public event Action? OnNoteRemoved; + + public NotekeeperUiFragment() + { + RobustXamlLoader.Load(this); + Orientation = LayoutOrientation.Vertical; + HorizontalExpand = true; + VerticalExpand = true; + + Input.OnTextEntered += _ => + { + AddNote(Input.Text); + OnNoteAdded?.Invoke(Input.Text); + Input.Clear(); + }; + + UpdateState(new List()); + } + + public void UpdateState(List notes) + { + MessageContainer.RemoveAllChildren(); + + foreach (var note in notes) + { + AddNote(note); + } + } + + private void AddNote(string note) + { + var row = new BoxContainer(); + row.HorizontalExpand = true; + row.Orientation = LayoutOrientation.Horizontal; + row.Margin = new Thickness(4); + + var label = new Label(); + label.Text = note; + label.HorizontalExpand = true; + label.ClipText = true; + + var removeButton = new TextureButton(); + removeButton.AddStyleClass("windowCloseButton"); + removeButton.OnPressed += _ => OnNoteRemoved?.Invoke(label.Text); + + row.AddChild(label); + row.AddChild(removeButton); + + MessageContainer.AddChild(row); + } +} diff --git a/Content.Client/PDA/PDABorderColorComponent.cs b/Content.Client/PDA/PDABorderColorComponent.cs new file mode 100644 index 0000000000..c9af50d2f5 --- /dev/null +++ b/Content.Client/PDA/PDABorderColorComponent.cs @@ -0,0 +1,19 @@ +namespace Content.Client.PDA; + +/// +/// Used for specifying the pda windows border colors +/// +[RegisterComponent] +public sealed class PDABorderColorComponent : Component +{ + [DataField("borderColor", required: true)] + public string? BorderColor; + + + [DataField("accentHColor")] + public string? AccentHColor; + + + [DataField("accentVColor")] + public string? AccentVColor; +} diff --git a/Content.Client/PDA/PDABoundUserInterface.cs b/Content.Client/PDA/PDABoundUserInterface.cs index 6fcc316acb..52507df703 100644 --- a/Content.Client/PDA/PDABoundUserInterface.cs +++ b/Content.Client/PDA/PDABoundUserInterface.cs @@ -1,17 +1,20 @@ -using Content.Client.Message; +using Content.Client.CartridgeLoader; +using Content.Shared.CartridgeLoader; using Content.Shared.CCVar; using Content.Shared.Containers.ItemSlots; using Content.Shared.CrewManifest; using Content.Shared.PDA; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Configuration; namespace Content.Client.PDA { [UsedImplicitly] - public sealed class PDABoundUserInterface : BoundUserInterface + public sealed class PDABoundUserInterface : CartridgeLoaderBoundUserInterface { + [Dependency] private readonly IEntityManager? _entityManager = default!; [Dependency] private readonly IConfigurationManager _configManager = default!; private PDAMenu? _menu; @@ -67,54 +70,52 @@ namespace Content.Client.PDA SendMessage(new PDAShowRingtoneMessage()); }; + _menu.OnProgramItemPressed += ActivateCartridge; + _menu.OnInstallButtonPressed += InstallCartridge; + _menu.OnUninstallButtonPressed += UninstallCartridge; + _menu.ProgramCloseButton.OnPressed += _ => DeactivateActiveCartridge(); + + var borderColorComponent = GetBorderColorComponent(); + if (borderColorComponent == null) + return; + + _menu.BorderColor = borderColorComponent.BorderColor; + _menu.AccentHColor = borderColorComponent.AccentHColor; + _menu.AccentVColor = borderColorComponent.AccentVColor; } protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); - if (_menu == null) - { + if (state is not PDAUpdateState updateState) return; - } - switch (state) - { - case PDAUpdateState msg: - { - _menu.FlashLightToggleButton.Pressed = msg.FlashlightEnabled; - - if (msg.PDAOwnerInfo.ActualOwnerName != null) - { - _menu.PdaOwnerLabel.SetMarkup(Loc.GetString("comp-pda-ui-owner", - ("ActualOwnerName", msg.PDAOwnerInfo.ActualOwnerName))); - } - - - if (msg.PDAOwnerInfo.IdOwner != null || msg.PDAOwnerInfo.JobTitle != null) - { - _menu.IdInfoLabel.SetMarkup(Loc.GetString("comp-pda-ui", - ("Owner",msg.PDAOwnerInfo.IdOwner ?? Loc.GetString("comp-pda-ui-unknown")), - ("JobTitle",msg.PDAOwnerInfo.JobTitle ?? Loc.GetString("comp-pda-ui-unassigned")))); - } - else - { - _menu.IdInfoLabel.SetMarkup(Loc.GetString("comp-pda-ui-blank")); - } - - _menu.StationNameLabel.SetMarkup(Loc.GetString("comp-pda-ui-station", ("Station",msg.StationName ?? Loc.GetString("comp-pda-ui-unknown")))); - - _menu.EjectIdButton.Visible = msg.PDAOwnerInfo.IdOwner != null || msg.PDAOwnerInfo.JobTitle != null; - _menu.EjectPenButton.Visible = msg.HasPen; - _menu.ActivateUplinkButton.Visible = msg.HasUplink; - _menu.ActivateMusicButton.Visible = msg.CanPlayMusic; - - break; - } - } + _menu?.UpdateState(updateState); } + protected override void AttachCartridgeUI(Control cartridgeUIFragment, string? title) + { + _menu?.ProgramView.AddChild(cartridgeUIFragment); + _menu?.ToProgramView(title ?? Loc.GetString("comp-pda-io-program-fallback-title")); + } + + protected override void DetachCartridgeUI(Control cartridgeUIFragment) + { + if (_menu is null) + return; + + _menu.ToHomeScreen(); + _menu.HideProgramHeader(); + _menu.ProgramView.RemoveChild(cartridgeUIFragment); + } + + protected override void UpdateAvailablePrograms(List<(EntityUid, CartridgeComponent)> programs) + { + _menu?.UpdateAvailablePrograms(programs); + } + protected override void Dispose(bool disposing) { base.Dispose(disposing); @@ -123,5 +124,10 @@ namespace Content.Client.PDA _menu?.Dispose(); } + + private PDABorderColorComponent? GetBorderColorComponent() + { + return _entityManager?.GetComponentOrNull(Owner.Owner); + } } } diff --git a/Content.Client/PDA/PDAMenu.xaml b/Content.Client/PDA/PDAMenu.xaml index 712e9f6d7d..d54de2c6bb 100644 --- a/Content.Client/PDA/PDAMenu.xaml +++ b/Content.Client/PDA/PDAMenu.xaml @@ -1,12 +1,32 @@ - - + + + + + + + + + + + + + + + + + + + MinSize="50 50" + Margin="8"> - + + + + diff --git a/Content.Client/PDA/PDAProgramItem.xaml.cs b/Content.Client/PDA/PDAProgramItem.xaml.cs new file mode 100644 index 0000000000..5cc16da497 --- /dev/null +++ b/Content.Client/PDA/PDAProgramItem.xaml.cs @@ -0,0 +1,42 @@ +using Robust.Client.AutoGenerated; +using Robust.Client.Graphics; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Input; + +namespace Content.Client.PDA; + +[GenerateTypedNameReferences] +public sealed partial class PDAProgramItem : ContainerButton +{ + public const string StylePropertyBgColor = "backgroundColor"; + public const string NormalBgColor = "#313138"; + public const string HoverColor = "#3E6C45"; + + private readonly StyleBoxFlat _styleBox = new() + { + BackgroundColor = Color.FromHex("#25252a"), + }; + + public Color BackgroundColor + { + get => _styleBox.BackgroundColor; + set => _styleBox.BackgroundColor = value; + } + + public PDAProgramItem() + { + RobustXamlLoader.Load(this); + Panel.PanelOverride = _styleBox; + } + + protected override void Draw(DrawingHandleScreen handle) + { + base.Draw(handle); + + if (TryGetStyleProperty(StylePropertyBgColor, out var bgColor)) + BackgroundColor = bgColor; + + } +} diff --git a/Content.Client/PDA/PDASettingsButton.xaml b/Content.Client/PDA/PDASettingsButton.xaml new file mode 100644 index 0000000000..39bd560324 --- /dev/null +++ b/Content.Client/PDA/PDASettingsButton.xaml @@ -0,0 +1,11 @@ + + + + + diff --git a/Content.Client/PDA/PDASettingsButton.xaml.cs b/Content.Client/PDA/PDASettingsButton.xaml.cs new file mode 100644 index 0000000000..0fb4ffb596 --- /dev/null +++ b/Content.Client/PDA/PDASettingsButton.xaml.cs @@ -0,0 +1,69 @@ +using Robust.Client.AutoGenerated; +using Robust.Client.Graphics; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; + +namespace Content.Client.PDA; + +[GenerateTypedNameReferences] +public sealed partial class PDASettingsButton : ContainerButton +{ + public const string StylePropertyFgColor = "foregroundColor"; + public const string StylePropertyBgColor = "backgroundColor"; + public const string NormalBgColor = "#313138"; + public const string HoverColor = "#3E6C45"; + public const string PressedColor = "#3E6C45"; + public const string DisabledFgColor = "#5a5a5a"; + public const string EnabledFgColor = "#FFFFFF"; + + private readonly StyleBoxFlat _styleBox = new() + { + BackgroundColor = Color.FromHex("#25252a") + }; + + public string? Text + { + get => OptionName.Text; + set => OptionName.Text = value; + } + public string? Description + { + get => OptionDescription.Text; + set => OptionDescription.Text = value; + } + + public Color BackgroundColor + { + get => _styleBox.BackgroundColor; + set => _styleBox.BackgroundColor = value; + } + + public Color? ForegroundColor + { + get => OptionName.FontColorOverride; + + set + { + OptionName.FontColorOverride = value; + OptionDescription.FontColorOverride = value; + } + } + + public PDASettingsButton() + { + RobustXamlLoader.Load(this); + Panel.PanelOverride = _styleBox; + } + + protected override void Draw(DrawingHandleScreen handle) + { + base.Draw(handle); + + if (TryGetStyleProperty(StylePropertyBgColor, out var bgColor)) + BackgroundColor = bgColor; + + if (TryGetStyleProperty(StylePropertyFgColor, out var fgColor)) + ForegroundColor = fgColor; + + } +} diff --git a/Content.Client/PDA/PDAWindow.xaml b/Content.Client/PDA/PDAWindow.xaml new file mode 100644 index 0000000000..fd6ec57ebe --- /dev/null +++ b/Content.Client/PDA/PDAWindow.xaml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content.Client/PDA/PDAWindow.xaml.cs b/Content.Client/PDA/PDAWindow.xaml.cs new file mode 100644 index 0000000000..8b39d744cd --- /dev/null +++ b/Content.Client/PDA/PDAWindow.xaml.cs @@ -0,0 +1,56 @@ +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.CustomControls; +using Robust.Client.UserInterface.XAML; + +namespace Content.Client.PDA; + +[Virtual] +[GenerateTypedNameReferences] +public partial class PDAWindow : BaseWindow +{ + + public string? BorderColor + { + get => Background.ActualModulateSelf.ToHex(); + + set => Background.ModulateSelfOverride = Color.FromHex(value, Color.White); + } + + public string? AccentHColor + { + get => AccentH.ActualModulateSelf.ToHex(); + + set + { + AccentH.ModulateSelfOverride = Color. FromHex(value, Color.White); + AccentH.Visible = value != null; + } + } + + public string? AccentVColor + { + get => AccentV.ActualModulateSelf.ToHex(); + + set + { + AccentV.ModulateSelfOverride = Color. FromHex(value, Color.White); + AccentV.Visible = value != null; + } + } + + public PDAWindow() + { + RobustXamlLoader.Load(this); + + CloseButton.OnPressed += _ => Close(); + XamlChildren = ContentsContainer.Children; + + AccentH.Visible = false; + AccentV.Visible = false; + } + + protected override DragMode GetDragModeFor(Vector2 relativeMousePos) + { + return DragMode.Move; + } +} diff --git a/Content.Client/Stylesheets/StyleBase.cs b/Content.Client/Stylesheets/StyleBase.cs index d8df98197e..0a7cac910d 100644 --- a/Content.Client/Stylesheets/StyleBase.cs +++ b/Content.Client/Stylesheets/StyleBase.cs @@ -38,6 +38,7 @@ namespace Content.Client.Stylesheets protected StyleBoxTexture BaseButtonSquare { get; } protected StyleBoxTexture BaseAngleRect { get; } + protected StyleBoxTexture AngleBorderRect { get; } protected StyleBase(IResourceCache resCache) { @@ -114,6 +115,12 @@ namespace Content.Client.Stylesheets }; BaseAngleRect.SetPatchMargin(StyleBox.Margin.All, 10); + AngleBorderRect = new StyleBoxTexture + { + Texture = resCache.GetTexture("/Textures/Interface/Nano/geometric_panel_border.svg.96dpi.png"), + }; + AngleBorderRect.SetPatchMargin(StyleBox.Margin.All, 10); + var vScrollBarGrabberNormal = new StyleBoxFlat { BackgroundColor = Color.Gray.WithAlpha(0.35f), ContentMarginLeftOverride = DefaultGrabberSize, diff --git a/Content.Client/Stylesheets/StyleNano.cs b/Content.Client/Stylesheets/StyleNano.cs index 33da24088a..c5dd457ee8 100644 --- a/Content.Client/Stylesheets/StyleNano.cs +++ b/Content.Client/Stylesheets/StyleNano.cs @@ -1,9 +1,8 @@ using System.Linq; -using Content.Client.Actions.UI; using Content.Client.ContextMenu.UI; using Content.Client.Examine; +using Content.Client.PDA; using Content.Client.Resources; -using Content.Client.Targeting; using Content.Client.Targeting.UI; using Content.Client.UserInterface.Controls; using Content.Client.Verbs.UI; @@ -13,7 +12,6 @@ using Robust.Client.ResourceManagement; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; -using Robust.Shared.Maths; using static Robust.Client.UserInterface.StylesheetHelpers; namespace Content.Client.Stylesheets @@ -1395,6 +1393,60 @@ namespace Content.Client.Stylesheets Element