Gas Analyzer can now scan pipes/devices along with the environment (#10976)

This commit is contained in:
theashtronaut
2022-09-08 14:22:14 +00:00
committed by GitHub
parent ae8fe43529
commit 868abaca5c
23 changed files with 826 additions and 758 deletions

View File

@@ -1,77 +1,9 @@
using Content.Client.Items.Components;
using Content.Client.Message;
using Content.Client.Stylesheets;
using Content.Shared.Atmos.Components;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.GameObjects;
using Robust.Shared.Localization;
using Robust.Shared.Timing;
using Robust.Shared.ViewVariables;
namespace Content.Client.Atmos.Components
{
[RegisterComponent]
internal sealed class GasAnalyzerComponent : SharedGasAnalyzerComponent, IItemStatus
internal sealed class GasAnalyzerComponent : SharedGasAnalyzerComponent
{
[ViewVariables(VVAccess.ReadWrite)] private bool _uiUpdateNeeded;
[ViewVariables] private GasAnalyzerDanger Danger { get; set; }
Control IItemStatus.MakeControl()
{
return new StatusControl(this);
}
/// <inheritdoc />
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
{
if (curState is not GasAnalyzerComponentState state)
return;
Danger = state.Danger;
_uiUpdateNeeded = true;
}
private sealed class StatusControl : Control
{
private readonly GasAnalyzerComponent _parent;
private readonly RichTextLabel _label;
public StatusControl(GasAnalyzerComponent parent)
{
_parent = parent;
_label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
AddChild(_label);
Update();
}
/// <inheritdoc />
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
if (!_parent._uiUpdateNeeded)
{
return;
}
Update();
}
public void Update()
{
_parent._uiUpdateNeeded = false;
var color = _parent.Danger switch
{
GasAnalyzerDanger.Warning => "orange",
GasAnalyzerDanger.Hazard => "red",
_ => "green",
};
_label.SetMarkup(Loc.GetString("itemstatus-pressure-warn", ("color", color), ("danger", _parent.Danger)));
}
}
}
}

View File

@@ -1,5 +1,4 @@
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using static Content.Shared.Atmos.Components.SharedGasAnalyzerComponent;
namespace Content.Client.Atmos.UI
@@ -10,34 +9,41 @@ namespace Content.Client.Atmos.UI
{
}
private GasAnalyzerWindow? _menu;
private GasAnalyzerWindow? _window;
protected override void Open()
{
base.Open();
_menu = new GasAnalyzerWindow(this);
_menu.OnClose += Close;
_menu.OpenCentered();
_window = new GasAnalyzerWindow(this);
_window.OnClose += OnClose;
_window.OpenCentered();
}
protected override void UpdateState(BoundUserInterfaceState state)
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
{
base.UpdateState(state);
_menu?.Populate((GasAnalyzerBoundUserInterfaceState) state);
if (_window == null)
return;
if (message is not GasAnalyzerUserMessage cast)
return;
_window.Populate(cast);
}
public void Refresh()
/// <summary>
/// Closes UI and tells the server to disable the analyzer
/// </summary>
private void OnClose()
{
SendMessage(new GasAnalyzerRefreshMessage());
SendMessage(new GasAnalyzerDisableMessage());
Close();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing) _menu?.Dispose();
if (disposing)
_window?.Dispose();
}
}
}

View File

@@ -1,282 +0,0 @@
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<IResourceCache>();
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, 420);
}
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;
}
}
}

View File

@@ -0,0 +1,46 @@
<DefaultWindow xmlns="https://spacestation14.io"
MinSize="270 420"
SetSize="315 420" Title="{Loc 'gas-analyzer-window-name'}">
<BoxContainer Orientation="Vertical" Margin="5 5 5 5">
<BoxContainer Name="CTopBox" Orientation="Horizontal"/>
<!-- Gas Mix Data, Populated by function -->
<TabContainer Name="CTabContainer" VerticalExpand="True" Margin="1 1 1 2">
<!-- Scanned device mix data -->
<ScrollContainer VerticalExpand="True">
<BoxContainer HorizontalExpand="True" VerticalExpand="True" Orientation="Vertical">
<GridContainer Name="CDeviceGrid" Columns="3" Rows="1" VerticalExpand="True" HorizontalExpand="True">
<BoxContainer Orientation="Vertical" VerticalExpand="True">
<Control MinHeight="5"/>
<Label Name="LeftPanelLabel" HorizontalExpand="True" Align="Center"/>
<Control MinHeight="27"/>
<BoxContainer Name="LeftPanel" VerticalExpand="True" HorizontalExpand="True" Margin="1 1 1 1" MinSize="315 150" Align="Center" Visible="False"/>
</BoxContainer>
<BoxContainer Orientation="Vertical" VerticalExpand="True">
<SpriteView Name="GridIcon"
MinSize="32 32"
OverrideDirection="North"
RectClipContent="True"/>
<Label Name="MiddlePanelLabel" HorizontalExpand="True" Align="Center"/>
<BoxContainer Name="MiddlePanel" VerticalExpand="True" HorizontalExpand="True" Margin="1 1 1 1" MinSize="315 150" Align="Center" Visible="False"/>
</BoxContainer>
<BoxContainer Orientation="Vertical" VerticalExpand="True">
<Control MinHeight="5"/>
<Label Name="RightPanelLabel" HorizontalExpand="True" Align="Center"/>
<Control MinHeight="27"/>
<BoxContainer Name="RightPanel" VerticalExpand="True" HorizontalExpand="True" Margin="1 1 1 1" MinSize="315 150" Align="Center" Visible="False"/>
</BoxContainer>
</GridContainer>
<!-- this is for any leftover mixes for > trinary, but it'll look really ugly -->
<BoxContainer Name="CDeviceMixes" HorizontalExpand="True" Orientation="Horizontal">
</BoxContainer>
</BoxContainer>
</ScrollContainer>
<!-- Environment mix data -->
<ScrollContainer VerticalExpand="True">
<BoxContainer Name="CEnvironmentMix" Orientation="Vertical" VerticalExpand="True" Margin="1 1 1 1" MinSize="315 150" Align="Center">
</BoxContainer>
</ScrollContainer>
</TabContainer>
</BoxContainer>
</DefaultWindow>

View File

@@ -0,0 +1,326 @@
using Content.Shared.Atmos;
using Content.Shared.Temperature;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface.XAML;
using static Content.Shared.Atmos.Components.SharedGasAnalyzerComponent;
namespace Content.Client.Atmos.UI
{
[GenerateTypedNameReferences]
public sealed partial class GasAnalyzerWindow : DefaultWindow
{
private GasAnalyzerBoundUserInterface _owner;
private IEntityManager _entityManager;
public GasAnalyzerWindow(GasAnalyzerBoundUserInterface owner)
{
RobustXamlLoader.Load(this);
_entityManager = IoCManager.Resolve<IEntityManager>();
_owner = owner;
}
public void Populate(GasAnalyzerUserMessage msg)
{
if (msg.Error != null)
{
CTopBox.AddChild(new Label
{
Text = Loc.GetString("gas-analyzer-window-error-text", ("errorText", msg.Error)),
FontColorOverride = Color.Red
});
return;
}
if (msg.NodeGasMixes.Length == 0)
{
CTopBox.AddChild(new Label
{
Text = Loc.GetString("gas-analyzer-window-no-data")
});
MinSize = new Vector2(CTopBox.DesiredSize.X + 40, MinSize.Y);
return;
}
Vector2 minSize;
// Environment Tab
var envMix = msg.NodeGasMixes[0];
CTabContainer.SetTabTitle(1, envMix.Name);
CEnvironmentMix.RemoveAllChildren();
GenerateGasDisplay(envMix, CEnvironmentMix);
// Device Tab
if (msg.NodeGasMixes.Length > 1)
{
CTabContainer.SetTabVisible(0, true);
CTabContainer.SetTabTitle(0, Loc.GetString("gas-analyzer-window-tab-title-capitalized", ("title", msg.DeviceName)));
// Set up Grid
GridIcon.OverrideDirection = msg.NodeGasMixes.Length switch
{
// Unary layout
2 => Direction.South,
// Binary layout
3 => Direction.East,
// Trinary layout
4 => Direction.East,
_ => GridIcon.OverrideDirection
};
GridIcon.Sprite = _entityManager.GetComponent<SpriteComponent>(msg.DeviceUid);
LeftPanel.RemoveAllChildren();
MiddlePanel.RemoveAllChildren();
RightPanel.RemoveAllChildren();
if (msg.NodeGasMixes.Length == 2)
{
// Unary, use middle
LeftPanelLabel.Text = string.Empty;
MiddlePanelLabel.Text = Loc.GetString("gas-analyzer-window-tab-title-capitalized", ("title", msg.NodeGasMixes[1].Name));
RightPanelLabel.Text = string.Empty;
LeftPanel.Visible = false;
MiddlePanel.Visible = true;
RightPanel.Visible = false;
GenerateGasDisplay(msg.NodeGasMixes[1], MiddlePanel);
minSize = new Vector2(CDeviceGrid.DesiredSize.X + 40, MinSize.Y);
}
else if (msg.NodeGasMixes.Length == 3)
{
// Binary, use left and right
LeftPanelLabel.Text = Loc.GetString("gas-analyzer-window-tab-title-capitalized", ("title", msg.NodeGasMixes[1].Name));
MiddlePanelLabel.Text = string.Empty;
RightPanelLabel.Text = Loc.GetString("gas-analyzer-window-tab-title-capitalized", ("title", msg.NodeGasMixes[2].Name));
LeftPanel.Visible = true;
MiddlePanel.Visible = false;
RightPanel.Visible = true;
GenerateGasDisplay(msg.NodeGasMixes[1], LeftPanel);
GenerateGasDisplay(msg.NodeGasMixes[2], RightPanel);
minSize = new Vector2(CDeviceGrid.DesiredSize.X + 40, MinSize.Y);
}
else if (msg.NodeGasMixes.Length == 4)
{
// Trinary, use all three
// Trinary can be flippable, which complicates how to display things currently
LeftPanelLabel.Text = Loc.GetString("gas-analyzer-window-tab-title-capitalized",
("title", msg.DeviceFlipped ? msg.NodeGasMixes[1].Name : msg.NodeGasMixes[3].Name));
MiddlePanelLabel.Text = Loc.GetString("gas-analyzer-window-tab-title-capitalized", ("title", msg.NodeGasMixes[2].Name));
RightPanelLabel.Text = Loc.GetString("gas-analyzer-window-tab-title-capitalized",
("title", msg.DeviceFlipped ? msg.NodeGasMixes[3].Name : msg.NodeGasMixes[1].Name));
LeftPanel.Visible = true;
MiddlePanel.Visible = true;
RightPanel.Visible = true;
GenerateGasDisplay(msg.DeviceFlipped ? msg.NodeGasMixes[1] : msg.NodeGasMixes[3], LeftPanel);
GenerateGasDisplay(msg.NodeGasMixes[2], MiddlePanel);
GenerateGasDisplay(msg.DeviceFlipped ? msg.NodeGasMixes[3] : msg.NodeGasMixes[1], RightPanel);
minSize = new Vector2(CDeviceGrid.DesiredSize.X + 40, MinSize.Y);
}
else
{
// oh shit of fuck its more than 4 this ui isn't gonna look pretty anymore
for (var i = 1; i < msg.NodeGasMixes.Length; i++)
{
GenerateGasDisplay(msg.NodeGasMixes[i], CDeviceMixes);
}
LeftPanel.Visible = false;
MiddlePanel.Visible = false;
RightPanel.Visible = false;
minSize = new Vector2(CDeviceMixes.DesiredSize.X + 40, MinSize.Y);
}
}
else
{
// Hide device tab, no device selected
CTabContainer.SetTabVisible(0, false);
CTabContainer.CurrentTab = 1;
minSize = new Vector2(CEnvironmentMix.DesiredSize.X + 40, MinSize.Y);
}
MinSize = minSize;
}
private void GenerateGasDisplay(GasMixEntry gasMix, Control parent)
{
var panel = new PanelContainer
{
VerticalExpand = true,
HorizontalExpand = true,
Margin = new Thickness(4),
PanelOverride = new StyleBoxFlat{BorderColor = Color.FromHex("#4f4f4f"), BorderThickness = new Thickness(1)}
};
var dataContainer = new BoxContainer { Orientation = BoxContainer.LayoutOrientation.Vertical, VerticalExpand = true, Margin = new Thickness(4)};
parent.AddChild(panel);
panel.AddChild(dataContainer);
// Pressure label
var presBox = new BoxContainer { Orientation = BoxContainer.LayoutOrientation.Horizontal };
presBox.AddChild(new Label
{
Text = Loc.GetString("gas-analyzer-window-pressure-text")
});
presBox.AddChild(new Control
{
MinSize = new Vector2(10, 0),
HorizontalExpand = true
});
presBox.AddChild(new Label
{
Text = Loc.GetString("gas-analyzer-window-pressure-val-text", ("pressure", $"{gasMix.Pressure:0.##}")),
Align = Label.AlignMode.Right,
HorizontalExpand = true
});
dataContainer.AddChild(presBox);
// If there is no gas, it doesn't really have a temperature, so skip displaying it
if (gasMix.Pressure > Atmospherics.GasMinMoles)
{
// Temperature label
var tempBox = new BoxContainer { Orientation = BoxContainer.LayoutOrientation.Horizontal };
tempBox.AddChild(new Label
{
Text = Loc.GetString("gas-analyzer-window-temperature-text")
});
tempBox.AddChild(new Control
{
MinSize = new Vector2(10, 0),
HorizontalExpand = true
});
tempBox.AddChild(new Label
{
Text = Loc.GetString("gas-analyzer-window-temperature-val-text",
("tempK", $"{gasMix.Temperature:0.#}"),
("tempC", $"{TemperatureHelpers.KelvinToCelsius(gasMix.Temperature):0.#}")),
Align = Label.AlignMode.Right,
HorizontalExpand = true
});
dataContainer.AddChild(tempBox);
}
if (gasMix.Gases == null || gasMix.Gases?.Length == 0)
{
// Separator
dataContainer.AddChild(new Control
{
MinSize = new Vector2(0, 10)
});
// Add a label that there are no gases so it's less confusing
dataContainer.AddChild(new Label
{
Text = Loc.GetString("gas-analyzer-window-no-gas-text"),
FontColorOverride = Color.Gray
});
// return, everything below is for the fancy gas display stuff
return;
}
// Separator
dataContainer.AddChild(new Control
{
MinSize = new Vector2(0, 10)
});
// Add a table with all the gases
var tableKey = new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Vertical
};
var tableVal = new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Vertical
};
dataContainer.AddChild(new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Horizontal,
Children =
{
tableKey,
new Control
{
MinSize = new Vector2(10, 0),
HorizontalExpand = true
},
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 = BoxContainer.LayoutOrientation.Horizontal,
HorizontalExpand = true,
MinSize = new Vector2(0, height)
};
// Separator
dataContainer.AddChild(new Control
{
MinSize = new Vector2(0, 10),
VerticalExpand = true
});
var totalGasAmount = 0f;
foreach (var gas in gasMix.Gases!)
{
totalGasAmount += gas.Amount;
}
for (var j = 0; j < gasMix.Gases.Length; j++)
{
var gas = gasMix.Gases[j];
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-molarity-text",
("mol", $"{gas.Amount:0.##}"),
("percentage", $"{(gas.Amount / totalGasAmount * 100):0.#}")),
Align = Label.AlignMode.Right,
HorizontalExpand = true
});
// Add to the gas bar //TODO: highlight the currently hover one
var left = (j == 0) ? 0f : 2f;
var right = (j == gasMix.Gases.Length - 1) ? 0f : 2f;
gasBar.AddChild(new PanelContainer
{
ToolTip = Loc.GetString("gas-analyzer-window-molarity-percentage-text",
("gasName", gas.Name),
("amount", $"{gas.Amount:0.##}"),
("percentage", $"{(gas.Amount / totalGasAmount * 100):0.#}")),
HorizontalExpand = true,
SizeFlagsStretchRatio = gas.Amount,
MouseFilter = MouseFilterMode.Stop,
PanelOverride = new StyleBoxFlat
{
BackgroundColor = color,
PaddingLeft = left,
PaddingRight = right
},
MinSize = new Vector2(minSize, 0)
});
}
dataContainer.AddChild(gasBar);
}
}
}