using System.Collections.Generic; using Content.Client.Stylesheets; using Content.Client.UserInterface; using Content.Shared.Chemistry.Dispenser; using Content.Shared.Chemistry.Reagent; using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.XAML; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Prototypes; using static Content.Shared.Chemistry.Dispenser.SharedReagentDispenserComponent; using static Robust.Client.UserInterface.Controls.BoxContainer; namespace Content.Client.Chemistry.UI { /// /// Client-side UI used to control a /// [GenerateTypedNameReferences] public partial class ReagentDispenserWindow : DefaultWindow { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; /// /// Create and initialize the dispenser UI client-side. Creates the basic layout, /// actual data isn't filled in until the server sends data about the dispenser. /// public ReagentDispenserWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); var dispenseAmountGroup = new ButtonGroup(); DispenseButton1.Group = dispenseAmountGroup; DispenseButton5.Group = dispenseAmountGroup; DispenseButton10.Group = dispenseAmountGroup; DispenseButton15.Group = dispenseAmountGroup; DispenseButton20.Group = dispenseAmountGroup; DispenseButton25.Group = dispenseAmountGroup; DispenseButton30.Group = dispenseAmountGroup; DispenseButton50.Group = dispenseAmountGroup; DispenseButton100.Group = dispenseAmountGroup; } /// /// Update the button grid of reagents which can be dispensed. /// The actions for these buttons are set in . /// /// Reagents which can be dispensed by this dispenser public void UpdateReagentsList(List inventory) { if (ChemicalList == null) return; if (inventory == null) return; ChemicalList.Children.Clear(); foreach (var entry in inventory) { if (_prototypeManager.TryIndex(entry.ID, out ReagentPrototype? proto)) { ChemicalList.AddChild(new Button {Text = proto.Name}); } else { ChemicalList.AddChild(new Button {Text = Loc.GetString("reagent-dispenser-window-reagent-name-not-found-text") }); } } } /// /// Update the UI state when new state data is received from the server. /// /// State data sent by the server. public void UpdateState(BoundUserInterfaceState state) { var castState = (ReagentDispenserBoundUserInterfaceState) state; Title = castState.DispenserName; UpdateContainerInfo(castState); // Disable all buttons if not powered if (Contents.Children != null) { ButtonHelpers.SetButtonDisabledRecursive(Contents, !castState.HasPower); EjectButton.Disabled = false; } // Disable the Clear & Eject button if no beaker if (!castState.HasBeaker) { ClearButton.Disabled = true; EjectButton.Disabled = true; } switch (castState.SelectedDispenseAmount.Int()) { case 1: DispenseButton1.Pressed = true; break; case 5: DispenseButton5.Pressed = true; break; case 10: DispenseButton10.Pressed = true; break; case 15: DispenseButton15.Pressed = true; break; case 20: DispenseButton20.Pressed = true; break; case 25: DispenseButton25.Pressed = true; break; case 30: DispenseButton30.Pressed = true; break; case 50: DispenseButton50.Pressed = true; break; case 100: DispenseButton100.Pressed = true; break; } } /// /// Update the fill state and list of reagents held by the current reagent container, if applicable. /// Also highlights a reagent if it's dispense button is being mouse hovered. /// /// State data for the dispenser. /// Prototype id of the reagent whose dispense button is currently being mouse hovered. public void UpdateContainerInfo(ReagentDispenserBoundUserInterfaceState state, string highlightedReagentId = "") { ContainerInfo.Children.Clear(); if (!state.HasBeaker) { ContainerInfo.Children.Add(new Label {Text = Loc.GetString("reagent-dispenser-window-no-container-loaded-text") }); return; } ContainerInfo.Children.Add(new BoxContainer // Name of the container and its fill status (Ex: 44/100u) { Orientation = LayoutOrientation.Horizontal, Children = { new Label {Text = $"{state.ContainerName}: "}, new Label { Text = $"{state.BeakerCurrentVolume}/{state.BeakerMaxVolume}", StyleClasses = {StyleNano.StyleClassLabelSecondaryColor} } } }); if (state.ContainerReagents == null) { return; } foreach (var reagent in state.ContainerReagents) { var name = Loc.GetString("reagent-dispenser-window-unknown-reagent-text"); //Try to the prototype for the given reagent. This gives us it's name. if (_prototypeManager.TryIndex(reagent.ReagentId, out ReagentPrototype? proto)) { name = proto.Name; } //Check if the reagent is being moused over. If so, color it green. if (proto != null && proto.ID == highlightedReagentId) { ContainerInfo.Children.Add(new BoxContainer { Orientation = LayoutOrientation.Horizontal, Children = { new Label { Text = $"{name}: ", StyleClasses = {StyleNano.StyleClassPowerStateGood} }, new Label { Text = Loc.GetString("reagent-dispenser-window-quantity-label-text", ("quantity", reagent.Quantity)), StyleClasses = {StyleNano.StyleClassPowerStateGood} } } }); } else //Otherwise, color it the normal colors. { ContainerInfo.Children.Add(new BoxContainer { Orientation = LayoutOrientation.Horizontal, Children = { new Label {Text = $"{name}: "}, new Label { Text = Loc.GetString("reagent-dispenser-window-quantity-label-text", ("quantity", reagent.Quantity)), StyleClasses = {StyleNano.StyleClassLabelSecondaryColor} } } }); } } } } }