using Content.Client.Resources; using Content.Client.Stylesheets; using Content.Shared.Temperature; using Robust.Client.Graphics; using Robust.Client.ResourceManagement; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Maths; using static Content.Shared.Atmos.Components.SharedGasAnalyzerComponent; using static Robust.Client.UserInterface.Controls.BoxContainer; namespace Content.Client.Atmos.UI { public sealed class GasAnalyzerWindow : BaseWindow { public GasAnalyzerBoundUserInterface Owner { get; } private readonly Control _topContainer; private readonly Control _statusContainer; private readonly Label _nameLabel; public TextureButton CloseButton { get; set; } public GasAnalyzerWindow(GasAnalyzerBoundUserInterface owner) { var resourceCache = IoCManager.Resolve(); Owner = owner; var rootContainer = new LayoutContainer { Name = "WireRoot" }; AddChild(rootContainer); MouseFilter = MouseFilterMode.Stop; var panelTex = resourceCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); var back = new StyleBoxTexture { Texture = panelTex, Modulate = Color.FromHex("#25252A"), }; back.SetPatchMargin(StyleBox.Margin.All, 10); var topPanel = new PanelContainer { PanelOverride = back, MouseFilter = MouseFilterMode.Pass }; var bottomWrap = new LayoutContainer { Name = "BottomWrap" }; rootContainer.AddChild(topPanel); rootContainer.AddChild(bottomWrap); LayoutContainer.SetAnchorPreset(topPanel, LayoutContainer.LayoutPreset.Wide); LayoutContainer.SetMarginBottom(topPanel, -80); LayoutContainer.SetAnchorPreset(bottomWrap, LayoutContainer.LayoutPreset.VerticalCenterWide); LayoutContainer.SetGrowHorizontal(bottomWrap, LayoutContainer.GrowDirection.Both); var topContainerWrap = new BoxContainer { Orientation = LayoutOrientation.Vertical, Children = { (_topContainer = new BoxContainer { Orientation = LayoutOrientation.Vertical }), new Control {MinSize = (0, 110)} } }; rootContainer.AddChild(topContainerWrap); LayoutContainer.SetAnchorPreset(topContainerWrap, LayoutContainer.LayoutPreset.Wide); var font = resourceCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); var fontSmall = resourceCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 10); Button refreshButton; var topRow = new BoxContainer { Orientation = LayoutOrientation.Horizontal, Margin = new Thickness(4, 4, 12, 2), Children = { (_nameLabel = new Label { Text = Loc.GetString("gas-analyzer-window-name"), FontOverride = font, FontColorOverride = StyleNano.NanoGold, VerticalAlignment = VAlignment.Center }), new Control { MinSize = (20, 0), HorizontalExpand = true, }, (refreshButton = new Button {Text = Loc.GetString("gas-analyzer-window-refresh-button")}), //TODO: refresh icon? new Control { MinSize = (2, 0), }, (CloseButton = new TextureButton { StyleClasses = {DefaultWindow.StyleClassWindowCloseButton}, VerticalAlignment = VAlignment.Center }) } }; refreshButton.OnPressed += a => { Owner.Refresh(); }; var middle = new PanelContainer { PanelOverride = new StyleBoxFlat { BackgroundColor = Color.FromHex("#202025") }, Children = { (_statusContainer = new BoxContainer { Orientation = LayoutOrientation.Vertical, Margin = new Thickness(8, 8, 4, 4) }) } }; _topContainer.AddChild(topRow); _topContainer.AddChild(new PanelContainer { MinSize = (0, 2), PanelOverride = new StyleBoxFlat { BackgroundColor = Color.FromHex("#525252ff") } }); _topContainer.AddChild(middle); _topContainer.AddChild(new PanelContainer { MinSize = (0, 2), PanelOverride = new StyleBoxFlat { BackgroundColor = Color.FromHex("#525252ff") } }); CloseButton.OnPressed += _ => Close(); SetSize = (300, 200); } public void Populate(GasAnalyzerBoundUserInterfaceState state) { _statusContainer.RemoveAllChildren(); if (state.Error != null) { _statusContainer.AddChild(new Label { Text = Loc.GetString("gas-analyzer-window-error-text", ("errorText", state.Error)), FontColorOverride = Color.Red }); return; } _statusContainer.AddChild(new Label { Text = Loc.GetString("gas-analyzer-window-pressure-text", ("pressure", $"{state.Pressure:0.##}")) }); _statusContainer.AddChild(new Label { Text = Loc.GetString("gas-analyzer-window-temperature-text", ("tempK", $"{state.Temperature:0.#}"), ("tempC", $"{TemperatureHelpers.KelvinToCelsius(state.Temperature):0.#}")) }); // Return here cause all that stuff down there is gas stuff (so we don't get the seperators) if (state.Gases == null || state.Gases.Length == 0) { return; } // Seperator _statusContainer.AddChild(new Control { MinSize = new Vector2(0, 10) }); // Add a table with all the gases var tableKey = new BoxContainer { Orientation = LayoutOrientation.Vertical }; var tableVal = new BoxContainer { Orientation = LayoutOrientation.Vertical }; _statusContainer.AddChild(new BoxContainer { Orientation = LayoutOrientation.Horizontal, Children = { tableKey, new Control { MinSize = new Vector2(20, 0) }, tableVal } }); // This is the gas bar thingy var height = 30; var minSize = 24; // This basically allows gases which are too small, to be shown properly var gasBar = new BoxContainer { Orientation = LayoutOrientation.Horizontal, HorizontalExpand = true, MinSize = new Vector2(0, height) }; // Seperator _statusContainer.AddChild(new Control { MinSize = new Vector2(0, 10) }); var totalGasAmount = 0f; foreach (var gas in state.Gases) { totalGasAmount += gas.Amount; } for (int i = 0; i < state.Gases.Length; i++) { var gas = state.Gases[i]; var color = Color.FromHex($"#{gas.Color}", Color.White); // Add to the table tableKey.AddChild(new Label { Text = Loc.GetString(gas.Name) }); tableVal.AddChild(new Label { Text = Loc.GetString("gas-analyzer-window-molality-text", ("mol", $"{gas.Amount:0.##}")) }); // Add to the gas bar //TODO: highlight the currently hover one var left = (i == 0) ? 0f : 2f; var right = (i == state.Gases.Length - 1) ? 0f : 2f; gasBar.AddChild(new PanelContainer { ToolTip = Loc.GetString("gas-analyzer-window-molality-percentage-text", ("gasName", gas.Name), ("amount", $"{gas.Amount:0.##}"), ("percentage", $"{(gas.Amount / totalGasAmount * 100):0.#}")), HorizontalExpand = true, SizeFlagsStretchRatio = gas.Amount, MouseFilter = MouseFilterMode.Pass, PanelOverride = new StyleBoxFlat { BackgroundColor = color, PaddingLeft = left, PaddingRight = right }, MinSize = new Vector2(minSize, 0) }); } _statusContainer.AddChild(gasBar); } protected override DragMode GetDragModeFor(Vector2 relativeMousePos) { return DragMode.Move; } protected override bool HasPoint(Vector2 point) { // This makes it so our base window won't count for hit tests, // but we will still receive mouse events coming in from Pass mouse filter mode. // So basically, it perfectly shells out the hit tests to the panels we have! return false; } } }