diff --git a/Pulsar4X/Pulsar4X.Client/DisplayExtensions/EntityDisplay.cs b/Pulsar4X/Pulsar4X.Client/DisplayExtensions/EntityDisplay.cs index f9610ef5c..b2a0010ca 100644 --- a/Pulsar4X/Pulsar4X.Client/DisplayExtensions/EntityDisplay.cs +++ b/Pulsar4X/Pulsar4X.Client/DisplayExtensions/EntityDisplay.cs @@ -83,6 +83,17 @@ public static void DisplaySummary(this Entity entity, EntityState entityState, G { if(entity.TryGetDatablob(out var storage)) { + var size = ImGui.GetContentRegionMax(); + ImGui.PushStyleColor(ImGuiCol.Button, Styles.SelectedColor); + ImGui.PushStyleColor(ImGuiCol.ButtonHovered, Styles.SelectedColorHover); + ImGui.PushStyleColor(ImGuiCol.ButtonActive, Styles.SelectedColorActive); + if(ImGui.Button("Initiate Transfer", new Vector2(size.X - 8, 18))) + { + CreateTransferWindow.GetInstance().SetLeft(entity); + CreateTransferWindow.GetInstance().SetActive(true); + } + ImGui.PopStyleColor(3); + ImGui.Columns(2); DisplayHelpers.PrintRow("Total Mass in Storage", Stringify.Mass(storage.TotalStoredMass)); DisplayHelpers.PrintRow("Transfer Rate", storage.TransferRateInKgHr.ToString() + " kg/hr"); diff --git a/Pulsar4X/Pulsar4X.Client/DisplayExtensions/ICargoableDisplay.cs b/Pulsar4X/Pulsar4X.Client/DisplayExtensions/ICargoableDisplay.cs new file mode 100644 index 000000000..a418e66f7 --- /dev/null +++ b/Pulsar4X/Pulsar4X.Client/DisplayExtensions/ICargoableDisplay.cs @@ -0,0 +1,43 @@ +using System.Linq; +using Pulsar4X.Components; +using Pulsar4X.Engine.Designs; +using Pulsar4X.Engine.Industry; +using Pulsar4X.Interfaces; + +namespace Pulsar4X.SDL2UI; + +public static class ICargoableDisplay +{ + public static void ShowTooltip(this ICargoable cargoable) + { + if(cargoable is Mineral) + { + var mineralSD = (Mineral)cargoable; + DisplayHelpers.DescriptiveTooltip(cargoable.Name, "Mineral", mineralSD.Description); + } + else if(cargoable is ProcessedMaterial) + { + var processedMaterialSD = (ProcessedMaterial)cargoable; + DisplayHelpers.DescriptiveTooltip(cargoable.Name, "Processed Material", processedMaterialSD.Description); + } + else if(cargoable is ComponentInstance) + { + var componentInstance = (ComponentInstance)cargoable; + DisplayHelpers.DescriptiveTooltip(cargoable.Name, componentInstance.Design.ComponentType, componentInstance.Design.Description); + } + else if(cargoable is ComponentDesign) + { + var componentDesign = (ComponentDesign)cargoable; + DisplayHelpers.DescriptiveTooltip(componentDesign.Name, componentDesign.ComponentType, componentDesign.Description); + } + else if(cargoable is OrdnanceDesign) + { + var ordnanceDesign = (OrdnanceDesign)cargoable; + var components = ordnanceDesign.Components.Select(tuple => tuple.design).ToArray(); + foreach(var component in components) + { + DisplayHelpers.DescriptiveTooltip(component.Name, component.ComponentType, component.Description); + } + } + } +} \ No newline at end of file diff --git a/Pulsar4X/Pulsar4X.Client/EntityManagement/CreateTransferWindow.cs b/Pulsar4X/Pulsar4X.Client/EntityManagement/CreateTransferWindow.cs new file mode 100644 index 000000000..6006bd040 --- /dev/null +++ b/Pulsar4X/Pulsar4X.Client/EntityManagement/CreateTransferWindow.cs @@ -0,0 +1,182 @@ +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using ImGuiNET; +using Pulsar4X.Datablobs; +using Pulsar4X.Engine; +using Pulsar4X.Extensions; +using Pulsar4X.Interfaces; + +namespace Pulsar4X.SDL2UI; + +public class CreateTransferWindow : PulsarGuiWindow +{ + public Entity? TransferLeft { get; private set; } + public Entity? TransferRight { get; private set; } + + public Dictionary TransferLeftGoods { get; private set; } = new (); + public Dictionary TransferRightGoods { get; private set; } = new (); + + internal static CreateTransferWindow GetInstance() + { + return _uiState.LoadedWindows.ContainsKey(typeof(CreateTransferWindow)) ? (CreateTransferWindow)_uiState.LoadedWindows[typeof(CreateTransferWindow)] : new CreateTransferWindow(); + } + + public void SetLeft(Entity entity) + { + TransferLeft = entity; + } + + public void SetRight(Entity entity) + { + TransferRight = entity; + } + + internal override void Display() + { + if(!IsActive) return; + + if(ImGui.Begin("Create Transfer Order", ref IsActive)) + { + Vector2 windowContentSize = ImGui.GetContentRegionAvail(); + var firstChildSize = new Vector2(Styles.LeftColumnWidthLg, windowContentSize.Y); + var secondChildSize = new Vector2(windowContentSize.X - (Styles.LeftColumnWidthLg * 2) - (windowContentSize.X * 0.01f), windowContentSize.Y); + var thirdChildSize = new Vector2(Styles.LeftColumnWidthLg - (windowContentSize.X * 0.01f), windowContentSize.Y); + if(ImGui.BeginChild(GetLeftTitle() + "###left", firstChildSize, true)) + { + if(TransferLeft != null) + DisplayStorageList(TransferLeft); + + ImGui.EndChild(); + } + ImGui.SameLine(); + + if(ImGui.BeginChild("Transfer Details", secondChildSize, true)) + { + + ImGui.Columns(2); + + ImGui.Text("Items to Transfer"); + ImGui.NextColumn(); + ImGui.Text("Items to Transfer"); + ImGui.Separator(); + ImGui.NextColumn(); + + if(TransferLeft != null) + DisplayTradeList(TransferLeftGoods, TransferLeft); + + ImGui.NextColumn(); + + if(TransferRight != null) + DisplayTradeList(TransferRightGoods, TransferRight); + + ImGui.Columns(1); + + ImGui.EndChild(); + } + ImGui.SameLine(); + + if(ImGui.BeginChild(GetRightTitle() + "###right", thirdChildSize, true)) + { + if(TransferRight != null) + DisplayStorageList(TransferRight); + else + DisplayTransferSelection(); + + ImGui.EndChild(); + } + ImGui.End(); + } + } + + private void DisplayStorageList(Entity entity) + { + if(entity.TryGetDatablob(out var leftVolumeStorageDB)) + { + ImGui.Text(entity.GetName(_uiState.Faction.Id)); + ImGui.Separator(); + foreach(var (storageId, storageType) in leftVolumeStorageDB.TypeStores) + { + string header = entity.GetFactionOwner.GetDataBlob().Data.CargoTypes[storageId].Name + " Storage"; + if(ImGui.CollapsingHeader(header + "###" + storageId, ImGuiTreeNodeFlags.DefaultOpen)) + { + var cargoables = storageType.GetCargoables(); + // Sort the display by the cargoables name + var sortedUnitsByCargoablesName = storageType.CurrentStoreInUnits.OrderBy(e => cargoables[e.Key].Name); + var contentSize = ImGui.GetContentRegionAvail(); + + foreach(var (id, value) in sortedUnitsByCargoablesName) + { + + if(ImGui.SmallButton("+###add" + cargoables[id].Name)) + { + if(entity == TransferLeft && !TransferLeftGoods.ContainsKey(cargoables[id])) + { + TransferLeftGoods.Add(cargoables[id], 0); + } + else if(entity == TransferRight && !TransferRightGoods.ContainsKey(cargoables[id])) + { + TransferRightGoods.Add(cargoables[id], 0); + } + } + ImGui.SameLine(); + ImGui.Text(cargoables[id].Name); + cargoables[id].ShowTooltip(); + ImGui.SameLine(); + + string amount = Stringify.Number(value); + var amountSize = ImGui.CalcTextSize(amount); + + ImGui.SetCursorPosX(contentSize.X - amountSize.X); + ImGui.Text(value.ToString()); + + } + } + } + } + } + + private void DisplayTradeList(Dictionary list, Entity entity) + { + var contentSize = ImGui.GetContentRegionAvail(); + foreach(var (cargoable, amount) in list) + { + ImGui.Text(cargoable.Name); + ImGui.SameLine(); + byte[] buffer = new byte[16]; + + ImGui.SetNextItemWidth(96); + ImGui.SetCursorPosX(contentSize.X - 96); + ImGui.InputText("###input" + cargoable.Name, buffer, 16); + cargoable.ShowTooltip(); + } + } + + private void DisplayTransferSelection() + { + // We get the system from the TransferLeft so it needs to be set + if(TransferLeft == null || TransferLeft.Manager == null) return; + + // Setup the target list + var systemState = _uiState.StarSystemStates[TransferLeft.Manager.ManagerGuid]; + var allFriendlyStorageInSystem = systemState.GetFilteredEntities(DataStructures.EntityFilter.Friendly, _uiState.Faction.Id, typeof(VolumeStorageDB)); + + ImGui.Text("Select a Transfer Partner"); + ImGui.Separator(); + + foreach(var potentialTarget in allFriendlyStorageInSystem) + { + if(potentialTarget.Entity.Id == TransferLeft.Id) continue; + + // TODO: check the distance from TransferLeft to potentialTarget + // make sure it is within the transfer range + if(ImGui.Button(potentialTarget.Name)) + { + SetRight(potentialTarget.Entity); + } + } + } + + private string GetLeftTitle() => TransferLeft?.GetFactionName() ?? "Select Entity"; + private string GetRightTitle() => TransferRight?.GetFactionName() ?? "Select Entity"; +} \ No newline at end of file diff --git a/Pulsar4X/Pulsar4X.Client/Styles.cs b/Pulsar4X/Pulsar4X.Client/Styles.cs index 4a85a5b77..c2e11c823 100644 --- a/Pulsar4X/Pulsar4X.Client/Styles.cs +++ b/Pulsar4X/Pulsar4X.Client/Styles.cs @@ -15,6 +15,8 @@ public static class Styles public static Vector4 TerribleColor = new (1.0f, 0.05f, 0.05f, 1.0f); public static Vector4 SelectedColor = new Vector4(0.75f, 0.25f, 0.25f, 1f); + public static Vector4 SelectedColorHover = new Vector4(0.775f, 0.325f, 0.325f, 1f); + public static Vector4 SelectedColorActive = new Vector4(0.675f, 0.225f, 0.225f, 1f); public static Vector4 InvisibleColor = new Vector4(0, 0, 0, 0f); public static Vector4 NeutralColor = new (0.65f, 0.65f, 0.65f, 1f);