Adding sorting to chem master (#34763)
* Adding sorting to chem master * Chem Master can now sort based on following categories - Alphabetical - Quantity - Time Added to Machine * Sorting is disabled by default and persist in the machine for everyone * Removed some pointless code from Chem Master's UI * Changed None and Time Added's text to reflect what they do better * Minor adjustments to the code requested by maintainers
This commit is contained in:
@@ -46,6 +46,8 @@ namespace Content.Client.Chemistry.UI
|
|||||||
_window.CreateBottleButton.OnPressed += _ => SendMessage(
|
_window.CreateBottleButton.OnPressed += _ => SendMessage(
|
||||||
new ChemMasterOutputToBottleMessage(
|
new ChemMasterOutputToBottleMessage(
|
||||||
(uint) _window.BottleDosage.Value, _window.LabelLine));
|
(uint) _window.BottleDosage.Value, _window.LabelLine));
|
||||||
|
_window.BufferSortButton.OnPressed += _ => SendMessage(
|
||||||
|
new ChemMasterSortingTypeCycleMessage());
|
||||||
|
|
||||||
for (uint i = 0; i < _window.PillTypeButtons.Length; i++)
|
for (uint i = 0; i < _window.PillTypeButtons.Length; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
<Label Text="{Loc 'chem-master-window-buffer-text'}" />
|
<Label Text="{Loc 'chem-master-window-buffer-text'}" />
|
||||||
<Control HorizontalExpand="True" />
|
<Control HorizontalExpand="True" />
|
||||||
<Button MinSize="80 0" Name="BufferTransferButton" Access="Public" Text="{Loc 'chem-master-window-transfer-button'}" ToggleMode="True" StyleClasses="OpenRight" />
|
<Button MinSize="80 0" Name="BufferTransferButton" Access="Public" Text="{Loc 'chem-master-window-transfer-button'}" ToggleMode="True" StyleClasses="OpenRight" />
|
||||||
|
<Button MinSize="80 0" Name="BufferSortButton" Access="Public" Text="{Loc 'chem-master-window-sort-type-none'}" StyleClasses="OpenBoth" />
|
||||||
<Button MinSize="80 0" Name="BufferDiscardButton" Access="Public" Text="{Loc 'chem-master-window-discard-button'}" ToggleMode="True" StyleClasses="OpenLeft" />
|
<Button MinSize="80 0" Name="BufferDiscardButton" Access="Public" Text="{Loc 'chem-master-window-discard-button'}" ToggleMode="True" StyleClasses="OpenLeft" />
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
|
|
||||||
|
|||||||
@@ -140,17 +140,17 @@ namespace Content.Client.Chemistry.UI
|
|||||||
|
|
||||||
// Ensure the Panel Info is updated, including UI elements for Buffer Volume, Output Container and so on
|
// Ensure the Panel Info is updated, including UI elements for Buffer Volume, Output Container and so on
|
||||||
UpdatePanelInfo(castState);
|
UpdatePanelInfo(castState);
|
||||||
|
|
||||||
BufferCurrentVolume.Text = $" {castState.BufferCurrentVolume?.Int() ?? 0}u";
|
BufferCurrentVolume.Text = $" {castState.BufferCurrentVolume?.Int() ?? 0}u";
|
||||||
|
|
||||||
InputEjectButton.Disabled = castState.InputContainerInfo is null;
|
InputEjectButton.Disabled = castState.InputContainerInfo is null;
|
||||||
OutputEjectButton.Disabled = castState.OutputContainerInfo is null;
|
OutputEjectButton.Disabled = castState.OutputContainerInfo is null;
|
||||||
CreateBottleButton.Disabled = castState.OutputContainerInfo?.Reagents == null;
|
CreateBottleButton.Disabled = castState.OutputContainerInfo?.Reagents == null;
|
||||||
CreatePillButton.Disabled = castState.OutputContainerInfo?.Entities == null;
|
CreatePillButton.Disabled = castState.OutputContainerInfo?.Entities == null;
|
||||||
|
|
||||||
UpdateDosageFields(castState);
|
UpdateDosageFields(castState);
|
||||||
}
|
}
|
||||||
|
|
||||||
//assign default values for pill and bottle fields.
|
//assign default values for pill and bottle fields.
|
||||||
private void UpdateDosageFields(ChemMasterBoundUserInterfaceState castState)
|
private void UpdateDosageFields(ChemMasterBoundUserInterfaceState castState)
|
||||||
{
|
{
|
||||||
@@ -162,8 +162,9 @@ namespace Content.Client.Chemistry.UI
|
|||||||
var bufferVolume = castState.BufferCurrentVolume?.Int() ?? 0;
|
var bufferVolume = castState.BufferCurrentVolume?.Int() ?? 0;
|
||||||
|
|
||||||
PillDosage.Value = (int)Math.Min(bufferVolume, castState.PillDosageLimit);
|
PillDosage.Value = (int)Math.Min(bufferVolume, castState.PillDosageLimit);
|
||||||
|
|
||||||
PillTypeButtons[castState.SelectedPillType].Pressed = true;
|
PillTypeButtons[castState.SelectedPillType].Pressed = true;
|
||||||
|
|
||||||
PillNumber.IsValid = x => x >= 0 && x <= pillNumberMax;
|
PillNumber.IsValid = x => x >= 0 && x <= pillNumberMax;
|
||||||
PillDosage.IsValid = x => x > 0 && x <= castState.PillDosageLimit;
|
PillDosage.IsValid = x => x > 0 && x <= castState.PillDosageLimit;
|
||||||
BottleDosage.IsValid = x => x >= 0 && x <= bottleAmountMax;
|
BottleDosage.IsValid = x => x >= 0 && x <= bottleAmountMax;
|
||||||
@@ -213,6 +214,17 @@ namespace Content.Client.Chemistry.UI
|
|||||||
|
|
||||||
BufferInfo.Children.Clear();
|
BufferInfo.Children.Clear();
|
||||||
|
|
||||||
|
// This has to happen here due to people possibly
|
||||||
|
// setting sorting before putting any chemicals
|
||||||
|
BufferSortButton.Text = state.SortingType switch
|
||||||
|
{
|
||||||
|
ChemMasterSortingType.Alphabetical => Loc.GetString("chem-master-window-sort-type-alphabetical"),
|
||||||
|
ChemMasterSortingType.Quantity => Loc.GetString("chem-master-window-sort-type-quantity"),
|
||||||
|
ChemMasterSortingType.Latest => Loc.GetString("chem-master-window-sort-type-latest"),
|
||||||
|
_ => Loc.GetString("chem-master-window-sort-type-none")
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
if (!state.BufferReagents.Any())
|
if (!state.BufferReagents.Any())
|
||||||
{
|
{
|
||||||
BufferInfo.Children.Add(new Label { Text = Loc.GetString("chem-master-window-buffer-empty-text") });
|
BufferInfo.Children.Add(new Label { Text = Loc.GetString("chem-master-window-buffer-empty-text") });
|
||||||
@@ -235,19 +247,48 @@ namespace Content.Client.Chemistry.UI
|
|||||||
};
|
};
|
||||||
bufferHBox.AddChild(bufferVol);
|
bufferHBox.AddChild(bufferVol);
|
||||||
|
|
||||||
// initialises rowCount to allow for striped rows
|
// This sets up the needed data for sorting later in a list
|
||||||
|
// Its done this way to not repeat having to use same code twice (once for sorting
|
||||||
var rowCount = 0;
|
// and once for displaying)
|
||||||
|
var reagentList = new List<(ReagentId reagentId, string name, Color color, FixedPoint2 quantity)>();
|
||||||
foreach (var (reagent, quantity) in state.BufferReagents)
|
foreach (var (reagent, quantity) in state.BufferReagents)
|
||||||
{
|
{
|
||||||
var reagentId = reagent;
|
var reagentId = reagent;
|
||||||
_prototypeManager.TryIndex(reagentId.Prototype, out ReagentPrototype? proto);
|
_prototypeManager.TryIndex(reagentId.Prototype, out ReagentPrototype? proto);
|
||||||
var name = proto?.LocalizedName ?? Loc.GetString("chem-master-window-unknown-reagent-text");
|
var name = proto?.LocalizedName ?? Loc.GetString("chem-master-window-unknown-reagent-text");
|
||||||
var reagentColor = proto?.SubstanceColor ?? default(Color);
|
var reagentColor = proto?.SubstanceColor ?? default(Color);
|
||||||
BufferInfo.Children.Add(BuildReagentRow(reagentColor, rowCount++, name, reagentId, quantity, true, true));
|
reagentList.Add(new (reagentId, name, reagentColor, quantity));
|
||||||
|
}
|
||||||
|
|
||||||
|
// We sort here since we need sorted list to be filled first.
|
||||||
|
// You can easily add any new params you need to it.
|
||||||
|
switch (state.SortingType)
|
||||||
|
{
|
||||||
|
case ChemMasterSortingType.Alphabetical:
|
||||||
|
reagentList = reagentList.OrderBy(x => x.name).ToList();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ChemMasterSortingType.Quantity:
|
||||||
|
reagentList = reagentList.OrderByDescending(x => x.quantity).ToList();
|
||||||
|
break;
|
||||||
|
case ChemMasterSortingType.Latest:
|
||||||
|
reagentList = Enumerable.Reverse(reagentList).ToList();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ChemMasterSortingType.None:
|
||||||
|
default:
|
||||||
|
// This case is pointless but it is there for readability
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialises rowCount to allow for striped rows
|
||||||
|
var rowCount = 0;
|
||||||
|
foreach (var reagent in reagentList)
|
||||||
|
{
|
||||||
|
BufferInfo.Children.Add(BuildReagentRow(reagent.color, rowCount++, reagent.name, reagent.reagentId, reagent.quantity, true, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BuildContainerUI(Control control, ContainerInfo? info, bool addReagentButtons)
|
private void BuildContainerUI(Control control, ContainerInfo? info, bool addReagentButtons)
|
||||||
{
|
{
|
||||||
control.Children.Clear();
|
control.Children.Clear();
|
||||||
@@ -295,7 +336,7 @@ namespace Content.Client.Chemistry.UI
|
|||||||
_prototypeManager.TryIndex(reagent.Reagent.Prototype, out ReagentPrototype? proto);
|
_prototypeManager.TryIndex(reagent.Reagent.Prototype, out ReagentPrototype? proto);
|
||||||
var name = proto?.LocalizedName ?? Loc.GetString("chem-master-window-unknown-reagent-text");
|
var name = proto?.LocalizedName ?? Loc.GetString("chem-master-window-unknown-reagent-text");
|
||||||
var reagentColor = proto?.SubstanceColor ?? default(Color);
|
var reagentColor = proto?.SubstanceColor ?? default(Color);
|
||||||
|
|
||||||
control.Children.Add(BuildReagentRow(reagentColor, rowCount++, name, reagent.Reagent, reagent.Quantity, false, addReagentButtons));
|
control.Children.Add(BuildReagentRow(reagentColor, rowCount++, name, reagent.Reagent, reagent.Quantity, false, addReagentButtons));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,7 +356,7 @@ namespace Content.Client.Chemistry.UI
|
|||||||
}
|
}
|
||||||
//this calls the separated button builder, and stores the return to render after labels
|
//this calls the separated button builder, and stores the return to render after labels
|
||||||
var reagentButtonConstructors = CreateReagentTransferButtons(reagent, isBuffer, addReagentButtons);
|
var reagentButtonConstructors = CreateReagentTransferButtons(reagent, isBuffer, addReagentButtons);
|
||||||
|
|
||||||
// Create the row layout with the color panel
|
// Create the row layout with the color panel
|
||||||
var rowContainer = new BoxContainer
|
var rowContainer = new BoxContainer
|
||||||
{
|
{
|
||||||
@@ -358,7 +399,7 @@ namespace Content.Client.Chemistry.UI
|
|||||||
Children = { rowContainer }
|
Children = { rowContainer }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public string LabelLine
|
public string LabelLine
|
||||||
{
|
{
|
||||||
get => LabelLineEdit.Text;
|
get => LabelLineEdit.Text;
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ namespace Content.Server.Chemistry.Components
|
|||||||
[DataField("mode"), ViewVariables(VVAccess.ReadWrite)]
|
[DataField("mode"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
public ChemMasterMode Mode = ChemMasterMode.Transfer;
|
public ChemMasterMode Mode = ChemMasterMode.Transfer;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public ChemMasterSortingType SortingType = ChemMasterSortingType.None;
|
||||||
|
|
||||||
[DataField("pillDosageLimit", required: true), ViewVariables(VVAccess.ReadWrite)]
|
[DataField("pillDosageLimit", required: true), ViewVariables(VVAccess.ReadWrite)]
|
||||||
public uint PillDosageLimit;
|
public uint PillDosageLimit;
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ namespace Content.Server.Chemistry.EntitySystems
|
|||||||
SubscribeLocalEvent<ChemMasterComponent, BoundUIOpenedEvent>(SubscribeUpdateUiState);
|
SubscribeLocalEvent<ChemMasterComponent, BoundUIOpenedEvent>(SubscribeUpdateUiState);
|
||||||
|
|
||||||
SubscribeLocalEvent<ChemMasterComponent, ChemMasterSetModeMessage>(OnSetModeMessage);
|
SubscribeLocalEvent<ChemMasterComponent, ChemMasterSetModeMessage>(OnSetModeMessage);
|
||||||
|
SubscribeLocalEvent<ChemMasterComponent, ChemMasterSortingTypeCycleMessage>(OnCycleSortingTypeMessage);
|
||||||
SubscribeLocalEvent<ChemMasterComponent, ChemMasterSetPillTypeMessage>(OnSetPillTypeMessage);
|
SubscribeLocalEvent<ChemMasterComponent, ChemMasterSetPillTypeMessage>(OnSetPillTypeMessage);
|
||||||
SubscribeLocalEvent<ChemMasterComponent, ChemMasterReagentAmountButtonMessage>(OnReagentButtonMessage);
|
SubscribeLocalEvent<ChemMasterComponent, ChemMasterReagentAmountButtonMessage>(OnReagentButtonMessage);
|
||||||
SubscribeLocalEvent<ChemMasterComponent, ChemMasterCreatePillsMessage>(OnCreatePillsMessage);
|
SubscribeLocalEvent<ChemMasterComponent, ChemMasterCreatePillsMessage>(OnCreatePillsMessage);
|
||||||
@@ -76,7 +77,7 @@ namespace Content.Server.Chemistry.EntitySystems
|
|||||||
var bufferCurrentVolume = bufferSolution.Volume;
|
var bufferCurrentVolume = bufferSolution.Volume;
|
||||||
|
|
||||||
var state = new ChemMasterBoundUserInterfaceState(
|
var state = new ChemMasterBoundUserInterfaceState(
|
||||||
chemMaster.Mode, BuildInputContainerInfo(inputContainer), BuildOutputContainerInfo(outputContainer),
|
chemMaster.Mode, chemMaster.SortingType, BuildInputContainerInfo(inputContainer), BuildOutputContainerInfo(outputContainer),
|
||||||
bufferReagents, bufferCurrentVolume, chemMaster.PillType, chemMaster.PillDosageLimit, updateLabel);
|
bufferReagents, bufferCurrentVolume, chemMaster.PillType, chemMaster.PillDosageLimit, updateLabel);
|
||||||
|
|
||||||
_userInterfaceSystem.SetUiState(owner, ChemMasterUiKey.Key, state);
|
_userInterfaceSystem.SetUiState(owner, ChemMasterUiKey.Key, state);
|
||||||
@@ -93,6 +94,15 @@ namespace Content.Server.Chemistry.EntitySystems
|
|||||||
ClickSound(chemMaster);
|
ClickSound(chemMaster);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnCycleSortingTypeMessage(Entity<ChemMasterComponent> chemMaster, ref ChemMasterSortingTypeCycleMessage message)
|
||||||
|
{
|
||||||
|
chemMaster.Comp.SortingType++;
|
||||||
|
if (chemMaster.Comp.SortingType > ChemMasterSortingType.Latest)
|
||||||
|
chemMaster.Comp.SortingType = ChemMasterSortingType.None;
|
||||||
|
UpdateUiState(chemMaster);
|
||||||
|
ClickSound(chemMaster);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnSetPillTypeMessage(Entity<ChemMasterComponent> chemMaster, ref ChemMasterSetPillTypeMessage message)
|
private void OnSetPillTypeMessage(Entity<ChemMasterComponent> chemMaster, ref ChemMasterSetPillTypeMessage message)
|
||||||
{
|
{
|
||||||
// Ensure valid pill type. There are 20 pills selectable, 0-19.
|
// Ensure valid pill type. There are 20 pills selectable, 0-19.
|
||||||
|
|||||||
@@ -89,6 +89,18 @@ namespace Content.Shared.Chemistry
|
|||||||
Discard,
|
Discard,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ChemMasterSortingType : byte
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Alphabetical = 1,
|
||||||
|
Quantity = 2,
|
||||||
|
Latest = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class ChemMasterSortingTypeCycleMessage : BoundUserInterfaceMessage;
|
||||||
|
|
||||||
|
|
||||||
public enum ChemMasterReagentAmount
|
public enum ChemMasterReagentAmount
|
||||||
{
|
{
|
||||||
U1 = 1,
|
U1 = 1,
|
||||||
@@ -160,6 +172,8 @@ namespace Content.Shared.Chemistry
|
|||||||
|
|
||||||
public readonly ChemMasterMode Mode;
|
public readonly ChemMasterMode Mode;
|
||||||
|
|
||||||
|
public readonly ChemMasterSortingType SortingType;
|
||||||
|
|
||||||
public readonly FixedPoint2? BufferCurrentVolume;
|
public readonly FixedPoint2? BufferCurrentVolume;
|
||||||
public readonly uint SelectedPillType;
|
public readonly uint SelectedPillType;
|
||||||
|
|
||||||
@@ -168,7 +182,7 @@ namespace Content.Shared.Chemistry
|
|||||||
public readonly bool UpdateLabel;
|
public readonly bool UpdateLabel;
|
||||||
|
|
||||||
public ChemMasterBoundUserInterfaceState(
|
public ChemMasterBoundUserInterfaceState(
|
||||||
ChemMasterMode mode, ContainerInfo? inputContainerInfo, ContainerInfo? outputContainerInfo,
|
ChemMasterMode mode, ChemMasterSortingType sortingType, ContainerInfo? inputContainerInfo, ContainerInfo? outputContainerInfo,
|
||||||
IReadOnlyList<ReagentQuantity> bufferReagents, FixedPoint2 bufferCurrentVolume,
|
IReadOnlyList<ReagentQuantity> bufferReagents, FixedPoint2 bufferCurrentVolume,
|
||||||
uint selectedPillType, uint pillDosageLimit, bool updateLabel)
|
uint selectedPillType, uint pillDosageLimit, bool updateLabel)
|
||||||
{
|
{
|
||||||
@@ -176,6 +190,7 @@ namespace Content.Shared.Chemistry
|
|||||||
OutputContainerInfo = outputContainerInfo;
|
OutputContainerInfo = outputContainerInfo;
|
||||||
BufferReagents = bufferReagents;
|
BufferReagents = bufferReagents;
|
||||||
Mode = mode;
|
Mode = mode;
|
||||||
|
SortingType = sortingType;
|
||||||
BufferCurrentVolume = bufferCurrentVolume;
|
BufferCurrentVolume = bufferCurrentVolume;
|
||||||
SelectedPillType = selectedPillType;
|
SelectedPillType = selectedPillType;
|
||||||
PillDosageLimit = pillDosageLimit;
|
PillDosageLimit = pillDosageLimit;
|
||||||
|
|||||||
@@ -29,3 +29,7 @@ chem-master-window-dose-label = Dose (u):
|
|||||||
chem-master-window-create-button = Create
|
chem-master-window-create-button = Create
|
||||||
chem-master-window-bottles-label = Bottles:
|
chem-master-window-bottles-label = Bottles:
|
||||||
chem-master-window-unknown-reagent-text = Unknown reagent
|
chem-master-window-unknown-reagent-text = Unknown reagent
|
||||||
|
chem-master-window-sort-type-none = Sort by: Oldest First
|
||||||
|
chem-master-window-sort-type-alphabetical = Sort by: Alphabetical
|
||||||
|
chem-master-window-sort-type-quantity = Sort by: Quantity
|
||||||
|
chem-master-window-sort-type-latest = Sort by: Recent First
|
||||||
|
|||||||
Reference in New Issue
Block a user