From 4c141812a3c9cb6e9a6ad38055d56125d640d687 Mon Sep 17 00:00:00 2001 From: Dale McCoy <21223975+DaleStan@users.noreply.github.com> Date: Wed, 31 Jul 2024 13:41:44 -0400 Subject: [PATCH 1/6] Introduce a SchemeColorGroup for at least some situations where the SchemeColor needs to be a multiple of 4. --- Yafc.UI/Core/Structs.cs | 15 +++++++++++++++ Yafc.UI/ImGui/ImGuiBuilding.cs | 2 +- Yafc.UI/ImGui/ImGuiTextInputHelper.cs | 12 ++++++------ Yafc/Widgets/ImmediateWidgets.cs | 2 +- .../ProductionTable/ProductionTableView.cs | 2 +- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/Yafc.UI/Core/Structs.cs b/Yafc.UI/Core/Structs.cs index ec0455f5..b4948d5e 100644 --- a/Yafc.UI/Core/Structs.cs +++ b/Yafc.UI/Core/Structs.cs @@ -64,6 +64,21 @@ public enum SchemeColor { TagColorBlueTextFaint } + public enum SchemeColorGroup { + Pure = SchemeColor.PureBackground, + Background = SchemeColor.Background, + Primary = SchemeColor.Primary, + Secondary = SchemeColor.Secondary, + Error = SchemeColor.Error, + Grey = SchemeColor.Grey, + Magenta = SchemeColor.Magenta, + Green = SchemeColor.Green, + TagColorGreen = SchemeColor.TagColorGreen, + TagColorYellow = SchemeColor.TagColorYellow, + TagColorRed = SchemeColor.TagColorRed, + TagColorBlue = SchemeColor.TagColorBlue, + } + public enum RectangleBorder { None, Thin, diff --git a/Yafc.UI/ImGui/ImGuiBuilding.cs b/Yafc.UI/ImGui/ImGuiBuilding.cs index 615f9cb8..8dde787b 100644 --- a/Yafc.UI/ImGui/ImGuiBuilding.cs +++ b/Yafc.UI/ImGui/ImGuiBuilding.cs @@ -150,7 +150,7 @@ public bool BuildTextInput(string? text, out string newText, string? placeholder return BuildTextInput(text, out newText, placeholder, icon, delayed, padding, setInitialFocus: setInitialFocus); } - public bool BuildTextInput(string? text, out string newText, string? placeholder, Icon icon, bool delayed, Padding padding, RectAlignment alignment = RectAlignment.MiddleLeft, SchemeColor color = SchemeColor.Grey, bool setInitialFocus = false) { + public bool BuildTextInput(string? text, out string newText, string? placeholder, Icon icon, bool delayed, Padding padding, RectAlignment alignment = RectAlignment.MiddleLeft, SchemeColorGroup color = SchemeColorGroup.Grey, bool setInitialFocus = false) { setInitialFocus &= textInputHelper == null; textInputHelper ??= new ImGuiTextInputHelper(this); bool result = textInputHelper.BuildTextInput(text, out newText, placeholder, GetFontSize(), delayed, icon, padding, alignment, color); diff --git a/Yafc.UI/ImGui/ImGuiTextInputHelper.cs b/Yafc.UI/ImGui/ImGuiTextInputHelper.cs index f793d5e1..22820fb1 100644 --- a/Yafc.UI/ImGui/ImGuiTextInputHelper.cs +++ b/Yafc.UI/ImGui/ImGuiTextInputHelper.cs @@ -55,13 +55,13 @@ private void GetTextParameters(string? textToBuild, Rect textRect, FontFile.Font } } - public bool BuildTextInput(string? text, out string newText, string? placeholder, FontFile.FontSize fontSize, bool delayed, Icon icon, Padding padding, RectAlignment alignment, SchemeColor color) { + public bool BuildTextInput(string? text, out string newText, string? placeholder, FontFile.FontSize fontSize, bool delayed, Icon icon, Padding padding, RectAlignment alignment, SchemeColorGroup color) { newText = text ?? ""; Rect textRect, realTextRect; using (gui.EnterGroup(padding, RectAllocator.LeftRow)) { float lineSize = gui.PixelsToUnits(fontSize.lineSize); if (icon != Icon.None) { - gui.BuildIcon(icon, lineSize, color + 3); + gui.BuildIcon(icon, lineSize, (SchemeColor)color + 3); } textRect = gui.RemainingRow(0.3f).AllocateRect(0, lineSize, RectAlignment.MiddleFullRow); @@ -93,14 +93,14 @@ public bool BuildTextInput(string? text, out string newText, string? placeholder _ = gui.ConsumeMouseOver(boundingRect, RenderingUtils.cursorCaret, false); break; case ImGuiAction.Build: - var textColor = color + 2; + SchemeColor textColor = (SchemeColor)color + 2; string? textToBuild; if (focused && !string.IsNullOrEmpty(text)) { textToBuild = this.text; } else if (string.IsNullOrEmpty(text)) { textToBuild = placeholder; - textColor = color + 3; + textColor = (SchemeColor)color + 3; } else { textToBuild = text; @@ -125,11 +125,11 @@ public bool BuildTextInput(string? text, out string newText, string? placeholder gui.SetNextRebuild(nextCaretTimer); if (caretVisible) { float caretPosition = GetCharacterPosition(caret, fontSize, textWidth) * scale; - gui.DrawRectangle(new Rect(caretPosition + realTextRect.X - 0.05f, realTextRect.Y, 0.1f, realTextRect.Height), color + 2); + gui.DrawRectangle(new Rect(caretPosition + realTextRect.X - 0.05f, realTextRect.Y, 0.1f, realTextRect.Height), (SchemeColor)color + 2); } } } - gui.DrawRectangle(boundingRect, color); + gui.DrawRectangle(boundingRect, (SchemeColor)color); break; } diff --git a/Yafc/Widgets/ImmediateWidgets.cs b/Yafc/Widgets/ImmediateWidgets.cs index 3ecade8f..7921e348 100644 --- a/Yafc/Widgets/ImmediateWidgets.cs +++ b/Yafc/Widgets/ImmediateWidgets.cs @@ -272,7 +272,7 @@ public static GoodsWithAmountEvent BuildFactorioObjectWithEditableAmount(this Im newAmount = amount; GoodsWithAmountEvent evt = (GoodsWithAmountEvent)gui.BuildFactorioObjectButton(obj, 3f, MilestoneDisplay.Contained, color, useScale, tooltipOptions); - if (gui.BuildTextInput(DataUtils.FormatAmount(amount, unit), out string newText, null, Icon.None, true, default, RectAlignment.Middle, SchemeColor.Secondary)) { + if (gui.BuildTextInput(DataUtils.FormatAmount(amount, unit), out string newText, null, Icon.None, true, default, RectAlignment.Middle, SchemeColorGroup.Secondary)) { if (DataUtils.TryParseAmount(newText, out newAmount, unit)) { evt = GoodsWithAmountEvent.TextEditing; } diff --git a/Yafc/Workspace/ProductionTable/ProductionTableView.cs b/Yafc/Workspace/ProductionTable/ProductionTableView.cs index 5ef0b469..a832dfe2 100644 --- a/Yafc/Workspace/ProductionTable/ProductionTableView.cs +++ b/Yafc/Workspace/ProductionTable/ProductionTableView.cs @@ -293,7 +293,7 @@ public override void BuildElement(ImGui gui, RecipeRow recipe) { } if (recipe.builtBuildings != null) { - if (gui.BuildTextInput(DataUtils.FormatAmount(Convert.ToSingle(recipe.builtBuildings), UnitOfMeasure.None), out string newText, null, Icon.None, true, default, RectAlignment.Middle, SchemeColor.Grey)) { + if (gui.BuildTextInput(DataUtils.FormatAmount(Convert.ToSingle(recipe.builtBuildings), UnitOfMeasure.None), out string newText, null, Icon.None, true, default, RectAlignment.Middle, SchemeColorGroup.Grey)) { if (DataUtils.TryParseAmount(newText, out float newAmount, UnitOfMeasure.None)) { recipe.RecordUndo().builtBuildings = Convert.ToInt32(newAmount); } From 52b12a7281b1e596fd5d3754cad8ce8eeae6f8b0 Mon Sep 17 00:00:00 2001 From: Dale McCoy <21223975+DaleStan@users.noreply.github.com> Date: Thu, 1 Aug 2024 15:44:28 -0400 Subject: [PATCH 2/6] Add a DisplayAmount to combine the display value, units, and (where applicable) new value. --- Yafc/Widgets/ImmediateWidgets.cs | 68 ++++++++++++------- Yafc/Widgets/ObjectTooltip.cs | 2 +- Yafc/Windows/NeverEnoughItemsPanel.cs | 6 +- Yafc/Windows/PreferencesScreen.cs | 35 +++++----- Yafc/Workspace/AutoPlannerView.cs | 12 ++-- .../ProductionSummaryView.cs | 13 ++-- .../ModuleCustomizationScreen.cs | 41 +++++------ .../ModuleFillerParametersScreen.cs | 34 +++++----- .../ProductionTable/ProductionTableView.cs | 26 +++---- Yafc/Workspace/SummaryView.cs | 9 +-- 10 files changed, 135 insertions(+), 111 deletions(-) diff --git a/Yafc/Widgets/ImmediateWidgets.cs b/Yafc/Widgets/ImmediateWidgets.cs index 7921e348..e71be15c 100644 --- a/Yafc/Widgets/ImmediateWidgets.cs +++ b/Yafc/Widgets/ImmediateWidgets.cs @@ -60,12 +60,13 @@ public static void BuildFactorioObjectIcon(this ImGui gui, FactorioObject? obj, } } - public static bool BuildFloatInput(this ImGui gui, float value, out float newValue, UnitOfMeasure unit, Padding padding, bool setInitialFocus = false) { - if (gui.BuildTextInput(DataUtils.FormatAmount(value, unit), out string newText, null, Icon.None, true, padding, setInitialFocus: setInitialFocus) && DataUtils.TryParseAmount(newText, out newValue, unit)) { + public static bool BuildFloatInput(this ImGui gui, DisplayAmount amount, Padding padding, bool setInitialFocus = false) { + if (gui.BuildTextInput(DataUtils.FormatAmount(amount.Value, amount.Unit), out string newText, null, Icon.None, true, padding, setInitialFocus: setInitialFocus) + && DataUtils.TryParseAmount(newText, out float newValue, amount.Unit)) { + amount.Value = newValue; return true; } - newValue = value; return false; } @@ -202,41 +203,40 @@ public static void BuildInlineObjectListAndButtonWithNone(this ImGui gui, ICo /// Draws a button displaying the icon belonging to a , or an empty box as a placeholder if no object is available. /// Also draws a label under the button, containing the supplied . /// Draw the icon for this object, or an empty box if this is . - /// Display this value, formatted appropriately for . - /// Use this unit of measure when formatting for display. + /// Display this value and unit. /// If , this icon will be displayed at , instead of at 100% scale. - public static Click BuildFactorioObjectWithAmount(this ImGui gui, FactorioObject? goods, float amount, UnitOfMeasure unit, SchemeColor bgColor = SchemeColor.None, SchemeColor textColor = SchemeColor.None, bool useScale = true, ObjectTooltipOptions tooltipOptions = default) { + public static Click BuildFactorioObjectWithAmount(this ImGui gui, FactorioObject? goods, DisplayAmount amount, SchemeColor bgColor = SchemeColor.None, SchemeColor textColor = SchemeColor.None, bool useScale = true, ObjectTooltipOptions tooltipOptions = default) { using (gui.EnterFixedPositioning(3f, 3f, default)) { gui.allocator = RectAllocator.Stretch; gui.spacing = 0f; Click clicked = gui.BuildFactorioObjectButton(goods, 3f, MilestoneDisplay.Contained, bgColor, useScale, tooltipOptions); if (goods != null) { - gui.BuildText(DataUtils.FormatAmount(amount, unit), Font.text, false, RectAlignment.Middle, textColor); + gui.BuildText(DataUtils.FormatAmount(amount.Value, amount.Unit), Font.text, false, RectAlignment.Middle, textColor); if (InputSystem.Instance.control && gui.BuildButton(gui.lastRect, SchemeColor.None, SchemeColor.Grey) == ButtonEvent.MouseOver) { - ShowPrecisionValueTooltip(gui, amount, unit, goods); + ShowPrecisionValueTooltip(gui, amount, goods); } } return clicked; } } - public static void ShowPrecisionValueTooltip(ImGui gui, float amount, UnitOfMeasure unit, FactorioObject goods) { + public static void ShowPrecisionValueTooltip(ImGui gui, DisplayAmount amount, FactorioObject goods) { string text; - switch (unit) { + switch (amount.Unit) { case UnitOfMeasure.PerSecond: case UnitOfMeasure.FluidPerSecond: case UnitOfMeasure.ItemPerSecond: - string perSecond = DataUtils.FormatAmountRaw(amount, 1f, "/s", DataUtils.PreciseFormat); - string perMinute = DataUtils.FormatAmountRaw(amount, 60f, "/m", DataUtils.PreciseFormat); - string perHour = DataUtils.FormatAmountRaw(amount, 3600f, "/h", DataUtils.PreciseFormat); + string perSecond = DataUtils.FormatAmountRaw(amount.Value, 1f, "/s", DataUtils.PreciseFormat); + string perMinute = DataUtils.FormatAmountRaw(amount.Value, 60f, "/m", DataUtils.PreciseFormat); + string perHour = DataUtils.FormatAmountRaw(amount.Value, 3600f, "/h", DataUtils.PreciseFormat); text = perSecond + "\n" + perMinute + "\n" + perHour; if (goods is Item item) { - text += DataUtils.FormatAmount(MathF.Abs(item.stackSize / amount), UnitOfMeasure.Second, "\n", " per stack"); + text += DataUtils.FormatAmount(MathF.Abs(item.stackSize / amount.Value), UnitOfMeasure.Second, "\n", " per stack"); } break; default: - text = DataUtils.FormatAmount(amount, unit, precise: true); + text = DataUtils.FormatAmount(amount.Value, amount.Unit, precise: true); break; } gui.ShowTooltip(gui.lastRect, x => { @@ -261,30 +261,46 @@ public static void BuildObjectSelectDropDownWithNone(this ImGui gui, ICollect /// Also draws an editable textbox under the button, containing the supplied . /// Draw the icon for this object, or an empty box if this is . /// If , this icon will be displayed at , instead of at 100% scale. - /// Display this value, formatted appropriately for . - /// Use this unit of measure when formatting for display. - /// The new value entered by the user, if this returns . Otherwise, the original . + /// Display this value and unit. If the user edits the value, the new value will be stored in before returning. /// If , the default, the user can adjust the value by using the scroll wheel while hovering over the editable text. /// If , the scroll wheel will be ignored when hovering. - public static GoodsWithAmountEvent BuildFactorioObjectWithEditableAmount(this ImGui gui, FactorioObject? obj, float amount, UnitOfMeasure unit, out float newAmount, SchemeColor color = SchemeColor.None, bool useScale = true, bool allowScroll = true, ObjectTooltipOptions tooltipOptions = default) { + public static GoodsWithAmountEvent BuildFactorioObjectWithEditableAmount(this ImGui gui, FactorioObject? obj, DisplayAmount amount, SchemeColor color = SchemeColor.None, bool useScale = true, bool allowScroll = true, ObjectTooltipOptions tooltipOptions = default) { using var group = gui.EnterGroup(default, RectAllocator.Stretch, spacing: 0f); group.SetWidth(3f); - newAmount = amount; GoodsWithAmountEvent evt = (GoodsWithAmountEvent)gui.BuildFactorioObjectButton(obj, 3f, MilestoneDisplay.Contained, color, useScale, tooltipOptions); - if (gui.BuildTextInput(DataUtils.FormatAmount(amount, unit), out string newText, null, Icon.None, true, default, RectAlignment.Middle, SchemeColorGroup.Secondary)) { - if (DataUtils.TryParseAmount(newText, out newAmount, unit)) { - evt = GoodsWithAmountEvent.TextEditing; + if (gui.BuildTextInput(DataUtils.FormatAmount(amount.Value, amount.Unit), out string newText, null, Icon.None, true, default, RectAlignment.Middle, SchemeColorGroup.Secondary)) { + if (DataUtils.TryParseAmount(newText, out float newAmount, amount.Unit)) { + amount.Value = newAmount; + return GoodsWithAmountEvent.TextEditing; } } if (allowScroll && gui.action == ImGuiAction.MouseScroll && gui.ConsumeEvent(gui.lastRect)) { - float digit = MathF.Pow(10, MathF.Floor(MathF.Log10(amount) - 2f)); - newAmount = MathF.Round((amount / digit) + gui.actionParameter) * digit; - evt = GoodsWithAmountEvent.TextEditing; + float digit = MathF.Pow(10, MathF.Floor(MathF.Log10(amount.Value) - 2f)); + amount.Value = MathF.Round((amount.Value / digit) + gui.actionParameter) * digit; + return GoodsWithAmountEvent.TextEditing; } return evt; } } + + /// + /// Represents an amount to be displayed to the user, and possibly edited. + /// + /// The initial value to be displayed to the user. + /// The to be used when formatting for display and when parsing user input. + public record DisplayAmount(float Value, UnitOfMeasure Unit = UnitOfMeasure.None) { + /// + /// Gets or sets the value. This is either the value to be displayed or the value after modification by the user. + /// + public float Value { get; set; } = Value; + + /// + /// Creates a new for basic numeric display. will be set to . + /// + /// The initial value to be displayed to the user. + public static implicit operator DisplayAmount(float value) => new(value); + } } diff --git a/Yafc/Widgets/ObjectTooltip.cs b/Yafc/Widgets/ObjectTooltip.cs index 8c00f740..086ec93a 100644 --- a/Yafc/Widgets/ObjectTooltip.cs +++ b/Yafc/Widgets/ObjectTooltip.cs @@ -520,7 +520,7 @@ private void BuildTechnology(Technology technology, ImGui gui) { using var grid = gui.EnterInlineGrid(3f); foreach (var pack in packs) { grid.Next(); - _ = gui.BuildFactorioObjectWithAmount(pack.goods, pack.amount, UnitOfMeasure.None); + _ = gui.BuildFactorioObjectWithAmount(pack.goods, pack.amount); } } } diff --git a/Yafc/Windows/NeverEnoughItemsPanel.cs b/Yafc/Windows/NeverEnoughItemsPanel.cs index 5ea7acd1..9a69a926 100644 --- a/Yafc/Windows/NeverEnoughItemsPanel.cs +++ b/Yafc/Windows/NeverEnoughItemsPanel.cs @@ -118,7 +118,7 @@ private void DrawIngredients(ImGui gui, Recipe recipe) { return; } foreach (var ingredient in recipe.ingredients) { - if (gui.BuildFactorioObjectWithAmount(ingredient.goods, ingredient.amount, UnitOfMeasure.None) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(ingredient.goods, ingredient.amount) == Click.Left) { if (ingredient.variants != null) { gui.ShowDropDown(imGui => imGui.BuildInlineObjectListAndButton(ingredient.variants, DataUtils.DefaultOrdering, SetItem, "Accepted fluid variants")); } @@ -136,7 +136,7 @@ private void DrawProducts(ImGui gui, Recipe recipe) { } for (int i = recipe.products.Length - 1; i >= 0; i--) { var product = recipe.products[i]; - if (gui.BuildFactorioObjectWithAmount(product.goods, product.amount, UnitOfMeasure.None) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(product.goods, product.amount) == Click.Left) { changing = product.goods; } } @@ -146,7 +146,7 @@ private void DrawTooManyThings(ImGui gui, IEnumerable li using var grid = gui.EnterInlineGrid(3f, 0f, maxElemCount); foreach (var item in list) { grid.Next(); - if (gui.BuildFactorioObjectWithAmount(item.target, item.amount, UnitOfMeasure.None) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(item.target, item.amount) == Click.Left) { changing = item.target as Goods; } } diff --git a/Yafc/Windows/PreferencesScreen.cs b/Yafc/Windows/PreferencesScreen.cs index c2b993b5..c0c2db89 100644 --- a/Yafc/Windows/PreferencesScreen.cs +++ b/Yafc/Windows/PreferencesScreen.cs @@ -40,16 +40,18 @@ public override void Build(ImGui gui) { using (gui.EnterRowWithHelpIcon("0 for off, 100% for old default")) { gui.BuildText("Pollution cost modifier", topOffset: 0.5f); - if (gui.BuildFloatInput(settings.PollutionCostModifier, out float pollutionCostModifier, UnitOfMeasure.Percent, new Padding(0.5f))) { - settings.RecordUndo().PollutionCostModifier = pollutionCostModifier; + DisplayAmount amount = new(settings.PollutionCostModifier, UnitOfMeasure.Percent); + if (gui.BuildFloatInput(amount, new Padding(0.5f))) { + settings.RecordUndo().PollutionCostModifier = amount.Value; gui.Rebuild(); } } using (gui.EnterRowWithHelpIcon("Some mod icons have little or no transparency, hiding the background color. This setting reduces the size of icons that could hide link information.")) { gui.BuildText("Display scale for linkable icons", topOffset: 0.5f); - if (gui.BuildFloatInput(prefs.iconScale, out float iconScale, UnitOfMeasure.Percent, new Padding(0.5f)) && iconScale > 0 && iconScale <= 1) { - prefs.RecordUndo().iconScale = iconScale; + DisplayAmount amount = new(prefs.iconScale, UnitOfMeasure.Percent); + if (gui.BuildFloatInput(amount, new Padding(0.5f)) && amount.Value > 0 && amount.Value <= 1) { + prefs.RecordUndo().iconScale = amount.Value; gui.Rebuild(); } } @@ -130,15 +132,14 @@ private static void ChooseObjectWithNone(ImGui gui, string text, T[] list, T? } private void BuildUnitPerTime(ImGui gui, bool fluid, ProjectPreferences preferences) { - float unit = fluid ? preferences.fluidUnit : preferences.itemUnit; - float newUnit = unit; + DisplayAmount unit = fluid ? preferences.fluidUnit : preferences.itemUnit; if (gui.BuildRadioButton("Simple Amount" + preferences.GetPerTimeUnit().suffix, unit == 0f)) { - newUnit = 0f; + unit = 0f; } using (gui.EnterRow()) { if (gui.BuildRadioButton("Custom: 1 unit equals", unit != 0f)) { - newUnit = 1f; + unit = 1f; } gui.AllocateSpacing(); @@ -152,20 +153,18 @@ private void BuildUnitPerTime(ImGui gui, bool fluid, ProjectPreferences preferen } } gui.BuildText("per second"); - if (gui.BuildTextInput(DataUtils.FormatAmount(unit, UnitOfMeasure.None), out string updated, null, Icon.None, true) && - DataUtils.TryParseAmount(updated, out float parsed, UnitOfMeasure.None)) { - newUnit = parsed; - } + _ = gui.BuildFloatInput(unit, new Padding(.5f)); } gui.AllocateSpacing(1f); - if (newUnit != unit) { - _ = preferences.RecordUndo(true); - if (fluid) { - preferences.fluidUnit = newUnit; + if (fluid) { + if (preferences.fluidUnit != unit.Value) { + preferences.RecordUndo(true).fluidUnit = unit.Value; } - else { - preferences.itemUnit = newUnit; + } + else { + if (preferences.itemUnit != unit.Value) { + preferences.RecordUndo(true).itemUnit = unit.Value; } } } diff --git a/Yafc/Workspace/AutoPlannerView.cs b/Yafc/Workspace/AutoPlannerView.cs index 069f23c6..58b2c117 100644 --- a/Yafc/Workspace/AutoPlannerView.cs +++ b/Yafc/Workspace/AutoPlannerView.cs @@ -18,7 +18,7 @@ protected override void BuildPageTooltip(ImGui gui, AutoPlanner contents) { using var grid = gui.EnterInlineGrid(3f, 1f); foreach (var goal in contents.goals) { grid.Next(); - _ = gui.BuildFactorioObjectWithAmount(goal.item, goal.amount, goal.item.flowUnitOfMeasure); + _ = gui.BuildFactorioObjectWithAmount(goal.item, new(goal.amount, goal.item.flowUnitOfMeasure)); } } @@ -36,10 +36,10 @@ void Page1(ImGui gui, ref bool valid) { for (int i = 0; i < goal.Count; i++) { var elem = goal[i]; grid.Next(); - var evt = gui.BuildFactorioObjectWithEditableAmount(elem.item, elem.amount, elem.item.flowUnitOfMeasure, out float newAmount); - if (evt == GoodsWithAmountEvent.TextEditing) { - if (newAmount != 0f) { - elem.amount = newAmount; + DisplayAmount amount = new(elem.amount, elem.item.flowUnitOfMeasure); + if (gui.BuildFactorioObjectWithEditableAmount(elem.item, amount) == GoodsWithAmountEvent.TextEditing) { + if (amount.Value != 0f) { + elem.amount = amount.Value; } else { goal.RemoveAt(i--); @@ -90,7 +90,7 @@ protected override void BuildContent(ImGui gui) { } } grid.Next(); - if (gui.BuildFactorioObjectWithAmount(recipe.recipe, recipe.recipesPerSecond, UnitOfMeasure.PerSecond, color) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(recipe.recipe, new(recipe.recipesPerSecond, UnitOfMeasure.PerSecond), color) == Click.Left) { selectedRecipe = recipe; } } diff --git a/Yafc/Workspace/ProductionSummary/ProductionSummaryView.cs b/Yafc/Workspace/ProductionSummary/ProductionSummaryView.cs index 5fdcdf49..44dd7b08 100644 --- a/Yafc/Workspace/ProductionSummary/ProductionSummaryView.cs +++ b/Yafc/Workspace/ProductionSummary/ProductionSummaryView.cs @@ -125,8 +125,9 @@ public override void BuildElement(ImGui gui, ProductionSummaryEntry entry) { using (gui.EnterFixedPositioning(3f, 2f, default)) { gui.allocator = RectAllocator.LeftRow; gui.BuildText("x"); - if (gui.BuildFloatInput(entry.multiplier, out float newMultiplier, UnitOfMeasure.None, default) && newMultiplier >= 0) { - entry.SetMultiplier(newMultiplier); + DisplayAmount amount = entry.multiplier; + if (gui.BuildFloatInput(amount, default) && amount.Value >= 0) { + entry.SetMultiplier(amount.Value); } } } @@ -167,7 +168,7 @@ public override void BuildHeader(ImGui gui) { var moveHandle = gui.statePosition; moveHandle.Height = 5f; - if (gui.BuildFactorioObjectWithAmount(goods, view.model.GetTotalFlow(goods), goods.flowUnitOfMeasure, view.filteredGoods == goods ? SchemeColor.Primary : SchemeColor.None) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(goods, new(view.model.GetTotalFlow(goods), goods.flowUnitOfMeasure), view.filteredGoods == goods ? SchemeColor.Primary : SchemeColor.None) == Click.Left) { view.ApplyFilter(goods); } @@ -180,7 +181,7 @@ public override void BuildHeader(ImGui gui) { public override void BuildElement(ImGui gui, ProductionSummaryEntry data) { float amount = data.GetAmount(goods); if (amount != 0) { - if (gui.BuildFactorioObjectWithAmount(goods, data.GetAmount(goods), goods.flowUnitOfMeasure) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(goods, new(data.GetAmount(goods), goods.flowUnitOfMeasure)) == Click.Left) { view.ApplyFilter(goods); } } @@ -205,7 +206,7 @@ public override void BuildElement(ImGui gui, ProductionSummaryEntry data) { view.AddOrRemoveColumn(goods); } else if (evt == ButtonEvent.MouseOver) { - ImmediateWidgets.ShowPrecisionValueTooltip(gui, amount, goods.flowUnitOfMeasure, goods); + ImmediateWidgets.ShowPrecisionValueTooltip(gui, new(amount, goods.flowUnitOfMeasure), goods); } } } @@ -302,7 +303,7 @@ protected override void BuildContent(ImGui gui) { using var inlineGrid = gui.EnterInlineGrid(3f, 1f); foreach (var (goods, amount) in model.sortedFlow) { inlineGrid.Next(); - if (gui.BuildFactorioObjectWithAmount(goods, amount, goods.flowUnitOfMeasure, model.columnsExist.Contains(goods) ? SchemeColor.Primary : SchemeColor.None) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(goods, new(amount, goods.flowUnitOfMeasure), model.columnsExist.Contains(goods) ? SchemeColor.Primary : SchemeColor.None) == Click.Left) { AddOrRemoveColumn(goods); } } diff --git a/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs b/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs index 62cb9657..f4102fbb 100644 --- a/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs +++ b/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs @@ -166,27 +166,30 @@ private void DrawRecipeModules(ImGui gui, EntityBeacon? beacon, ref ModuleEffect var list = beacon != null ? modules!.beaconList : modules!.list;// null-forgiving: Both calls are from places where we know modules is not null foreach (RecipeRowCustomModule rowCustomModule in list) { grid.Next(); - var evt = gui.BuildFactorioObjectWithEditableAmount(rowCustomModule.module, rowCustomModule.fixedCount, UnitOfMeasure.None, out float newAmount); - if (evt == GoodsWithAmountEvent.LeftButtonClick) { - SelectSingleObjectPanel.SelectWithNone(GetModules(beacon), "Select module", sel => { - if (sel == null) { - _ = modules.RecordUndo(); - list.Remove(rowCustomModule); + DisplayAmount amount = rowCustomModule.fixedCount; + switch (gui.BuildFactorioObjectWithEditableAmount(rowCustomModule.module, amount)) { + case GoodsWithAmountEvent.LeftButtonClick: + SelectSingleObjectPanel.SelectWithNone(GetModules(beacon), "Select module", sel => { + if (sel == null) { + _ = modules.RecordUndo(); + list.Remove(rowCustomModule); + } + else { + rowCustomModule.RecordUndo().module = sel; + } + + gui.Rebuild(); + }, DataUtils.FavoriteModule); + break; + + case GoodsWithAmountEvent.TextEditing: + int amountInt = MathUtils.Floor(amount.Value); + if (amountInt < 0) { + amountInt = 0; } - else { - rowCustomModule.RecordUndo().module = sel; - } - - gui.Rebuild(); - }, DataUtils.FavoriteModule); - } - else if (evt == GoodsWithAmountEvent.TextEditing) { - int amountInt = MathUtils.Floor(newAmount); - if (amountInt < 0) { - amountInt = 0; - } - rowCustomModule.RecordUndo().fixedCount = amountInt; + rowCustomModule.RecordUndo().fixedCount = amountInt; + break; } if (beacon == null) { diff --git a/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs b/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs index ce568461..be0dfcca 100644 --- a/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs +++ b/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs @@ -24,7 +24,8 @@ private ModuleFillerParametersScreen(ModuleFillerParameters modules) { /// private void ListDrawer(ImGui gui, KeyValuePair element, int index) { (EntityCrafter crafter, BeaconOverrideConfiguration config) = element; - GoodsWithAmountEvent click = gui.BuildFactorioObjectWithEditableAmount(crafter, config.beaconCount, UnitOfMeasure.None, out float newAmount, allowScroll: false); + DisplayAmount amount = config.beaconCount; + GoodsWithAmountEvent click = gui.BuildFactorioObjectWithEditableAmount(crafter, amount, allowScroll: false); gui.DrawIcon(new(gui.lastRect.X, gui.lastRect.Y, 1.25f, 1.25f), config.beacon.icon, SchemeColor.Source); gui.DrawIcon(new(gui.lastRect.TopRight - new Vector2(1.25f, 0), new Vector2(1.25f, 1.25f)), config.beaconModule.icon, SchemeColor.Source); switch (click) { @@ -49,7 +50,7 @@ private void ListDrawer(ImGui gui, KeyValuePair 0) { - modules.RecordUndo().beaconsPerBuilding = newAmount; + DisplayAmount amount = modules.beaconsPerBuilding; + if (gui.BuildFloatInput(amount, new Padding(0.5f, 0f)) && (int)amount.Value > 0) { + modules.RecordUndo().beaconsPerBuilding = (int)amount.Value; } } gui.BuildText("Please note that beacons themselves are not part of the calculation", wrap: true); @@ -138,7 +139,8 @@ public override void Build(ImGui gui) { } using (gui.EnterRow()) { foreach ((EntityCrafter crafter, BeaconOverrideConfiguration beaconInfo) in modules.overrideCrafterBeacons) { - GoodsWithAmountEvent click = gui.BuildFactorioObjectWithEditableAmount(crafter, beaconInfo.beaconCount, UnitOfMeasure.None, out float newAmount); + DisplayAmount amount = beaconInfo.beaconCount; + GoodsWithAmountEvent click = gui.BuildFactorioObjectWithEditableAmount(crafter, amount); gui.DrawIcon(new Rect(gui.lastRect.TopLeft, new Vector2(1.25f, 1.25f)), beaconInfo.beacon.icon, SchemeColor.Source); gui.DrawIcon(new Rect(gui.lastRect.TopRight - new Vector2(1.25f, 0), new Vector2(1.25f, 1.25f)), beaconInfo.beaconModule.icon, SchemeColor.Source); switch (click) { @@ -167,7 +169,7 @@ public override void Build(ImGui gui) { }, noneTooltip: "Click here to remove the current override."); return; case GoodsWithAmountEvent.TextEditing: - modules.RecordUndo().overrideCrafterBeacons[crafter].beaconCount = (int)newAmount; + modules.RecordUndo().overrideCrafterBeacons[crafter].beaconCount = (int)amount.Value; return; } } @@ -187,23 +189,23 @@ public override void Build(ImGui gui) { gui.AllocateSpacing(); using (gui.EnterRow()) { gui.BuildText("Mining productivity bonus (project-wide setting): "); - if (gui.BuildTextInput(DataUtils.FormatAmount(Project.current.settings.miningProductivity, UnitOfMeasure.Percent), out string newText, null, Icon.None, true, new Padding(0.5f, 0f)) && - DataUtils.TryParseAmount(newText, out float newAmount, UnitOfMeasure.Percent) && newAmount >= 0) { - Project.current.settings.RecordUndo().miningProductivity = newAmount; + DisplayAmount amount = new(Project.current.settings.miningProductivity, UnitOfMeasure.Percent); + if (gui.BuildFloatInput(amount, new Padding(.5f, 0)) && amount.Value >= 0) { + Project.current.settings.RecordUndo().miningProductivity = amount.Value; } } using (gui.EnterRow()) { gui.BuildText("Research speed bonus (project-wide setting): "); - if (gui.BuildTextInput(DataUtils.FormatAmount(Project.current.settings.researchSpeedBonus, UnitOfMeasure.Percent), out string newText, null, Icon.None, true, new Padding(0.5f, 0f)) && - DataUtils.TryParseAmount(newText, out float newAmount, UnitOfMeasure.Percent) && newAmount >= 0) { - Project.current.settings.RecordUndo().researchSpeedBonus = newAmount; + DisplayAmount amount = new(Project.current.settings.researchSpeedBonus, UnitOfMeasure.Percent); + if (gui.BuildFloatInput(amount, new Padding(.5f, 0)) && amount.Value >= 0) { + Project.current.settings.RecordUndo().researchSpeedBonus = amount.Value; } } using (gui.EnterRow()) { gui.BuildText("Research productivity bonus (project-wide setting): "); - if (gui.BuildTextInput(DataUtils.FormatAmount(Project.current.settings.researchProductivity, UnitOfMeasure.Percent), out string newText, null, Icon.None, true, new Padding(0.5f, 0f)) && - DataUtils.TryParseAmount(newText, out float newAmount, UnitOfMeasure.Percent) && newAmount >= 0) { - Project.current.settings.RecordUndo().researchProductivity = newAmount; + DisplayAmount amount = new(Project.current.settings.researchProductivity, UnitOfMeasure.Percent); + if (gui.BuildFloatInput(amount, new Padding(.5f, 0)) && amount.Value >= 0) { + Project.current.settings.RecordUndo().researchProductivity = amount.Value; } } diff --git a/Yafc/Workspace/ProductionTable/ProductionTableView.cs b/Yafc/Workspace/ProductionTable/ProductionTableView.cs index a832dfe2..2e66fff7 100644 --- a/Yafc/Workspace/ProductionTable/ProductionTableView.cs +++ b/Yafc/Workspace/ProductionTable/ProductionTableView.cs @@ -281,15 +281,16 @@ public override void BuildElement(ImGui gui, RecipeRow recipe) { using (var group = gui.EnterGroup(default, RectAllocator.Stretch, spacing: 0f)) { group.SetWidth(3f); if (recipe.fixedBuildings > 0) { - var evt = gui.BuildFactorioObjectWithEditableAmount(recipe.entity, recipe.fixedBuildings, UnitOfMeasure.None, out float newAmount, useScale: false); + DisplayAmount amount = recipe.fixedBuildings; + GoodsWithAmountEvent evt = gui.BuildFactorioObjectWithEditableAmount(recipe.entity, amount, useScale: false); if (evt == GoodsWithAmountEvent.TextEditing) { - recipe.RecordUndo().fixedBuildings = newAmount; + recipe.RecordUndo().fixedBuildings = amount.Value; } click = (Click)evt; } else { - click = gui.BuildFactorioObjectWithAmount(recipe.entity, recipe.buildingCount, UnitOfMeasure.None, useScale: false); + click = gui.BuildFactorioObjectWithAmount(recipe.entity, recipe.buildingCount, useScale: false); } if (recipe.builtBuildings != null) { @@ -339,7 +340,7 @@ private static void BuildSolarPanelAccumulatorView(ImGui gui, RecipeRow recipe) var accumulator = recipe.GetVariant(Database.allAccumulators); float requiredMj = recipe.entity?.craftingSpeed * recipe.buildingCount * (70 / 0.7f) ?? 0; // 70 seconds of charge time to last through the night float requiredAccumulators = requiredMj / accumulator.accumulatorCapacity; - if (gui.BuildFactorioObjectWithAmount(accumulator, requiredAccumulators, UnitOfMeasure.None) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(accumulator, requiredAccumulators) == Click.Left) { ShowAccumulatorDropdown(gui, recipe, accumulator); } } @@ -565,7 +566,7 @@ public override void BuildElement(ImGui gui, RecipeRow recipe) { void drawItem(ImGui gui, FactorioObject? item, int count) { grid.Next(); - switch (gui.BuildFactorioObjectWithAmount(item, count, UnitOfMeasure.None, useScale: false)) { + switch (gui.BuildFactorioObjectWithAmount(item, count, useScale: false)) { case Click.Left: ShowModuleDropDown(gui, recipe); break; @@ -584,15 +585,15 @@ private void ShowModuleTemplateTooltip(ImGui gui, ModuleTemplate template) => gu using var grid = imGui.EnterInlineGrid(3f, 1f); foreach (var module in template.list) { grid.Next(); - _ = imGui.BuildFactorioObjectWithAmount(module.module, module.fixedCount, UnitOfMeasure.None); + _ = imGui.BuildFactorioObjectWithAmount(module.module, module.fixedCount); } if (template.beacon != null) { grid.Next(); - _ = imGui.BuildFactorioObjectWithAmount(template.beacon, template.CalcBeaconCount(), UnitOfMeasure.None); + _ = imGui.BuildFactorioObjectWithAmount(template.beacon, template.CalcBeaconCount()); foreach (var module in template.beaconList) { grid.Next(); - _ = imGui.BuildFactorioObjectWithAmount(module.module, module.fixedCount, UnitOfMeasure.None); + _ = imGui.BuildFactorioObjectWithAmount(module.module, module.fixedCount); } } }); @@ -925,15 +926,16 @@ private void DrawDesiredProduct(ImGui gui, ProductionLink element) { } ObjectTooltipOptions tooltipOptions = element.amount < 0 ? HintLocations.OnConsumingRecipes : HintLocations.OnProducingRecipes; - switch (gui.BuildFactorioObjectWithEditableAmount(element.goods, element.amount, element.goods.flowUnitOfMeasure, out float newAmount, iconColor, tooltipOptions: tooltipOptions)) { + DisplayAmount amount = new(element.amount, element.goods.flowUnitOfMeasure); + switch (gui.BuildFactorioObjectWithEditableAmount(element.goods, amount, iconColor, tooltipOptions: tooltipOptions)) { case GoodsWithAmountEvent.LeftButtonClick: OpenProductDropdown(gui, gui.lastRect, element.goods, element.amount, element, ProductDropdownType.DesiredProduct, null, element.owner); break; case GoodsWithAmountEvent.RightButtonClick: DestroyLink(element); break; - case GoodsWithAmountEvent.TextEditing when newAmount != 0: - element.RecordUndo().amount = newAmount; + case GoodsWithAmountEvent.TextEditing when amount.Value != 0: + element.RecordUndo().amount = amount.Value; break; } } @@ -979,7 +981,7 @@ private void BuildGoodsIcon(ImGui gui, Goods? goods, ProductionLink? link, float textColor = SchemeColor.BackgroundTextFaint; } - switch (gui.BuildFactorioObjectWithAmount(goods, amount, goods?.flowUnitOfMeasure ?? UnitOfMeasure.None, iconColor, textColor, tooltipOptions: tooltipOptions)) { + switch (gui.BuildFactorioObjectWithAmount(goods, new(amount, goods?.flowUnitOfMeasure ?? UnitOfMeasure.None), iconColor, textColor, tooltipOptions: tooltipOptions)) { case Click.Left when goods is not null: OpenProductDropdown(gui, gui.lastRect, goods, amount, link, dropdownType, recipe, context, variants); break; diff --git a/Yafc/Workspace/SummaryView.cs b/Yafc/Workspace/SummaryView.cs index fe677009..d67d8a1b 100644 --- a/Yafc/Workspace/SummaryView.cs +++ b/Yafc/Workspace/SummaryView.cs @@ -104,9 +104,10 @@ private static void DrawProvideProduct(ImGui gui, ProductionLink element, Projec gui.allocator = RectAllocator.Stretch; gui.spacing = 0f; - GoodsWithAmountEvent evt = gui.BuildFactorioObjectWithEditableAmount(element.goods, element.amount, element.goods.flowUnitOfMeasure, out float newAmount, iconColor); - if (evt == GoodsWithAmountEvent.TextEditing && newAmount != 0) { - SetProviderAmount(element, page, newAmount); + DisplayAmount amount = new(element.amount, element.goods.flowUnitOfMeasure); + GoodsWithAmountEvent evt = gui.BuildFactorioObjectWithEditableAmount(element.goods, amount, iconColor); + if (evt == GoodsWithAmountEvent.TextEditing && amount.Value != 0) { + SetProviderAmount(element, page, amount.Value); } else if (evt == GoodsWithAmountEvent.LeftButtonClick) { SetProviderAmount(element, page, YafcRounding(goodInfo.sum)); @@ -131,7 +132,7 @@ private static void DrawRequestProduct(ImGui gui, ProductionTableFlow flow, bool gui.allocator = RectAllocator.Stretch; gui.spacing = 0f; - _ = gui.BuildFactorioObjectWithAmount(flow.goods, -flow.amount, flow.goods?.flowUnitOfMeasure ?? UnitOfMeasure.None, iconColor); + _ = gui.BuildFactorioObjectWithAmount(flow.goods, new(-flow.amount, flow.goods.flowUnitOfMeasure), iconColor); } private static void SetProviderAmount(ProductionLink element, ProjectPage page, float newAmount) { From 15f67a8bb739a5166cdc7bf9f09de91fb4174d00 Mon Sep 17 00:00:00 2001 From: Dale McCoy <21223975+DaleStan@users.noreply.github.com> Date: Thu, 1 Aug 2024 23:46:27 -0400 Subject: [PATCH 3/6] Fix several places where we should be filtering negative values. --- Yafc/Windows/PreferencesScreen.cs | 2 +- .../ProductionTable/ModuleCustomizationScreen.cs | 9 ++------- .../ProductionTable/ModuleFillerParametersScreen.cs | 4 ++-- Yafc/Workspace/ProductionTable/ProductionTableView.cs | 2 +- changelog.txt | 5 +++++ 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Yafc/Windows/PreferencesScreen.cs b/Yafc/Windows/PreferencesScreen.cs index c0c2db89..cbac3b37 100644 --- a/Yafc/Windows/PreferencesScreen.cs +++ b/Yafc/Windows/PreferencesScreen.cs @@ -41,7 +41,7 @@ public override void Build(ImGui gui) { using (gui.EnterRowWithHelpIcon("0 for off, 100% for old default")) { gui.BuildText("Pollution cost modifier", topOffset: 0.5f); DisplayAmount amount = new(settings.PollutionCostModifier, UnitOfMeasure.Percent); - if (gui.BuildFloatInput(amount, new Padding(0.5f))) { + if (gui.BuildFloatInput(amount, new Padding(0.5f)) && amount.Value >= 0) { settings.RecordUndo().PollutionCostModifier = amount.Value; gui.Rebuild(); } diff --git a/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs b/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs index f4102fbb..cb927239 100644 --- a/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs +++ b/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs @@ -182,13 +182,8 @@ private void DrawRecipeModules(ImGui gui, EntityBeacon? beacon, ref ModuleEffect }, DataUtils.FavoriteModule); break; - case GoodsWithAmountEvent.TextEditing: - int amountInt = MathUtils.Floor(amount.Value); - if (amountInt < 0) { - amountInt = 0; - } - - rowCustomModule.RecordUndo().fixedCount = amountInt; + case GoodsWithAmountEvent.TextEditing when amount.Value >= 0: + rowCustomModule.RecordUndo().fixedCount = (int)amount.Value; break; } diff --git a/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs b/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs index be0dfcca..6f6c6882 100644 --- a/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs +++ b/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs @@ -49,7 +49,7 @@ private void ListDrawer(ImGui gui, KeyValuePair= 0: modules.RecordUndo().overrideCrafterBeacons[crafter].beaconCount = (int)amount.Value; break; } @@ -168,7 +168,7 @@ public override void Build(ImGui gui) { } }, noneTooltip: "Click here to remove the current override."); return; - case GoodsWithAmountEvent.TextEditing: + case GoodsWithAmountEvent.TextEditing when amount.Value >= 0: modules.RecordUndo().overrideCrafterBeacons[crafter].beaconCount = (int)amount.Value; return; } diff --git a/Yafc/Workspace/ProductionTable/ProductionTableView.cs b/Yafc/Workspace/ProductionTable/ProductionTableView.cs index 2e66fff7..b877ac66 100644 --- a/Yafc/Workspace/ProductionTable/ProductionTableView.cs +++ b/Yafc/Workspace/ProductionTable/ProductionTableView.cs @@ -283,7 +283,7 @@ public override void BuildElement(ImGui gui, RecipeRow recipe) { if (recipe.fixedBuildings > 0) { DisplayAmount amount = recipe.fixedBuildings; GoodsWithAmountEvent evt = gui.BuildFactorioObjectWithEditableAmount(recipe.entity, amount, useScale: false); - if (evt == GoodsWithAmountEvent.TextEditing) { + if (evt == GoodsWithAmountEvent.TextEditing && amount.Value >= 0) { recipe.RecordUndo().fixedBuildings = amount.Value; } diff --git a/changelog.txt b/changelog.txt index a94c846b..8901edb7 100644 --- a/changelog.txt +++ b/changelog.txt @@ -15,6 +15,11 @@ // Internal changes: // Changes to the code that do not affect the behavior of the program. ---------------------------------------------------------------------------------------------------------------------- +Version +Date: + Bugfixes: + - Refuse to accept negative numbers in several places where they don't make sense. +---------------------------------------------------------------------------------------------------------------------- Version 0.8.0 Date: August 3rd 2024 Features: From 6fb1b828bf57efb1a952251ac184c34375594d1f Mon Sep 17 00:00:00 2001 From: Dale McCoy <21223975+DaleStan@users.noreply.github.com> Date: Fri, 2 Aug 2024 16:36:35 -0400 Subject: [PATCH 4/6] Add DisplayStyles for labels. --- Yafc.UI/Core/ExceptionScreen.cs | 4 +- Yafc.UI/ImGui/ImGuiBuilding.cs | 14 +++--- Yafc.UI/ImGui/ImGuiUtils.cs | 18 +++---- Yafc.UI/ImGui/TextDisplayStyles.cs | 37 ++++++++++++++ Yafc/Widgets/ImmediateWidgets.cs | 11 +++-- Yafc/Widgets/ObjectTooltip.cs | 48 +++++++++---------- Yafc/Widgets/PseudoScreen.cs | 2 +- Yafc/Windows/AboutScreen.cs | 12 ++--- Yafc/Windows/DependencyExplorer.cs | 6 +-- Yafc/Windows/ErrorListPanel.cs | 2 +- Yafc/Windows/FilesystemScreen.cs | 2 +- Yafc/Windows/ImageSharePanel.cs | 2 +- Yafc/Windows/MainScreen.cs | 4 +- Yafc/Windows/MessageBox.cs | 2 +- Yafc/Windows/MilestonesEditor.cs | 2 +- Yafc/Windows/MilestonesPanel.cs | 4 +- Yafc/Windows/NeverEnoughItemsPanel.cs | 10 ++-- Yafc/Windows/SelectMultiObjectPanel.cs | 2 +- Yafc/Windows/ShoppingListScreen.cs | 4 +- Yafc/Windows/WelcomeScreen.cs | 32 ++++++------- Yafc/Workspace/AutoPlannerView.cs | 4 +- .../ProductionSummaryView.cs | 2 +- .../ModuleCustomizationScreen.cs | 2 +- .../ModuleFillerParametersScreen.cs | 6 +-- .../ProductionLinkSummaryScreen.cs | 4 +- .../ProductionTableFlatHierarchy.cs | 2 +- .../ProductionTable/ProductionTableView.cs | 34 ++++++------- Yafc/Workspace/SummaryView.cs | 2 +- 28 files changed, 157 insertions(+), 117 deletions(-) create mode 100644 Yafc.UI/ImGui/TextDisplayStyles.cs diff --git a/Yafc.UI/Core/ExceptionScreen.cs b/Yafc.UI/Core/ExceptionScreen.cs index 5cb06952..1d0bb016 100644 --- a/Yafc.UI/Core/ExceptionScreen.cs +++ b/Yafc.UI/Core/ExceptionScreen.cs @@ -35,8 +35,8 @@ protected internal override void Close() { protected override void BuildContents(ImGui gui) { gui.BuildText(ex.GetType().Name, Font.header); - gui.BuildText(ex.Message, Font.subheader, true); - gui.BuildText(ex.StackTrace, Font.text, true); + gui.BuildText(ex.Message, new TextBlockDisplayStyle(Font.subheader, true)); + gui.BuildText(ex.StackTrace, TextBlockDisplayStyle.WrappedText); using (gui.EnterRow(0.5f, RectAllocator.RightRow)) { if (gui.BuildButton("Close")) { Close(); diff --git a/Yafc.UI/ImGui/ImGuiBuilding.cs b/Yafc.UI/ImGui/ImGuiBuilding.cs index 8dde787b..b6f4c8b8 100644 --- a/Yafc.UI/ImGui/ImGuiBuilding.cs +++ b/Yafc.UI/ImGui/ImGuiBuilding.cs @@ -88,12 +88,14 @@ public SchemeColor textColor { set => state.textColor = value; } - public void BuildText(string? text, Font? font = null, bool wrap = false, RectAlignment align = RectAlignment.MiddleLeft, SchemeColor color = SchemeColor.None, float topOffset = 0f, float maxWidth = float.MaxValue) { + public void BuildText(string? text, TextBlockDisplayStyle? displayStyle = null, float topOffset = 0f, float maxWidth = float.MaxValue) { + displayStyle ??= TextBlockDisplayStyle.Default(); + SchemeColor color = displayStyle.Color; if (color == SchemeColor.None) { color = state.textColor; } - var rect = AllocateTextRect(out var cache, text, font, wrap, align, topOffset, maxWidth); + Rect rect = AllocateTextRect(out TextCache? cache, text, displayStyle, topOffset, maxWidth); if (action == ImGuiAction.Build && cache != null) { DrawRenderable(rect, cache, color); } @@ -112,16 +114,16 @@ public Vector2 GetTextDimensions(out TextCache? cache, string? text, Font? font return new Vector2(textWidth, cache.texRect.h / pixelsPerUnit); } - public Rect AllocateTextRect(out TextCache? cache, string? text, Font? font = null, bool wrap = false, RectAlignment align = RectAlignment.MiddleLeft, float topOffset = 0f, float maxWidth = float.MaxValue) { - var fontSize = GetFontSize(font); + public Rect AllocateTextRect(out TextCache? cache, string? text, TextBlockDisplayStyle displayStyle, float topOffset = 0f, float maxWidth = float.MaxValue) { + FontFile.FontSize fontSize = GetFontSize(displayStyle.Font); Rect rect; if (string.IsNullOrEmpty(text)) { cache = null; rect = AllocateRect(0f, topOffset + (fontSize.lineSize / pixelsPerUnit)); } else { - Vector2 textSize = GetTextDimensions(out cache, text, font, wrap, maxWidth); - rect = AllocateRect(textSize.X, topOffset + (textSize.Y), align); + Vector2 textSize = GetTextDimensions(out cache, text, displayStyle.Font, displayStyle.WrapText, maxWidth); + rect = AllocateRect(textSize.X, topOffset + (textSize.Y), displayStyle.Alignment); } if (topOffset != 0f) { diff --git a/Yafc.UI/ImGui/ImGuiUtils.cs b/Yafc.UI/ImGui/ImGuiUtils.cs index 490dbfd6..c3c00ea3 100644 --- a/Yafc.UI/ImGui/ImGuiUtils.cs +++ b/Yafc.UI/ImGui/ImGuiUtils.cs @@ -58,7 +58,7 @@ public static ButtonEvent BuildButton(this ImGui gui, Rect rect, SchemeColor nor public static string ScanToString(SDL.SDL_Scancode scancode) => SDL.SDL_GetKeyName(SDL.SDL_GetKeyFromScancode(scancode)); public static bool BuildLink(this ImGui gui, string text) { - gui.BuildText(text, color: SchemeColor.Link); + gui.BuildText(text, TextBlockDisplayStyle.Default(SchemeColor.Link)); var rect = gui.lastRect; switch (gui.action) { case ImGuiAction.MouseMove: @@ -105,7 +105,7 @@ public static ButtonEvent BuildButton(this ImGui gui, string text, SchemeColor c } using (gui.EnterGroup(padding ?? DefaultButtonPadding, active ? color + 2 : color + 3)) { - gui.BuildText(text, Font.text, align: RectAlignment.Middle); + gui.BuildText(text, TextBlockDisplayStyle.Centered); } return active ? gui.BuildButton(gui.lastRect, color, color + 1) : ButtonEvent.None; @@ -119,10 +119,10 @@ public static ButtonEvent BuildContextMenuButton(this ImGui gui, string text, st gui.BuildIcon(icon, color: icon >= Icon.FirstCustom ? disabled ? SchemeColor.SourceFaint : SchemeColor.Source : textColor); } - gui.BuildText(text, Font.text, true, color: textColor); + gui.BuildText(text, TextBlockDisplayStyle.WrappedText with { Color = textColor }); if (rightText != null) { gui.allocator = RectAllocator.RightRow; - gui.BuildText(rightText, align: RectAlignment.MiddleRight); + gui.BuildText(rightText, new TextBlockDisplayStyle(Alignment: RectAlignment.MiddleRight)); } } return gui.BuildButton(gui.lastRect, SchemeColor.None, SchemeColor.Grey); @@ -142,7 +142,7 @@ public static ButtonEvent BuildRedButton(this ImGui gui, string text) { Rect textRect; TextCache? cache; using (gui.EnterGroup(DefaultButtonPadding)) { - textRect = gui.AllocateTextRect(out cache, text, align: RectAlignment.Middle); + textRect = gui.AllocateTextRect(out cache, text, TextBlockDisplayStyle.Centered); } var evt = gui.BuildButton(gui.lastRect, SchemeColor.None, SchemeColor.Error); @@ -200,7 +200,7 @@ public static bool WithTooltip(this ButtonEvent evt, ImGui gui, string tooltip, public static bool BuildCheckBox(this ImGui gui, string text, bool value, out bool newValue, SchemeColor color = SchemeColor.None, RectAllocator allocator = RectAllocator.LeftRow) { using (gui.EnterRow(allocator: allocator)) { gui.BuildIcon(value ? Icon.CheckBoxCheck : Icon.CheckBoxEmpty, 1.5f, color); - gui.BuildText(text, Font.text, color: color); + gui.BuildText(text, TextBlockDisplayStyle.Default(color)); } if (gui.OnClick(gui.lastRect)) { @@ -215,7 +215,7 @@ public static bool BuildCheckBox(this ImGui gui, string text, bool value, out bo public static bool BuildRadioButton(this ImGui gui, string option, bool selected, SchemeColor color = SchemeColor.None) { using (gui.EnterRow()) { gui.BuildIcon(selected ? Icon.RadioCheck : Icon.RadioEmpty, 1.5f, color); - gui.BuildText(option, Font.text, color: color, wrap: true); + gui.BuildText(option, TextBlockDisplayStyle.WrappedText with { Color = color }); } return !selected && gui.OnClick(gui.lastRect); @@ -239,7 +239,7 @@ public static bool BuildErrorRow(this ImGui gui, string text) { closed = true; } - gui.RemainingRow().BuildText(text, align: RectAlignment.Middle); + gui.RemainingRow().BuildText(text, TextBlockDisplayStyle.Centered); } if (gui.isBuilding) { gui.DrawRectangle(gui.lastRect, SchemeColor.Error); @@ -263,7 +263,7 @@ public static bool BuildIntegerInput(this ImGui gui, int value, out int newValue public static void ShowTooltip(this ImGui gui, Rect rect, GuiBuilder builder, float width = 20f) => gui.window?.ShowTooltip(gui, rect, builder, width); - public static void ShowTooltip(this ImGui gui, Rect rect, string text, float width = 20f) => gui.window?.ShowTooltip(gui, rect, x => x.BuildText(text, wrap: true), width); + public static void ShowTooltip(this ImGui gui, Rect rect, string text, float width = 20f) => gui.window?.ShowTooltip(gui, rect, x => x.BuildText(text, TextBlockDisplayStyle.WrappedText), width); public static void ShowTooltip(this ImGui gui, GuiBuilder builder, float width = 20f) => gui.window?.ShowTooltip(gui, gui.lastRect, builder, width); diff --git a/Yafc.UI/ImGui/TextDisplayStyles.cs b/Yafc.UI/ImGui/TextDisplayStyles.cs new file mode 100644 index 00000000..e81b4027 --- /dev/null +++ b/Yafc.UI/ImGui/TextDisplayStyles.cs @@ -0,0 +1,37 @@ +namespace Yafc.UI; + +/// +/// Contains the display parameters for fixed text (TextBlock in WPF, Label in WinForms) +/// +/// The to use when drawing the text, or to use . +/// Specifies whether or not the text should be wrapped. +/// Where the text should be drawn within the renderable area. +/// The color to use, or to use the previous color. +public record TextBlockDisplayStyle(Font? Font = null, bool WrapText = false, RectAlignment Alignment = RectAlignment.MiddleLeft, SchemeColor Color = SchemeColor.None) { + /// + /// Gets the default display style (, not wrapped, left-aligned), with the specified color. + /// + /// The color to use, or to use the previous color. + public static TextBlockDisplayStyle Default(SchemeColor color = SchemeColor.None) => new(Color: color); + /// + /// Gets the display style for nonwrapped centered text. + /// + public static TextBlockDisplayStyle Centered { get; } = new(Alignment: RectAlignment.Middle); + /// + /// Gets the display style for hint text. + /// + public static TextBlockDisplayStyle HintText { get; } = new(Color: SchemeColor.BackgroundTextFaint); + /// + /// Gets the display style for wrapped, left-aligned text. + /// + public static TextBlockDisplayStyle WrappedText { get; } = new(WrapText: true); + /// + /// Gets the display style for most error messages. + /// + public static TextBlockDisplayStyle ErrorText { get; } = new(WrapText: true, Color: SchemeColor.Error); + + /// + /// Converts a font to the default display style (not wrapped, left-aligned, default color) for that font. + /// + public static implicit operator TextBlockDisplayStyle(Font font) => new(font); +} diff --git a/Yafc/Widgets/ImmediateWidgets.cs b/Yafc/Widgets/ImmediateWidgets.cs index e71be15c..64822ba1 100644 --- a/Yafc/Widgets/ImmediateWidgets.cs +++ b/Yafc/Widgets/ImmediateWidgets.cs @@ -130,10 +130,10 @@ public static Click BuildFactorioObjectButtonWithText(this ImGui gui, FactorioOb if (extraText != null) { gui.AllocateSpacing(); gui.allocator = RectAllocator.RightRow; - gui.BuildText(extraText, color: color); + gui.BuildText(extraText, TextBlockDisplayStyle.Default(color)); } _ = gui.RemainingRow(); - gui.BuildText(obj == null ? "None" : obj.locName, wrap: true, color: color); + gui.BuildText(obj == null ? "None" : obj.locName, TextBlockDisplayStyle.WrappedText with { Color = color }); } return gui.BuildFactorioObjectButton(gui.lastRect, obj); @@ -205,13 +205,14 @@ public static void BuildInlineObjectListAndButtonWithNone(this ImGui gui, ICo /// Draw the icon for this object, or an empty box if this is . /// Display this value and unit. /// If , this icon will be displayed at , instead of at 100% scale. - public static Click BuildFactorioObjectWithAmount(this ImGui gui, FactorioObject? goods, DisplayAmount amount, SchemeColor bgColor = SchemeColor.None, SchemeColor textColor = SchemeColor.None, bool useScale = true, ObjectTooltipOptions tooltipOptions = default) { + public static Click BuildFactorioObjectWithAmount(this ImGui gui, FactorioObject? goods, DisplayAmount amount, SchemeColor bgColor = SchemeColor.None, TextBlockDisplayStyle? textDisplayStyle = null, bool useScale = true, ObjectTooltipOptions tooltipOptions = default) { + textDisplayStyle ??= new(Alignment: RectAlignment.Middle); using (gui.EnterFixedPositioning(3f, 3f, default)) { gui.allocator = RectAllocator.Stretch; gui.spacing = 0f; Click clicked = gui.BuildFactorioObjectButton(goods, 3f, MilestoneDisplay.Contained, bgColor, useScale, tooltipOptions); if (goods != null) { - gui.BuildText(DataUtils.FormatAmount(amount.Value, amount.Unit), Font.text, false, RectAlignment.Middle, textColor); + gui.BuildText(DataUtils.FormatAmount(amount.Value, amount.Unit), textDisplayStyle); if (InputSystem.Instance.control && gui.BuildButton(gui.lastRect, SchemeColor.None, SchemeColor.Grey) == ButtonEvent.MouseOver) { ShowPrecisionValueTooltip(gui, amount, goods); } @@ -241,7 +242,7 @@ public static void ShowPrecisionValueTooltip(ImGui gui, DisplayAmount amount, Fa } gui.ShowTooltip(gui.lastRect, x => { _ = x.BuildFactorioObjectButtonWithText(goods); - x.BuildText(text, wrap: true); + x.BuildText(text, TextBlockDisplayStyle.WrappedText); }, 10f); } diff --git a/Yafc/Widgets/ObjectTooltip.cs b/Yafc/Widgets/ObjectTooltip.cs index 086ec93a..dc0bf8a3 100644 --- a/Yafc/Widgets/ObjectTooltip.cs +++ b/Yafc/Widgets/ObjectTooltip.cs @@ -40,7 +40,7 @@ private void BuildHeader(ImGui gui) { name = name + " (" + target.target.type + ")"; } - gui.BuildText(name, Font.header, true); + gui.BuildText(name, new TextBlockDisplayStyle(Font.header, true)); var milestoneMask = Milestones.Instance.GetMilestoneResult(target.target); if (milestoneMask.HighestBitSet() > 0) { float spacing = MathF.Min((22f / Milestones.Instance.currentMilestones.Length) - 1f, 0f); @@ -75,7 +75,7 @@ private void BuildIconRow(ImGui gui, IReadOnlyList objects, int const int itemsPerRow = 9; int count = objects.Count; if (count == 0) { - gui.BuildText("Nothing", color: SchemeColor.BackgroundTextFaint); + gui.BuildText("Nothing", TextBlockDisplayStyle.HintText); return; } @@ -118,7 +118,7 @@ private void BuildIconRow(ImGui gui, IReadOnlyList objects, int private void BuildItem(ImGui gui, IFactorioObjectWrapper item) { using (gui.EnterRow()) { gui.BuildFactorioObjectIcon(item.target); - gui.BuildText(item.text, wrap: true); + gui.BuildText(item.text, TextBlockDisplayStyle.WrappedText); } } @@ -150,21 +150,21 @@ private void BuildCommon(FactorioObject target, ImGui gui) { } if (target.locDescr != null) { - gui.BuildText(target.locDescr, wrap: true); + gui.BuildText(target.locDescr, TextBlockDisplayStyle.WrappedText); } if (!target.IsAccessible()) { - gui.BuildText("This " + target.type + " is inaccessible, or it is only accessible through mod or map script. Middle click to open dependency analyzer to investigate.", wrap: true); + gui.BuildText("This " + target.type + " is inaccessible, or it is only accessible through mod or map script. Middle click to open dependency analyzer to investigate.", TextBlockDisplayStyle.WrappedText); } else if (!target.IsAutomatable()) { - gui.BuildText("This " + target.type + " cannot be fully automated. This means that it requires either manual crafting, or manual labor such as cutting trees", wrap: true); + gui.BuildText("This " + target.type + " cannot be fully automated. This means that it requires either manual crafting, or manual labor such as cutting trees", TextBlockDisplayStyle.WrappedText); } else { - gui.BuildText(CostAnalysis.GetDisplayCost(target), wrap: true); + gui.BuildText(CostAnalysis.GetDisplayCost(target), TextBlockDisplayStyle.WrappedText); } if (target.IsAccessibleWithCurrentMilestones() && !target.IsAutomatableWithCurrentMilestones()) { - gui.BuildText("This " + target.type + " cannot be fully automated at current milestones.", wrap: true); + gui.BuildText("This " + target.type + " cannot be fully automated at current milestones.", TextBlockDisplayStyle.WrappedText); } if (target.specialType != FactorioObjectSpecialType.Normal) { @@ -198,7 +198,7 @@ private void BuildEntity(Entity entity, ImGui gui) { if (entity.mapGenerated) { using (gui.EnterGroup(contentPadding)) { - gui.BuildText("Generates on map (estimated density: " + (entity.mapGenDensity <= 0f ? "unknown" : DataUtils.FormatAmount(entity.mapGenDensity, UnitOfMeasure.None)) + ")", wrap: true); + gui.BuildText("Generates on map (estimated density: " + (entity.mapGenDensity <= 0f ? "unknown" : DataUtils.FormatAmount(entity.mapGenDensity, UnitOfMeasure.None)) + ")", TextBlockDisplayStyle.WrappedText); } } @@ -218,7 +218,7 @@ private void BuildEntity(Entity entity, ImGui gui) { if (crafter.allowedEffects != AllowedEffects.None) { gui.BuildText("Module slots: " + crafter.moduleSlots); if (crafter.allowedEffects != AllowedEffects.All) { - gui.BuildText("Only allowed effects: " + crafter.allowedEffects, wrap: true); + gui.BuildText("Only allowed effects: " + crafter.allowedEffects, TextBlockDisplayStyle.WrappedText); } } } @@ -245,16 +245,16 @@ private void BuildEntity(Entity entity, ImGui gui) { } if (entity.energy.emissions != 0f) { - var emissionColor = SchemeColor.BackgroundText; + TextBlockDisplayStyle emissionStyle = TextBlockDisplayStyle.Default(SchemeColor.BackgroundText); if (entity.energy.emissions < 0f) { - emissionColor = SchemeColor.Green; - gui.BuildText("This building absorbs pollution", color: emissionColor); + emissionStyle = TextBlockDisplayStyle.Default(SchemeColor.Green); + gui.BuildText("This building absorbs pollution", emissionStyle); } else if (entity.energy.emissions >= 20f) { - emissionColor = SchemeColor.Error; - gui.BuildText("This building contributes to global warning!", color: emissionColor); + emissionStyle = TextBlockDisplayStyle.Default(SchemeColor.Error); + gui.BuildText("This building contributes to global warning!", emissionStyle); } - gui.BuildText("Emissions: " + DataUtils.FormatAmount(entity.energy.emissions, UnitOfMeasure.None), color: emissionColor); + gui.BuildText("Emissions: " + DataUtils.FormatAmount(entity.energy.emissions, UnitOfMeasure.None), emissionStyle); } } } @@ -293,7 +293,7 @@ private void BuildGoods(Goods goods, ImGui gui) { BuildCommon(goods, gui); if (goods.showInExplorers) { using (gui.EnterGroup(contentPadding)) { - gui.BuildText("Middle mouse button to open Never Enough Items Explorer for this " + goods.type, wrap: true); + gui.BuildText("Middle mouse button to open Never Enough Items Explorer for this " + goods.type, TextBlockDisplayStyle.WrappedText); } } @@ -303,7 +303,7 @@ private void BuildGoods(Goods goods, ImGui gui) { BuildIconRow(gui, goods.production, 2); if (tooltipOptions.HintLocations.HasFlag(HintLocations.OnProducingRecipes)) { goods.production.SelectSingle(out string recipeTip); - gui.BuildText(recipeTip, color: SchemeColor.BackgroundTextFaint); + gui.BuildText(recipeTip, TextBlockDisplayStyle.HintText); } } } @@ -321,7 +321,7 @@ private void BuildGoods(Goods goods, ImGui gui) { BuildIconRow(gui, goods.usages, 4); if (tooltipOptions.HintLocations.HasFlag(HintLocations.OnConsumingRecipes)) { goods.usages.SelectSingle(out string recipeTip); - gui.BuildText(recipeTip, color: SchemeColor.BackgroundTextFaint); + gui.BuildText(recipeTip, TextBlockDisplayStyle.HintText); } } } @@ -403,15 +403,15 @@ private void BuildRecipe(RecipeOrTechnology recipe, ImGui gui) { if (waste > 0.01f) { int wasteAmount = MathUtils.Round(waste * 100f); string wasteText = ". (Wasting " + wasteAmount + "% of YAFC cost)"; - var color = wasteAmount < 90 ? SchemeColor.BackgroundText : SchemeColor.Error; + TextBlockDisplayStyle style = TextBlockDisplayStyle.WrappedText with { Color = wasteAmount < 90 ? SchemeColor.BackgroundText : SchemeColor.Error }; if (recipe.products.Length == 1) { - gui.BuildText("YAFC analysis: There are better recipes to create " + recipe.products[0].goods.locName + wasteText, wrap: true, color: color); + gui.BuildText("YAFC analysis: There are better recipes to create " + recipe.products[0].goods.locName + wasteText, style); } else if (recipe.products.Length > 0) { - gui.BuildText("YAFC analysis: There are better recipes to create each of the products" + wasteText, wrap: true, color: color); + gui.BuildText("YAFC analysis: There are better recipes to create each of the products" + wasteText, style); } else { - gui.BuildText("YAFC analysis: This recipe wastes useful products. Don't do this recipe.", wrap: true, color: color); + gui.BuildText("YAFC analysis: This recipe wastes useful products. Don't do this recipe.", style); } } } @@ -495,7 +495,7 @@ private void BuildTechnology(Technology technology, ImGui gui) { BuildRecipe(technology, gui); if (technology.hidden && !technology.enabled) { using (gui.EnterGroup(contentPadding)) { - gui.BuildText("This technology is hidden from the list and cannot be researched.", wrap: true); + gui.BuildText("This technology is hidden from the list and cannot be researched.", TextBlockDisplayStyle.WrappedText); } } diff --git a/Yafc/Widgets/PseudoScreen.cs b/Yafc/Widgets/PseudoScreen.cs index d34dde56..17d34308 100644 --- a/Yafc/Widgets/PseudoScreen.cs +++ b/Yafc/Widgets/PseudoScreen.cs @@ -31,7 +31,7 @@ public void Build(ImGui gui, Vector2 screenSize) { } protected void BuildHeader(ImGui gui, string? text, bool closeButton = true) { - gui.BuildText(text, Font.header, false, RectAlignment.Middle); + gui.BuildText(text, new TextBlockDisplayStyle(Font.header, Alignment: RectAlignment.Middle)); if (closeButton) { Rect closeButtonRect = new Rect(width - 3f, 0f, 3f, 2f); if (gui.isBuilding) { diff --git a/Yafc/Windows/AboutScreen.cs b/Yafc/Windows/AboutScreen.cs index b18ac9d9..ca9570aa 100644 --- a/Yafc/Windows/AboutScreen.cs +++ b/Yafc/Windows/AboutScreen.cs @@ -8,14 +8,14 @@ public class AboutScreen : WindowUtility { protected override void BuildContents(ImGui gui) { gui.allocator = RectAllocator.Center; - gui.BuildText("Yet Another Factorio Calculator", Font.header, align: RectAlignment.Middle); - gui.BuildText("(Community Edition)", align: RectAlignment.Middle); - gui.BuildText("Copyright 2020-2021 ShadowTheAge", align: RectAlignment.Middle); - gui.BuildText("Copyright 2024 YAFC Community", align: RectAlignment.Middle); + gui.BuildText("Yet Another Factorio Calculator", new TextBlockDisplayStyle(Font.header, Alignment: RectAlignment.Middle)); + gui.BuildText("(Community Edition)", TextBlockDisplayStyle.Centered); + gui.BuildText("Copyright 2020-2021 ShadowTheAge", TextBlockDisplayStyle.Centered); + gui.BuildText("Copyright 2024 YAFC Community", TextBlockDisplayStyle.Centered); gui.allocator = RectAllocator.LeftAlign; gui.AllocateSpacing(1.5f); - gui.BuildText("This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.", wrap: true); - gui.BuildText("This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.", wrap: true); + gui.BuildText("This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.", TextBlockDisplayStyle.WrappedText); + gui.BuildText("This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.", TextBlockDisplayStyle.WrappedText); using (gui.EnterRow(0.3f)) { gui.BuildText("Full license text:"); BuildLink(gui, "https://gnu.org/licenses/gpl-3.0.html"); diff --git a/Yafc/Windows/DependencyExplorer.cs b/Yafc/Windows/DependencyExplorer.cs index 2c86de92..37ca125f 100644 --- a/Yafc/Windows/DependencyExplorer.cs +++ b/Yafc/Windows/DependencyExplorer.cs @@ -43,7 +43,7 @@ private void DrawFactorioObject(ImGui gui, FactorioId id) { using (gui.EnterGroup(listPad, RectAllocator.LeftRow)) { gui.BuildFactorioObjectIcon(fobj); string text = fobj.locName + " (" + fobj.type + ")"; - gui.RemainingRow(0.5f).BuildText(text, null, true, color: fobj.IsAccessible() ? SchemeColor.BackgroundText : SchemeColor.BackgroundTextFaint); + gui.RemainingRow(0.5f).BuildText(text, TextBlockDisplayStyle.WrappedText with { Color = fobj.IsAccessible() ? SchemeColor.BackgroundText : SchemeColor.BackgroundTextFaint }); } if (gui.BuildFactorioObjectButton(gui.lastRect, fobj, tooltipOptions: new() { ExtendHeader = true }) == Click.Left) { Change(fobj); @@ -83,7 +83,7 @@ private void DrawDependencies(ImGui gui) { text += ", and it is inaccessible"; } - gui.BuildText(text, wrap: true); + gui.BuildText(text, TextBlockDisplayStyle.WrappedText); } } } @@ -112,7 +112,7 @@ public override void Build(ImGui gui) { SelectSingleObjectPanel.Select(Database.objects.explorable, "Select something", Change); } - gui.BuildText("(Click to change)", color: SchemeColor.BackgroundTextFaint); + gui.BuildText("(Click to change)", TextBlockDisplayStyle.HintText); } using (gui.EnterRow()) { var settings = Project.current.settings; diff --git a/Yafc/Windows/ErrorListPanel.cs b/Yafc/Windows/ErrorListPanel.cs index b0bf797f..ceff718b 100644 --- a/Yafc/Windows/ErrorListPanel.cs +++ b/Yafc/Windows/ErrorListPanel.cs @@ -15,7 +15,7 @@ private ErrorListPanel(ErrorCollector collector) : base(60f) { private void BuildErrorList(ImGui gui) { foreach (var error in errors) { - gui.BuildText(error.error, wrap: true, color: error.severity >= ErrorSeverity.MajorDataLoss ? SchemeColor.Error : SchemeColor.BackgroundText); + gui.BuildText(error.error, TextBlockDisplayStyle.WrappedText with { Color = error.severity >= ErrorSeverity.MajorDataLoss ? SchemeColor.Error : SchemeColor.BackgroundText }); } } diff --git a/Yafc/Windows/FilesystemScreen.cs b/Yafc/Windows/FilesystemScreen.cs index 78da2943..fb15d82c 100644 --- a/Yafc/Windows/FilesystemScreen.cs +++ b/Yafc/Windows/FilesystemScreen.cs @@ -43,7 +43,7 @@ public FilesystemScreen(string? header, string description, string button, strin } protected override void BuildContents(ImGui gui) { - gui.BuildText(description, wrap: true); + gui.BuildText(description, TextBlockDisplayStyle.WrappedText); if (gui.BuildTextInput(location, out string newLocation, null)) { if (Directory.Exists(newLocation)) { SetLocation(newLocation); diff --git a/Yafc/Windows/ImageSharePanel.cs b/Yafc/Windows/ImageSharePanel.cs index c884f64c..b3e5705d 100644 --- a/Yafc/Windows/ImageSharePanel.cs +++ b/Yafc/Windows/ImageSharePanel.cs @@ -23,7 +23,7 @@ public ImageSharePanel(MemoryDrawingSurface surface, string name) { public override void Build(ImGui gui) { BuildHeader(gui, "Image generated"); - gui.BuildText(header, wrap: true); + gui.BuildText(header, TextBlockDisplayStyle.WrappedText); if (gui.BuildButton("Save as PNG")) { SaveAsPng(); } diff --git a/Yafc/Windows/MainScreen.cs b/Yafc/Windows/MainScreen.cs index 761c78e5..34ceda8f 100644 --- a/Yafc/Windows/MainScreen.cs +++ b/Yafc/Windows/MainScreen.cs @@ -124,7 +124,7 @@ private void BuildPage(ImGui gui, ProjectPage element, int index) { gui.BuildIcon(element.icon.icon); } - gui.RemainingRow().BuildText(element.name, color: element.visible ? SchemeColor.BackgroundText : SchemeColor.BackgroundTextFaint); + gui.RemainingRow().BuildText(element.name, TextBlockDisplayStyle.Default(element.visible ? SchemeColor.BackgroundText : SchemeColor.BackgroundTextFaint)); } var evt = gui.BuildButton(gui.lastRect, SchemeColor.PureBackground, SchemeColor.Grey, button: 0); if (evt) { @@ -726,7 +726,7 @@ public void ShowTooltip(ImGui gui, ProjectPage page, bool isMiddleEdit, Rect rec ShowTooltip(gui, rect, x => { pageView.BuildPageTooltip(x, page.content); if (isMiddleEdit) { - x.BuildText("Middle mouse button to edit", Font.text, true, color: SchemeColor.BackgroundTextFaint); + x.BuildText("Middle mouse button to edit", TextBlockDisplayStyle.WrappedText with { Color = SchemeColor.BackgroundTextFaint }); } }); } diff --git a/Yafc/Windows/MessageBox.cs b/Yafc/Windows/MessageBox.cs index 6f114db8..29e87a0e 100644 --- a/Yafc/Windows/MessageBox.cs +++ b/Yafc/Windows/MessageBox.cs @@ -32,7 +32,7 @@ public static void Show(Action? result, string title, string message public override void Build(ImGui gui) { BuildHeader(gui, title); if (message != null) { - gui.BuildText(message, wrap: true); + gui.BuildText(message, TextBlockDisplayStyle.WrappedText); } gui.AllocateSpacing(2f); diff --git a/Yafc/Windows/MilestonesEditor.cs b/Yafc/Windows/MilestonesEditor.cs index 53f67a72..f110dc6f 100644 --- a/Yafc/Windows/MilestonesEditor.cs +++ b/Yafc/Windows/MilestonesEditor.cs @@ -44,7 +44,7 @@ public override void Build(ImGui gui) { milestoneList.Build(gui); gui.BuildText( "Hint: You can reorder milestones. When an object is locked behind a milestone, the first inaccessible milestone will be shown. Also when there is a choice between different milestones, first will be chosen", - wrap: true, color: SchemeColor.BackgroundTextFaint); + TextBlockDisplayStyle.WrappedText with { Color = SchemeColor.BackgroundTextFaint }); using (gui.EnterRow()) { if (gui.BuildButton("Auto sort milestones", SchemeColor.Grey)) { ErrorCollector collector = new ErrorCollector(); diff --git a/Yafc/Windows/MilestonesPanel.cs b/Yafc/Windows/MilestonesPanel.cs index 6b302fe9..4fab8d03 100644 --- a/Yafc/Windows/MilestonesPanel.cs +++ b/Yafc/Windows/MilestonesPanel.cs @@ -43,10 +43,10 @@ public override void Build(ImGui gui) { gui.AllocateSpacing(2f); milestonesWidget.Build(gui); gui.AllocateSpacing(2f); - gui.BuildText("For your convenience, YAFC will show objects you DON'T have access to based on this selection", wrap: true); + gui.BuildText("For your convenience, YAFC will show objects you DON'T have access to based on this selection", TextBlockDisplayStyle.WrappedText); gui.BuildText("These are called 'Milestones'. By default all science packs are added as milestones, but this does not have to be this way! " + "You can define your own milestones: Any item, recipe, entity or technology may be added as a milestone. For example you can add advanced " + - "electronic circuits as a milestone, and YAFC will display everything that is locked behind those circuits", wrap: true); + "electronic circuits as a milestone, and YAFC will display everything that is locked behind those circuits", TextBlockDisplayStyle.WrappedText); using (gui.EnterRow()) { if (gui.BuildButton("Edit milestones", SchemeColor.Grey)) { MilestonesEditor.Show(); diff --git a/Yafc/Windows/NeverEnoughItemsPanel.cs b/Yafc/Windows/NeverEnoughItemsPanel.cs index 9a69a926..af0355e8 100644 --- a/Yafc/Windows/NeverEnoughItemsPanel.cs +++ b/Yafc/Windows/NeverEnoughItemsPanel.cs @@ -181,11 +181,11 @@ private void DrawRecipeEntry(ImGui gui, RecipeEntry entry, bool production) { _ = gui.BuildFactorioObjectButton(entry.recipe, 4f, MilestoneDisplay.Contained); using (gui.EnterRow()) { gui.BuildIcon(Icon.Time); - gui.BuildText(DataUtils.FormatAmount(entry.recipe.time, UnitOfMeasure.Second), align: RectAlignment.Middle); + gui.BuildText(DataUtils.FormatAmount(entry.recipe.time, UnitOfMeasure.Second), TextBlockDisplayStyle.Centered); } float bh = CostAnalysis.GetBuildingHours(recipe, entry.recipeFlow); if (bh > 20) { - gui.BuildText(DataUtils.FormatAmount(bh, UnitOfMeasure.None, suffix: "bh"), align: RectAlignment.Middle); + gui.BuildText(DataUtils.FormatAmount(bh, UnitOfMeasure.None, suffix: "bh"), TextBlockDisplayStyle.Centered); _ = gui.BuildButton(gui.lastRect, SchemeColor.None, SchemeColor.Grey).WithTooltip(gui, "Building-hours.\nAmount of building-hours required for all researches assuming crafting speed of 1"); } } @@ -201,7 +201,7 @@ private void DrawRecipeEntry(ImGui gui, RecipeEntry entry, bool production) { } gui.allocator = textAlloc; - gui.BuildText(recipe.locName, wrap: true); + gui.BuildText(recipe.locName, TextBlockDisplayStyle.WrappedText); } if (recipe.ingredients.Length + recipe.products.Length <= 8) { using (gui.EnterRow()) { @@ -284,7 +284,7 @@ private void DrawEntryList(ImGui gui, ReadOnlySpan entries, bool pr footerDrawn = true; gui.BuildText(entry.entryStatus == EntryStatus.Special ? "Show special recipes (barreling / voiding)" : entry.entryStatus == EntryStatus.NotAccessibleWithCurrentMilestones ? "There are more recipes, but they are locked based on current milestones" : - "There are more recipes but they are inaccessible", wrap: true); + "There are more recipes but they are inaccessible", TextBlockDisplayStyle.WrappedText); if (gui.BuildButton("Show more recipes")) { ChangeShowStatus(status); } @@ -348,7 +348,7 @@ public override void Build(ImGui gui) { gui.BuildText(CostAnalysis.GetDisplayCost(current)); string? amount = CostAnalysis.Instance.GetItemAmount(current); if (amount != null) { - gui.BuildText(amount, wrap: true); + gui.BuildText(amount, TextBlockDisplayStyle.WrappedText); } } diff --git a/Yafc/Windows/SelectMultiObjectPanel.cs b/Yafc/Windows/SelectMultiObjectPanel.cs index dd5d1d6a..62a1e96c 100644 --- a/Yafc/Windows/SelectMultiObjectPanel.cs +++ b/Yafc/Windows/SelectMultiObjectPanel.cs @@ -52,7 +52,7 @@ public override void Build(ImGui gui) { if (gui.BuildButton("OK")) { CloseWithResult(results); } - gui.BuildText("Hint: ctrl+click to select multiple", color: SchemeColor.BackgroundTextFaint); + gui.BuildText("Hint: ctrl+click to select multiple", TextBlockDisplayStyle.HintText); } } diff --git a/Yafc/Windows/ShoppingListScreen.cs b/Yafc/Windows/ShoppingListScreen.cs index a5095ee9..9d4d4b2f 100644 --- a/Yafc/Windows/ShoppingListScreen.cs +++ b/Yafc/Windows/ShoppingListScreen.cs @@ -47,7 +47,7 @@ public override void Build(ImGui gui) { BuildHeader(gui, "Shopping list"); gui.BuildText( "Total cost of all objects: " + DataUtils.FormatAmount(shoppingCost, UnitOfMeasure.None, "¥") + ", buildings: " + - DataUtils.FormatAmount(totalBuildings, UnitOfMeasure.None) + ", modules: " + DataUtils.FormatAmount(totalModules, UnitOfMeasure.None), align: RectAlignment.Middle); + DataUtils.FormatAmount(totalBuildings, UnitOfMeasure.None) + ", modules: " + DataUtils.FormatAmount(totalModules, UnitOfMeasure.None), TextBlockDisplayStyle.Centered); gui.AllocateSpacing(1f); list.Build(gui); using (gui.EnterRow(allocator: RectAllocator.RightRow)) { @@ -85,7 +85,7 @@ public override void Build(ImGui gui) { } private void ExportBlueprintDropdown(ImGui gui) { - gui.BuildText("Blueprint string will be copied to clipboard", wrap: true); + gui.BuildText("Blueprint string will be copied to clipboard", TextBlockDisplayStyle.WrappedText); if (Database.objectsByTypeName.TryGetValue("Entity.constant-combinator", out var combinator) && gui.BuildFactorioObjectButtonWithText(combinator) == Click.Left && gui.CloseDropdown()) { _ = BlueprintUtilities.ExportConstantCombinators("Shopping list", ExportGoods()); } diff --git a/Yafc/Windows/WelcomeScreen.cs b/Yafc/Windows/WelcomeScreen.cs index 1b4151dd..b41b5099 100644 --- a/Yafc/Windows/WelcomeScreen.cs +++ b/Yafc/Windows/WelcomeScreen.cs @@ -89,22 +89,22 @@ public WelcomeScreen(ProjectDefinition? cliProject = null) : base(ImGuiUtils.Def private void BuildError(ImGui gui) { if (errorMod != null) { - gui.BuildText("Error While loading mod " + errorMod, Font.text, align: RectAlignment.Middle, color: SchemeColor.Error); + gui.BuildText("Error While loading mod " + errorMod, TextBlockDisplayStyle.Centered with { Color = SchemeColor.Error }); } gui.allocator = RectAllocator.Stretch; - gui.BuildText(errorMessage, Font.text, color: SchemeColor.ErrorText, wrap: true); + gui.BuildText(errorMessage, TextBlockDisplayStyle.ErrorText); gui.DrawRectangle(gui.lastRect, SchemeColor.Error); } protected override void BuildContents(ImGui gui) { gui.spacing = 1.5f; - gui.BuildText("Yet Another Factorio Calculator", Font.header, align: RectAlignment.Middle); + gui.BuildText("Yet Another Factorio Calculator", new TextBlockDisplayStyle(Font.header, Alignment: RectAlignment.Middle)); if (loading) { - gui.BuildText(currentLoad1, align: RectAlignment.Middle); - gui.BuildText(currentLoad2, align: RectAlignment.Middle); + gui.BuildText(currentLoad1, TextBlockDisplayStyle.Centered); + gui.BuildText(currentLoad2, TextBlockDisplayStyle.Centered); gui.AllocateSpacing(15f); - gui.BuildText(tip, wrap: true, align: RectAlignment.Middle); + gui.BuildText(tip, new TextBlockDisplayStyle(WrapText: true, Alignment: RectAlignment.Middle)); gui.SetNextRebuild(Ui.time + 30); } else if (errorMessage != null) { @@ -178,15 +178,15 @@ protected override void BuildContents(ImGui gui) { private void ProjectErrorMoreInfo(ImGui gui) { gui.allocator = RectAllocator.LeftAlign; - gui.BuildText("Check that these mods load in Factorio", wrap: true); - gui.BuildText("YAFC only supports loading mods that were loaded in Factorio before. If you add or remove mods or change startup settings, you need to load those in Factorio and then close the game because Factorio writes some files only when exiting", wrap: true); - gui.BuildText("Check that Factorio loads mods from the same folder as YAFC", wrap: true); - gui.BuildText("If that doesn't help, try removing all the mods that are present but aren't loaded because they are disabled, don't have required dependencies, or (especially) have several versions", wrap: true); + gui.BuildText("Check that these mods load in Factorio", TextBlockDisplayStyle.WrappedText); + gui.BuildText("YAFC only supports loading mods that were loaded in Factorio before. If you add or remove mods or change startup settings, you need to load those in Factorio and then close the game because Factorio writes some files only when exiting", TextBlockDisplayStyle.WrappedText); + gui.BuildText("Check that Factorio loads mods from the same folder as YAFC", TextBlockDisplayStyle.WrappedText); + gui.BuildText("If that doesn't help, try removing all the mods that are present but aren't loaded because they are disabled, don't have required dependencies, or (especially) have several versions", TextBlockDisplayStyle.WrappedText); if (gui.BuildLink("If that doesn't help either, create a github issue")) { Ui.VisitLink(AboutScreen.Github); } - gui.BuildText("For these types of errors simple mod list will not be enough. You need to attach a 'New game' save game for syncing mods, mod versions and mod settings.", wrap: true); + gui.BuildText("For these types of errors simple mod list will not be enough. You need to attach a 'New game' save game for syncing mods, mod versions and mod settings.", TextBlockDisplayStyle.WrappedText); } private void DoLanguageList(ImGui gui, Dictionary list, bool enabled) { @@ -205,13 +205,13 @@ private void DoLanguageList(ImGui gui, Dictionary list, bool ena private void LanguageSelection(ImGui gui) { gui.spacing = 0f; gui.allocator = RectAllocator.LeftAlign; - gui.BuildText("Mods may not support your language, using English as a fallback.", wrap: true); + gui.BuildText("Mods may not support your language, using English as a fallback.", TextBlockDisplayStyle.WrappedText); gui.AllocateSpacing(0.5f); DoLanguageList(gui, languageMapping, true); if (!Program.hasOverriddenFont) { gui.AllocateSpacing(0.5f); - gui.BuildText("To select languages with non-european glyphs you need to override used font first. Download or locate a font that has your language glyphs.", wrap: true); + gui.BuildText("To select languages with non-european glyphs you need to override used font first. Download or locate a font that has your language glyphs.", TextBlockDisplayStyle.WrappedText); gui.AllocateSpacing(0.5f); } DoLanguageList(gui, languagesRequireFontOverride, Program.hasOverriddenFont); @@ -222,14 +222,14 @@ private void LanguageSelection(ImGui gui) { } if (Preferences.Instance.overrideFont != null) { - gui.BuildText(Preferences.Instance.overrideFont, wrap: true); + gui.BuildText(Preferences.Instance.overrideFont, TextBlockDisplayStyle.WrappedText); if (gui.BuildLink("Reset font to default")) { Preferences.Instance.overrideFont = null; languageScroll.RebuildContents(); Preferences.Instance.Save(); } } - gui.BuildText("Selecting font to override require YAFC restart to take effect", wrap: true); + gui.BuildText("Selecting font to override require YAFC restart to take effect", TextBlockDisplayStyle.WrappedText); } private async void SelectFont() { @@ -277,7 +277,7 @@ private void ValidateSelection() { } private void BuildPathSelect(ImGui gui, ref string path, string description, string placeholder, EditType editType) { - gui.BuildText(description, wrap: true); + gui.BuildText(description, TextBlockDisplayStyle.WrappedText); gui.spacing = 0.5f; using (gui.EnterGroup(default, RectAllocator.RightRow)) { if (gui.BuildButton("...")) { diff --git a/Yafc/Workspace/AutoPlannerView.cs b/Yafc/Workspace/AutoPlannerView.cs index 58b2c117..702f3723 100644 --- a/Yafc/Workspace/AutoPlannerView.cs +++ b/Yafc/Workspace/AutoPlannerView.cs @@ -27,7 +27,7 @@ private Action CreateAutoPlannerWizard(List pages) { string pageName = "Auto planner"; void Page1(ImGui gui, ref bool valid) { - gui.BuildText("This is an experimental feature and may lack functionality. Unfortunately, after some prototyping it wasn't very useful to work with. More research required.", wrap: true, color: SchemeColor.Error); + gui.BuildText("This is an experimental feature and may lack functionality. Unfortunately, after some prototyping it wasn't very useful to work with. More research required.", TextBlockDisplayStyle.ErrorText); gui.BuildText("Enter page name:"); _ = gui.BuildTextInput(pageName, out pageName, null); gui.AllocateSpacing(2f); @@ -56,7 +56,7 @@ void Page1(ImGui gui, ref bool valid) { grid.Next(); } gui.AllocateSpacing(2f); - gui.BuildText("Review active milestones, as they will restrict recipes that are considered:", wrap: true); + gui.BuildText("Review active milestones, as they will restrict recipes that are considered:", TextBlockDisplayStyle.WrappedText); new MilestonesWidget().Build(gui); gui.AllocateSpacing(2f); valid = !string.IsNullOrEmpty(pageName) && goal.Count > 0; diff --git a/Yafc/Workspace/ProductionSummary/ProductionSummaryView.cs b/Yafc/Workspace/ProductionSummary/ProductionSummaryView.cs index 44dd7b08..bded06e4 100644 --- a/Yafc/Workspace/ProductionSummary/ProductionSummaryView.cs +++ b/Yafc/Workspace/ProductionSummary/ProductionSummaryView.cs @@ -140,7 +140,7 @@ private void PagesDropdownDrawer(ImGui gui, ProjectPage element, int index) { gui.BuildIcon(element.icon.icon); } - gui.RemainingRow().BuildText(element.name, color: element.visible ? SchemeColor.BackgroundText : SchemeColor.BackgroundTextFaint); + gui.RemainingRow().BuildText(element.name, TextBlockDisplayStyle.Default(element.visible ? SchemeColor.BackgroundText : SchemeColor.BackgroundTextFaint)); } if (gui.BuildButton(gui.lastRect, SchemeColor.BackgroundAlt, SchemeColor.Background)) { diff --git a/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs b/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs index cb927239..a7f1e149 100644 --- a/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs +++ b/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs @@ -93,7 +93,7 @@ public override void Build(ImGui gui) { SelectBeacon(gui); } - gui.BuildText("Input the amount of modules, not the amount of beacons. Single beacon can hold " + modules.beacon.moduleSlots + " modules.", wrap: true); + gui.BuildText("Input the amount of modules, not the amount of beacons. Single beacon can hold " + modules.beacon.moduleSlots + " modules.", TextBlockDisplayStyle.WrappedText); DrawRecipeModules(gui, modules.beacon, ref effects); } diff --git a/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs b/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs index 6f6c6882..65b28900 100644 --- a/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs +++ b/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs @@ -74,7 +74,7 @@ public static void BuildSimple(ImGui gui, ModuleFillerParameters modules) { gui.BuildText("Use best modules"); } else { - gui.BuildText("Modules payback estimate: " + DataUtils.FormatTime(payback), wrap: true); + gui.BuildText("Modules payback estimate: " + DataUtils.FormatTime(payback), TextBlockDisplayStyle.WrappedText); } } @@ -93,7 +93,7 @@ public override void Build(ImGui gui) { gui.AllocateSpacing(); gui.BuildText("Filler module:", Font.subheader); - gui.BuildText("Use this module when aufofill doesn't add anything (for example when productivity modules doesn't fit)", wrap: true); + gui.BuildText("Use this module when aufofill doesn't add anything (for example when productivity modules doesn't fit)", TextBlockDisplayStyle.WrappedText); if (gui.BuildFactorioObjectButtonWithText(modules.fillerModule) == Click.Left) { SelectSingleObjectPanel.SelectWithNone(Database.allModules, "Select filler module", select => { modules.RecordUndo().fillerModule = select; }); } @@ -127,7 +127,7 @@ public override void Build(ImGui gui) { modules.RecordUndo().beaconsPerBuilding = (int)amount.Value; } } - gui.BuildText("Please note that beacons themselves are not part of the calculation", wrap: true); + gui.BuildText("Please note that beacons themselves are not part of the calculation", TextBlockDisplayStyle.WrappedText); gui.AllocateSpacing(); gui.BuildText("Override beacons:", Font.subheader); diff --git a/Yafc/Workspace/ProductionTable/ProductionLinkSummaryScreen.cs b/Yafc/Workspace/ProductionTable/ProductionLinkSummaryScreen.cs index 3b86c631..ce2d6d0e 100644 --- a/Yafc/Workspace/ProductionTable/ProductionLinkSummaryScreen.cs +++ b/Yafc/Workspace/ProductionTable/ProductionLinkSummaryScreen.cs @@ -25,12 +25,12 @@ private void BuildScrollArea(ImGui gui) { BuildFlow(gui, output, totalOutput); if (link.amount != 0) { gui.spacing = 0.5f; - gui.BuildText((link.amount > 0 ? "Requested production: " : "Requested consumption: ") + DataUtils.FormatAmount(MathF.Abs(link.amount), link.goods.flowUnitOfMeasure), Font.subheader, color: SchemeColor.GreenAlt); + gui.BuildText((link.amount > 0 ? "Requested production: " : "Requested consumption: ") + DataUtils.FormatAmount(MathF.Abs(link.amount), link.goods.flowUnitOfMeasure), new TextBlockDisplayStyle(Font.subheader, Color: SchemeColor.GreenAlt)); } if (link.flags.HasFlags(ProductionLink.Flags.LinkNotMatched) && totalInput != totalOutput + link.amount) { float amount = totalInput - totalOutput - link.amount; gui.spacing = 0.5f; - gui.BuildText((amount > 0 ? "Overproduction: " : "Overconsumption: ") + DataUtils.FormatAmount(MathF.Abs(amount), link.goods.flowUnitOfMeasure), Font.subheader, color: SchemeColor.Error); + gui.BuildText((amount > 0 ? "Overproduction: " : "Overconsumption: ") + DataUtils.FormatAmount(MathF.Abs(amount), link.goods.flowUnitOfMeasure), new TextBlockDisplayStyle(Font.subheader, Color: SchemeColor.Error)); } } diff --git a/Yafc/Workspace/ProductionTable/ProductionTableFlatHierarchy.cs b/Yafc/Workspace/ProductionTable/ProductionTableFlatHierarchy.cs index a4562488..72166031 100644 --- a/Yafc/Workspace/ProductionTable/ProductionTableFlatHierarchy.cs +++ b/Yafc/Workspace/ProductionTable/ProductionTableFlatHierarchy.cs @@ -197,7 +197,7 @@ public void Build(ImGui gui) { if (item != null) { if (item.elements.Count == 0) { using (gui.EnterGroup(new Padding(0.5f + depWidth, 0.5f, 0.5f, 0.5f))) { - gui.BuildText(emptyGroupMessage, wrap: true); // set color if the nested row is empty + gui.BuildText(emptyGroupMessage, TextBlockDisplayStyle.WrappedText); // set color if the nested row is empty } } diff --git a/Yafc/Workspace/ProductionTable/ProductionTableView.cs b/Yafc/Workspace/ProductionTable/ProductionTableView.cs index b877ac66..44314a99 100644 --- a/Yafc/Workspace/ProductionTable/ProductionTableView.cs +++ b/Yafc/Workspace/ProductionTable/ProductionTableView.cs @@ -63,7 +63,7 @@ public override void BuildElement(ImGui gui, RecipeRow row) { } foreach (var (flag, text) in WarningsMeaning) { if ((row.parameters.warningFlags & flag) != 0) { - g.BuildText(text, wrap: true); + g.BuildText(text, TextBlockDisplayStyle.WrappedText); } } }); @@ -158,7 +158,7 @@ public override void BuildElement(ImGui gui, RecipeRow recipe) { gui.textColor = recipe.hierarchyEnabled ? SchemeColor.BackgroundText : SchemeColor.BackgroundTextFaint; } - gui.BuildText(recipe.recipe.locName, wrap: true); + gui.BuildText(recipe.recipe.locName, TextBlockDisplayStyle.WrappedText); void unpackNestedTable() { var evacuate = recipe.subgroup.recipes; @@ -185,7 +185,7 @@ private void RemoveZeroRecipes(ProductionTable productionTable) { public override void BuildMenu(ImGui gui) { BuildRecipeButton(gui, view.model); - gui.BuildText("Export inputs and outputs to blueprint with constant combinators:", wrap: true); + gui.BuildText("Export inputs and outputs to blueprint with constant combinators:", TextBlockDisplayStyle.WrappedText); using (gui.EnterRow()) { gui.BuildText("Amount per:"); if (gui.BuildLink("second") && gui.CloseDropdown()) { @@ -579,7 +579,7 @@ void drawItem(ImGui gui, FactorioObject? item, int count) { private void ShowModuleTemplateTooltip(ImGui gui, ModuleTemplate template) => gui.ShowTooltip(imGui => { if (!template.IsCompatibleWith(editingRecipeModules)) { - imGui.BuildText("This module template seems incompatible with the recipe or the building", wrap: true); + imGui.BuildText("This module template seems incompatible with the recipe or the building", TextBlockDisplayStyle.WrappedText); } using var grid = imGui.EnterInlineGrid(3f, 1f); @@ -615,7 +615,7 @@ private void ShowModuleDropDown(ImGui gui, RecipeRow recipe) { } if (moduleTemplateList.data.Count > 0) { - dropGui.BuildText("Use module template:", wrap: true, font: Font.subheader); + dropGui.BuildText("Use module template:", Font.subheader); moduleTemplateList.Build(dropGui); } if (dropGui.BuildButton("Configure module templates") && dropGui.CloseDropdown()) { @@ -784,27 +784,27 @@ void dropDownContent(ImGui gui) { if (link != null) { if (!link.flags.HasFlags(ProductionLink.Flags.HasProduction)) { - gui.BuildText("This link has no production (Link ignored)", wrap: true, color: SchemeColor.Error); + gui.BuildText("This link has no production (Link ignored)", TextBlockDisplayStyle.ErrorText); } if (!link.flags.HasFlags(ProductionLink.Flags.HasConsumption)) { - gui.BuildText("This link has no consumption (Link ignored)", wrap: true, color: SchemeColor.Error); + gui.BuildText("This link has no consumption (Link ignored)", TextBlockDisplayStyle.ErrorText); } if (link.flags.HasFlags(ProductionLink.Flags.ChildNotMatched)) { - gui.BuildText("Nested table link have unmatched production/consumption. These unmatched products are not captured by this link.", wrap: true, color: SchemeColor.Error); + gui.BuildText("Nested table link have unmatched production/consumption. These unmatched products are not captured by this link.", TextBlockDisplayStyle.ErrorText); } if (!link.flags.HasFlags(ProductionLink.Flags.HasProductionAndConsumption) && link.owner.owner is RecipeRow recipeRow && recipeRow.FindLink(link.goods, out _)) { - gui.BuildText("Nested tables have their own set of links that DON'T connect to parent links. To connect this product to the outside, remove this link", wrap: true, color: SchemeColor.Error); + gui.BuildText("Nested tables have their own set of links that DON'T connect to parent links. To connect this product to the outside, remove this link", TextBlockDisplayStyle.ErrorText); } if (link.flags.HasFlags(ProductionLink.Flags.LinkRecursiveNotMatched)) { if (link.notMatchedFlow <= 0f) { - gui.BuildText("YAFC was unable to satisfy this link (Negative feedback loop). This doesn't mean that this link is the problem, but it is part of the loop.", wrap: true, color: SchemeColor.Error); + gui.BuildText("YAFC was unable to satisfy this link (Negative feedback loop). This doesn't mean that this link is the problem, but it is part of the loop.", TextBlockDisplayStyle.ErrorText); } else { - gui.BuildText("YAFC was unable to satisfy this link (Overproduction). You can allow overproduction for this link to solve the error.", wrap: true, color: SchemeColor.Error); + gui.BuildText("YAFC was unable to satisfy this link (Overproduction). You can allow overproduction for this link to solve the error.", TextBlockDisplayStyle.ErrorText); } } } @@ -853,7 +853,7 @@ void dropDownContent(ImGui gui) { } if (numberOfShownRecipes > 1) { - gui.BuildText("Hint: ctrl+click to add multiple", wrap: true, color: SchemeColor.BackgroundTextFaint); + gui.BuildText("Hint: ctrl+click to add multiple", TextBlockDisplayStyle.HintText); } if (link != null && gui.BuildCheckBox("Allow overproduction", link.algorithm == LinkAlgorithm.AllowOverProduction, out bool newValue)) { @@ -866,10 +866,10 @@ void dropDownContent(ImGui gui) { if (link != null && link.owner == context) { if (link.amount != 0) { - gui.BuildText(goods.locName + " is a desired product and cannot be unlinked.", wrap: true); + gui.BuildText(goods.locName + " is a desired product and cannot be unlinked.", TextBlockDisplayStyle.WrappedText); } else { - gui.BuildText(goods.locName + " production is currently linked. This means that YAFC will try to match production with consumption.", wrap: true); + gui.BuildText(goods.locName + " production is currently linked. This means that YAFC will try to match production with consumption.", TextBlockDisplayStyle.WrappedText); } if (type == ProductDropdownType.DesiredProduct) { @@ -887,10 +887,10 @@ void dropDownContent(ImGui gui) { } else if (goods != null) { if (link != null) { - gui.BuildText(goods.locName + " production is currently linked, but the link is outside this nested table. Nested tables can have its own separate set of links", wrap: true); + gui.BuildText(goods.locName + " production is currently linked, but the link is outside this nested table. Nested tables can have its own separate set of links", TextBlockDisplayStyle.WrappedText); } else { - gui.BuildText(goods.locName + " production is currently NOT linked. This means that YAFC will make no attempt to match production with consumption.", wrap: true); + gui.BuildText(goods.locName + " production is currently NOT linked. This means that YAFC will make no attempt to match production with consumption.", TextBlockDisplayStyle.WrappedText); } if (gui.BuildButton("Create link").WithTooltip(gui, "Shortcut: right-click") && gui.CloseDropdown()) { @@ -981,7 +981,7 @@ private void BuildGoodsIcon(ImGui gui, Goods? goods, ProductionLink? link, float textColor = SchemeColor.BackgroundTextFaint; } - switch (gui.BuildFactorioObjectWithAmount(goods, new(amount, goods?.flowUnitOfMeasure ?? UnitOfMeasure.None), iconColor, textColor, tooltipOptions: tooltipOptions)) { + switch (gui.BuildFactorioObjectWithAmount(goods, new(amount, goods?.flowUnitOfMeasure ?? UnitOfMeasure.None), iconColor, TextBlockDisplayStyle.Centered with { Color = textColor }, tooltipOptions: tooltipOptions)) { case Click.Left when goods is not null: OpenProductDropdown(gui, gui.lastRect, goods, amount, link, dropdownType, recipe, context, variants); break; diff --git a/Yafc/Workspace/SummaryView.cs b/Yafc/Workspace/SummaryView.cs index d67d8a1b..b9e19672 100644 --- a/Yafc/Workspace/SummaryView.cs +++ b/Yafc/Workspace/SummaryView.cs @@ -203,7 +203,7 @@ protected override void BuildHeader(ImGui gui) { base.BuildHeader(gui); gui.allocator = RectAllocator.Center; - gui.BuildText("Production Sheet Summary", Font.header, false, RectAlignment.Middle); + gui.BuildText("Production Sheet Summary", new TextBlockDisplayStyle(Font.header, Alignment: RectAlignment.Middle)); gui.allocator = RectAllocator.LeftAlign; } From 9e4216cff999571d466adb27635b8bb6603062a0 Mon Sep 17 00:00:00 2001 From: Dale McCoy <21223975+DaleStan@users.noreply.github.com> Date: Wed, 7 Aug 2024 20:31:02 -0400 Subject: [PATCH 5/6] Add DisplayStyles for text input boxes. --- Yafc.UI/ImGui/ImGuiBuilding.cs | 11 ++++++---- Yafc.UI/ImGui/ImGuiTextInputHelper.cs | 22 +++++++++---------- Yafc.UI/ImGui/TextDisplayStyles.cs | 22 +++++++++++++++++++ Yafc/Widgets/ImmediateWidgets.cs | 11 ++++------ Yafc/Windows/FilesystemScreen.cs | 2 +- Yafc/Windows/PreferencesScreen.cs | 6 ++--- .../ModuleFillerParametersScreen.cs | 8 +++---- .../ProductionTable/ProductionTableView.cs | 7 +++--- 8 files changed, 55 insertions(+), 34 deletions(-) diff --git a/Yafc.UI/ImGui/ImGuiBuilding.cs b/Yafc.UI/ImGui/ImGuiBuilding.cs index b6f4c8b8..9d9886b1 100644 --- a/Yafc.UI/ImGui/ImGuiBuilding.cs +++ b/Yafc.UI/ImGui/ImGuiBuilding.cs @@ -148,14 +148,17 @@ public void DrawText(Rect rect, string text, RectAlignment alignment = RectAlign private ImGuiTextInputHelper? textInputHelper; public bool BuildTextInput(string? text, out string newText, string? placeholder, Icon icon = Icon.None, bool delayed = false, bool setInitialFocus = false) { - Padding padding = new Padding(icon == Icon.None ? 0.8f : 0.5f, 0.5f); - return BuildTextInput(text, out newText, placeholder, icon, delayed, padding, setInitialFocus: setInitialFocus); + TextBoxDisplayStyle displayStyle = TextBoxDisplayStyle.DefaultTextInput; + if (icon != Icon.None) { + displayStyle = displayStyle with { Icon = icon }; + } + return BuildTextInput(text, out newText, placeholder, displayStyle, delayed, setInitialFocus); } - public bool BuildTextInput(string? text, out string newText, string? placeholder, Icon icon, bool delayed, Padding padding, RectAlignment alignment = RectAlignment.MiddleLeft, SchemeColorGroup color = SchemeColorGroup.Grey, bool setInitialFocus = false) { + public bool BuildTextInput(string? text, out string newText, string? placeholder, TextBoxDisplayStyle displayStyle, bool delayed, bool setInitialFocus = false) { setInitialFocus &= textInputHelper == null; textInputHelper ??= new ImGuiTextInputHelper(this); - bool result = textInputHelper.BuildTextInput(text, out newText, placeholder, GetFontSize(), delayed, icon, padding, alignment, color); + bool result = textInputHelper.BuildTextInput(text, out newText, placeholder, GetFontSize(), delayed, displayStyle); if (setInitialFocus) { SetTextInputFocus(lastRect, ""); } diff --git a/Yafc.UI/ImGui/ImGuiTextInputHelper.cs b/Yafc.UI/ImGui/ImGuiTextInputHelper.cs index 22820fb1..37bae168 100644 --- a/Yafc.UI/ImGui/ImGuiTextInputHelper.cs +++ b/Yafc.UI/ImGui/ImGuiTextInputHelper.cs @@ -55,13 +55,13 @@ private void GetTextParameters(string? textToBuild, Rect textRect, FontFile.Font } } - public bool BuildTextInput(string? text, out string newText, string? placeholder, FontFile.FontSize fontSize, bool delayed, Icon icon, Padding padding, RectAlignment alignment, SchemeColorGroup color) { + public bool BuildTextInput(string? text, out string newText, string? placeholder, FontFile.FontSize fontSize, bool delayed, TextBoxDisplayStyle displayStyle) { newText = text ?? ""; Rect textRect, realTextRect; - using (gui.EnterGroup(padding, RectAllocator.LeftRow)) { + using (gui.EnterGroup(displayStyle.Padding, RectAllocator.LeftRow)) { float lineSize = gui.PixelsToUnits(fontSize.lineSize); - if (icon != Icon.None) { - gui.BuildIcon(icon, lineSize, (SchemeColor)color + 3); + if (displayStyle.Icon != Icon.None) { + gui.BuildIcon(displayStyle.Icon, lineSize, (SchemeColor)displayStyle.ColorGroup + 3); } textRect = gui.RemainingRow(0.3f).AllocateRect(0, lineSize, RectAlignment.MiddleFullRow); @@ -81,32 +81,32 @@ public bool BuildTextInput(string? text, out string newText, string? placeholder if (gui.ConsumeMouseDown(boundingRect)) { SetFocus(boundingRect, text ?? ""); - GetTextParameters(this.text, textRect, fontSize, alignment, out _, out _, out _, out realTextRect); + GetTextParameters(this.text, textRect, fontSize, displayStyle.Alignment, out _, out _, out _, out realTextRect); SetCaret(FindCaretIndex(text, gui.mousePosition.X - realTextRect.X, fontSize, textRect.Width)); } break; case ImGuiAction.MouseMove: if (focused && gui.actionParameter == SDL.SDL_BUTTON_LEFT) { - GetTextParameters(this.text, textRect, fontSize, alignment, out _, out _, out _, out realTextRect); + GetTextParameters(this.text, textRect, fontSize, displayStyle.Alignment, out _, out _, out _, out realTextRect); SetCaret(caret, FindCaretIndex(this.text, gui.mousePosition.X - realTextRect.X, fontSize, textRect.Width)); } _ = gui.ConsumeMouseOver(boundingRect, RenderingUtils.cursorCaret, false); break; case ImGuiAction.Build: - SchemeColor textColor = (SchemeColor)color + 2; + SchemeColor textColor = (SchemeColor)displayStyle.ColorGroup + 2; string? textToBuild; if (focused && !string.IsNullOrEmpty(text)) { textToBuild = this.text; } else if (string.IsNullOrEmpty(text)) { textToBuild = placeholder; - textColor = (SchemeColor)color + 3; + textColor = (SchemeColor)displayStyle.ColorGroup + 3; } else { textToBuild = text; } - GetTextParameters(textToBuild, textRect, fontSize, alignment, out var cachedText, out float scale, out float textWidth, out realTextRect); + GetTextParameters(textToBuild, textRect, fontSize, displayStyle.Alignment, out TextCache? cachedText, out float scale, out float textWidth, out realTextRect); if (cachedText != null) { gui.DrawRenderable(realTextRect, cachedText, textColor); } @@ -125,11 +125,11 @@ public bool BuildTextInput(string? text, out string newText, string? placeholder gui.SetNextRebuild(nextCaretTimer); if (caretVisible) { float caretPosition = GetCharacterPosition(caret, fontSize, textWidth) * scale; - gui.DrawRectangle(new Rect(caretPosition + realTextRect.X - 0.05f, realTextRect.Y, 0.1f, realTextRect.Height), (SchemeColor)color + 2); + gui.DrawRectangle(new Rect(caretPosition + realTextRect.X - 0.05f, realTextRect.Y, 0.1f, realTextRect.Height), (SchemeColor)displayStyle.ColorGroup + 2); } } } - gui.DrawRectangle(boundingRect, (SchemeColor)color); + gui.DrawRectangle(boundingRect, (SchemeColor)displayStyle.ColorGroup); break; } diff --git a/Yafc.UI/ImGui/TextDisplayStyles.cs b/Yafc.UI/ImGui/TextDisplayStyles.cs index e81b4027..56f47051 100644 --- a/Yafc.UI/ImGui/TextDisplayStyles.cs +++ b/Yafc.UI/ImGui/TextDisplayStyles.cs @@ -35,3 +35,25 @@ public record TextBlockDisplayStyle(Font? Font = null, bool WrapText = false, Re /// public static implicit operator TextBlockDisplayStyle(Font font) => new(font); } + +/// +/// Contains the display parameters for editable text (TextBox in both WPF and WinForms) +/// +/// The to display to the left of the text, or to display no icon. +/// The to place between the text and the edges of the editable area. (The box area not used by .) +/// The to apply when drawing the text within the edit box. +/// The to use when drawing the edit box. +public record TextBoxDisplayStyle(Icon Icon, Padding Padding, RectAlignment Alignment, SchemeColorGroup ColorGroup) { + /// + /// Gets the default display style, used for the Preferences screen and calls to . + /// + public static TextBoxDisplayStyle DefaultTextInput { get; } = new(Icon.None, new Padding(.5f), RectAlignment.MiddleLeft, SchemeColorGroup.Grey); + /// + /// Gets the display style for input boxes on the Module Filler Parameters screen. + /// + public static TextBoxDisplayStyle ModuleParametersTextInput { get; } = new(Icon.None, new Padding(.5f, 0), RectAlignment.MiddleLeft, SchemeColorGroup.Grey); + /// + /// Gets the display style for amounts associated with Factorio objects. ( { ColorGroup = } for built building counts.) + /// + public static TextBoxDisplayStyle FactorioObjectInput { get; } = new(Icon.None, default, RectAlignment.Middle, SchemeColorGroup.Secondary); +} diff --git a/Yafc/Widgets/ImmediateWidgets.cs b/Yafc/Widgets/ImmediateWidgets.cs index 64822ba1..54217134 100644 --- a/Yafc/Widgets/ImmediateWidgets.cs +++ b/Yafc/Widgets/ImmediateWidgets.cs @@ -60,8 +60,8 @@ public static void BuildFactorioObjectIcon(this ImGui gui, FactorioObject? obj, } } - public static bool BuildFloatInput(this ImGui gui, DisplayAmount amount, Padding padding, bool setInitialFocus = false) { - if (gui.BuildTextInput(DataUtils.FormatAmount(amount.Value, amount.Unit), out string newText, null, Icon.None, true, padding, setInitialFocus: setInitialFocus) + public static bool BuildFloatInput(this ImGui gui, DisplayAmount amount, TextBoxDisplayStyle displayStyle, bool setInitialFocus = false) { + if (gui.BuildTextInput(DataUtils.FormatAmount(amount.Value, amount.Unit), out string newText, null, displayStyle, true, setInitialFocus) && DataUtils.TryParseAmount(newText, out float newValue, amount.Unit)) { amount.Value = newValue; return true; @@ -270,11 +270,8 @@ public static GoodsWithAmountEvent BuildFactorioObjectWithEditableAmount(this Im group.SetWidth(3f); GoodsWithAmountEvent evt = (GoodsWithAmountEvent)gui.BuildFactorioObjectButton(obj, 3f, MilestoneDisplay.Contained, color, useScale, tooltipOptions); - if (gui.BuildTextInput(DataUtils.FormatAmount(amount.Value, amount.Unit), out string newText, null, Icon.None, true, default, RectAlignment.Middle, SchemeColorGroup.Secondary)) { - if (DataUtils.TryParseAmount(newText, out float newAmount, amount.Unit)) { - amount.Value = newAmount; - return GoodsWithAmountEvent.TextEditing; - } + if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.FactorioObjectInput)) { + return GoodsWithAmountEvent.TextEditing; } if (allowScroll && gui.action == ImGuiAction.MouseScroll && gui.ConsumeEvent(gui.lastRect)) { diff --git a/Yafc/Windows/FilesystemScreen.cs b/Yafc/Windows/FilesystemScreen.cs index fb15d82c..5cc47bdf 100644 --- a/Yafc/Windows/FilesystemScreen.cs +++ b/Yafc/Windows/FilesystemScreen.cs @@ -147,7 +147,7 @@ private void BuildElement(ImGui gui, (EntryType type, string location) element, using (gui.EnterGroup(default, RectAllocator.LeftRow)) { gui.BuildIcon(icon); if (element.type == EntryType.CreateDirectory) { - if (gui.BuildTextInput("", out string dirName, elementText, Icon.None, true, new Padding(0.2f, 0.2f))) { + if (gui.BuildTextInput("", out string dirName, elementText, TextBoxDisplayStyle.DefaultTextInput with { Padding = new Padding(0.2f) }, true)) { if (!string.IsNullOrWhiteSpace(dirName) && dirName.IndexOfAny(Path.GetInvalidFileNameChars()) == -1) { string dirPath = Path.Combine(location, dirName); _ = Directory.CreateDirectory(dirPath); diff --git a/Yafc/Windows/PreferencesScreen.cs b/Yafc/Windows/PreferencesScreen.cs index cbac3b37..1c1a4382 100644 --- a/Yafc/Windows/PreferencesScreen.cs +++ b/Yafc/Windows/PreferencesScreen.cs @@ -41,7 +41,7 @@ public override void Build(ImGui gui) { using (gui.EnterRowWithHelpIcon("0 for off, 100% for old default")) { gui.BuildText("Pollution cost modifier", topOffset: 0.5f); DisplayAmount amount = new(settings.PollutionCostModifier, UnitOfMeasure.Percent); - if (gui.BuildFloatInput(amount, new Padding(0.5f)) && amount.Value >= 0) { + if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.DefaultTextInput) && amount.Value >= 0) { settings.RecordUndo().PollutionCostModifier = amount.Value; gui.Rebuild(); } @@ -50,7 +50,7 @@ public override void Build(ImGui gui) { using (gui.EnterRowWithHelpIcon("Some mod icons have little or no transparency, hiding the background color. This setting reduces the size of icons that could hide link information.")) { gui.BuildText("Display scale for linkable icons", topOffset: 0.5f); DisplayAmount amount = new(prefs.iconScale, UnitOfMeasure.Percent); - if (gui.BuildFloatInput(amount, new Padding(0.5f)) && amount.Value > 0 && amount.Value <= 1) { + if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.DefaultTextInput) && amount.Value > 0 && amount.Value <= 1) { prefs.RecordUndo().iconScale = amount.Value; gui.Rebuild(); } @@ -153,7 +153,7 @@ private void BuildUnitPerTime(ImGui gui, bool fluid, ProjectPreferences preferen } } gui.BuildText("per second"); - _ = gui.BuildFloatInput(unit, new Padding(.5f)); + _ = gui.BuildFloatInput(unit, TextBoxDisplayStyle.DefaultTextInput); } gui.AllocateSpacing(1f); diff --git a/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs b/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs index 65b28900..7d1fa506 100644 --- a/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs +++ b/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs @@ -123,7 +123,7 @@ public override void Build(ImGui gui) { using (gui.EnterRow()) { gui.BuildText("Beacons per building: "); DisplayAmount amount = modules.beaconsPerBuilding; - if (gui.BuildFloatInput(amount, new Padding(0.5f, 0f)) && (int)amount.Value > 0) { + if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.ModuleParametersTextInput) && (int)amount.Value > 0) { modules.RecordUndo().beaconsPerBuilding = (int)amount.Value; } } @@ -190,21 +190,21 @@ public override void Build(ImGui gui) { using (gui.EnterRow()) { gui.BuildText("Mining productivity bonus (project-wide setting): "); DisplayAmount amount = new(Project.current.settings.miningProductivity, UnitOfMeasure.Percent); - if (gui.BuildFloatInput(amount, new Padding(.5f, 0)) && amount.Value >= 0) { + if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.ModuleParametersTextInput) && amount.Value >= 0) { Project.current.settings.RecordUndo().miningProductivity = amount.Value; } } using (gui.EnterRow()) { gui.BuildText("Research speed bonus (project-wide setting): "); DisplayAmount amount = new(Project.current.settings.researchSpeedBonus, UnitOfMeasure.Percent); - if (gui.BuildFloatInput(amount, new Padding(.5f, 0)) && amount.Value >= 0) { + if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.ModuleParametersTextInput) && amount.Value >= 0) { Project.current.settings.RecordUndo().researchSpeedBonus = amount.Value; } } using (gui.EnterRow()) { gui.BuildText("Research productivity bonus (project-wide setting): "); DisplayAmount amount = new(Project.current.settings.researchProductivity, UnitOfMeasure.Percent); - if (gui.BuildFloatInput(amount, new Padding(.5f, 0)) && amount.Value >= 0) { + if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.ModuleParametersTextInput) && amount.Value >= 0) { Project.current.settings.RecordUndo().researchProductivity = amount.Value; } } diff --git a/Yafc/Workspace/ProductionTable/ProductionTableView.cs b/Yafc/Workspace/ProductionTable/ProductionTableView.cs index 44314a99..93e78739 100644 --- a/Yafc/Workspace/ProductionTable/ProductionTableView.cs +++ b/Yafc/Workspace/ProductionTable/ProductionTableView.cs @@ -294,10 +294,9 @@ public override void BuildElement(ImGui gui, RecipeRow recipe) { } if (recipe.builtBuildings != null) { - if (gui.BuildTextInput(DataUtils.FormatAmount(Convert.ToSingle(recipe.builtBuildings), UnitOfMeasure.None), out string newText, null, Icon.None, true, default, RectAlignment.Middle, SchemeColorGroup.Grey)) { - if (DataUtils.TryParseAmount(newText, out float newAmount, UnitOfMeasure.None)) { - recipe.RecordUndo().builtBuildings = Convert.ToInt32(newAmount); - } + DisplayAmount amount = recipe.builtBuildings.Value; + if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.FactorioObjectInput with { ColorGroup = SchemeColorGroup.Grey }) && amount.Value >= 0) { + recipe.RecordUndo().builtBuildings = (int)amount.Value; } } } From 412f62c9aad6d87a0047def1037e77aa03d43ea5 Mon Sep 17 00:00:00 2001 From: Dale McCoy <21223975+DaleStan@users.noreply.github.com> Date: Fri, 2 Aug 2024 17:31:50 -0400 Subject: [PATCH 6/6] Add IconDisplayStyles and ButtonDisplayStyles for FactorioObjectIcons and Buttons. --- Yafc/Utils/ObjectDisplayStyles.cs | 62 +++++++++++++++ Yafc/Widgets/ImmediateWidgets.cs | 79 +++++++++++++------ Yafc/Widgets/ObjectTooltip.cs | 2 +- Yafc/Windows/DependencyExplorer.cs | 2 +- Yafc/Windows/MilestonesEditor.cs | 2 +- Yafc/Windows/MilestonesPanel.cs | 2 +- Yafc/Windows/NeverEnoughItemsPanel.cs | 18 ++--- Yafc/Windows/ProjectPageSettingsPanel.cs | 2 +- Yafc/Windows/SelectMultiObjectPanel.cs | 3 +- Yafc/Windows/SelectSingleObjectPanel.cs | 2 +- Yafc/Windows/ShoppingListScreen.cs | 4 +- Yafc/Workspace/AutoPlannerView.cs | 6 +- .../ProductionSummaryView.cs | 6 +- .../ModuleCustomizationScreen.cs | 6 +- .../ModuleFillerParametersScreen.cs | 4 +- .../ProductionTable/ProductionTableView.cs | 30 +++---- Yafc/Workspace/SummaryView.cs | 4 +- changelog.txt | 3 + 18 files changed, 166 insertions(+), 71 deletions(-) create mode 100644 Yafc/Utils/ObjectDisplayStyles.cs diff --git a/Yafc/Utils/ObjectDisplayStyles.cs b/Yafc/Utils/ObjectDisplayStyles.cs new file mode 100644 index 00000000..472d22bb --- /dev/null +++ b/Yafc/Utils/ObjectDisplayStyles.cs @@ -0,0 +1,62 @@ +namespace Yafc.UI; + +/// +/// Contains the display parameters for FactorioObjectIcons. +/// +/// The icon size. The production tables use size 3. +/// The option to use when drawing the icon. +/// Whether or not to obey the setting. +public record IconDisplayStyle(float Size, MilestoneDisplay MilestoneDisplay, bool UseScaleSetting) { + /// + /// Gets the default icon style: Size 2, , and not scaled. + /// + public static IconDisplayStyle Default { get; } = new(2, MilestoneDisplay.Normal, false); +} + +/// +/// Contains the display parameters for FactorioObjectButtons. Buttons with a background color draw a scaled icon +/// ( = ) by default. +/// +/// The icon size. The production tables use size 3. +/// The option to use when drawing the icon. +/// The background color to display behind the icon. +public record ButtonDisplayStyle(float Size, MilestoneDisplay MilestoneDisplay, SchemeColor BackgroundColor) : IconDisplayStyle(Size, MilestoneDisplay, true) { + /// + /// Creates a new for buttons that do not have a background color. These buttons will not obey the setting. + /// + /// The icon size. The production tables use size 3. + /// The option to use when drawing the icon. + public ButtonDisplayStyle(float size, MilestoneDisplay milestoneDisplay) : this(size, milestoneDisplay, SchemeColor.None) => UseScaleSetting = false; + + /// + /// Gets the default button style: Size 2, , no background, and not scaled. + /// + public static new ButtonDisplayStyle Default { get; } = new(2, MilestoneDisplay.Normal); + /// + /// Gets the button style for the s: Size 2.5, , and scaled. + /// + /// The background color to use for this button. + public static ButtonDisplayStyle SelectObjectPanel(SchemeColor backgroundColor) => new(2.5f, MilestoneDisplay.Contained, backgroundColor); + /// + /// Gets the button style for production table buttons with a background: Size 2.5, , and scaled. + /// + /// The background color to use for this button. + public static ButtonDisplayStyle ProductionTableScaled(SchemeColor backgroundColor) => new(3, MilestoneDisplay.Contained, backgroundColor); + /// + /// Gets the button style for production table buttons with no background: Size 2.5, , and not scaled. + /// + public static ButtonDisplayStyle ProductionTableUnscaled { get; } = new(3, MilestoneDisplay.Contained); + /// + /// Gets the button style for small buttons in the Never Enough Items Explorer: Size 3, , and not scaled. + /// + public static ButtonDisplayStyle NeieSmall { get; } = new(3, MilestoneDisplay.Contained); + /// + /// Gets the button style for large buttons in the Never Enough Items Explorer: Size 4, , and not scaled. + /// + public static ButtonDisplayStyle NeieLarge { get; } = new(4, MilestoneDisplay.Contained); + /// + /// Gets the button style for the Milestones display buttons: Size 3, , and scaled. + /// + /// The background color to use for this button. + public static ButtonDisplayStyle Milestone(SchemeColor backgroundColor) => new(3, MilestoneDisplay.None, backgroundColor); +} diff --git a/Yafc/Widgets/ImmediateWidgets.cs b/Yafc/Widgets/ImmediateWidgets.cs index 54217134..2e100eb3 100644 --- a/Yafc/Widgets/ImmediateWidgets.cs +++ b/Yafc/Widgets/ImmediateWidgets.cs @@ -8,11 +8,40 @@ using Yafc.UI; namespace Yafc { + + // Contained draws the milestone like this + // +----+ + // | | + // | +-+ + // | | | + // +--+-+ + // Normal draws the milestone like this + // +----+ + // | | + // | | + // | +-+ + // +---| | + // +-+ public enum MilestoneDisplay { + /// + /// Draw the highest locked milestone centered on the lower-right corner of the base icon. + /// Normal, + /// + /// Draw the highest locked milestone with its lower-right corner aligned with the lower-right corner of the base icon. + /// Contained, - All, - AllContained, + /// + /// Draw the highest milestone, regardless of (un)lock state, centered on the lower-right corner of the base icon. + /// + Always, + /// + /// Draw the highest milestone, regardless of (un)lock state, with its lower-right corner aligned with the lower-right corner of the base icon. + /// + ContainedAlways, + /// + /// Do not draw a milestone icon. + /// None } @@ -32,26 +61,26 @@ public enum Click { public static class ImmediateWidgets { /// Draws the icon belonging to a , or an empty box as a placeholder if no object is available. /// Draw the icon for this object, or an empty box if this is . - /// If , this icon will be displayed at , instead of at 100% scale. - public static void BuildFactorioObjectIcon(this ImGui gui, FactorioObject? obj, MilestoneDisplay display = MilestoneDisplay.Normal, float size = 2f, bool useScale = false) { + public static void BuildFactorioObjectIcon(this ImGui gui, FactorioObject? obj, IconDisplayStyle? displayStyle = null) { + displayStyle ??= IconDisplayStyle.Default; if (obj == null) { - gui.BuildIcon(Icon.Empty, size, SchemeColor.BackgroundTextFaint); + gui.BuildIcon(Icon.Empty, displayStyle.Size, SchemeColor.BackgroundTextFaint); return; } var color = obj.IsAccessible() ? SchemeColor.Source : SchemeColor.SourceFaint; - if (useScale) { - Rect rect = gui.AllocateRect(size, size, RectAlignment.Middle); - gui.DrawIcon(rect.Expand(size * (Project.current.preferences.iconScale - 1) / 2), obj.icon, color); + if (displayStyle.UseScaleSetting) { + Rect rect = gui.AllocateRect(displayStyle.Size, displayStyle.Size, RectAlignment.Middle); + gui.DrawIcon(rect.Expand(displayStyle.Size * (Project.current.preferences.iconScale - 1) / 2), obj.icon, color); } else { - gui.BuildIcon(obj.icon, size, color); + gui.BuildIcon(obj.icon, displayStyle.Size, color); } - if (gui.isBuilding && display != MilestoneDisplay.None) { - bool contain = (display & MilestoneDisplay.Contained) != 0; - var milestone = Milestones.Instance.GetHighest(obj, display >= MilestoneDisplay.All); + if (gui.isBuilding && displayStyle.MilestoneDisplay != MilestoneDisplay.None) { + bool contain = (displayStyle.MilestoneDisplay & MilestoneDisplay.Contained) != 0; + FactorioObject? milestone = Milestones.Instance.GetHighest(obj, displayStyle.MilestoneDisplay >= MilestoneDisplay.Always); if (milestone != null) { - Vector2 psize = new Vector2(size / 2f); + Vector2 psize = new Vector2(displayStyle.Size / 2f); var delta = contain ? psize : psize / 2f; Rect milestoneIcon = new Rect(gui.lastRect.BottomRight - delta, psize); var icon = milestone == Database.voidEnergy ? DataUtils.HandIcon : milestone.icon; @@ -70,7 +99,7 @@ public static bool BuildFloatInput(this ImGui gui, DisplayAmount amount, TextBox return false; } - public static Click BuildFactorioObjectButton(this ImGui gui, Rect rect, FactorioObject? obj, SchemeColor bgColor = SchemeColor.None, ObjectTooltipOptions tooltipOptions = default) { + public static Click BuildFactorioObjectButtonBackground(this ImGui gui, Rect rect, FactorioObject? obj, SchemeColor bgColor = SchemeColor.None, ObjectTooltipOptions tooltipOptions = default) { SchemeColor overColor; if (bgColor == SchemeColor.None) { overColor = SchemeColor.Grey; @@ -109,15 +138,15 @@ public static Click BuildFactorioObjectButton(this ImGui gui, Rect rect, Factori /// Draws a button displaying the icon belonging to a , or an empty box as a placeholder if no object is available. /// Draw the icon for this object, or an empty box if this is . - /// If , this icon will be displayed at , instead of at 100% scale. - public static Click BuildFactorioObjectButton(this ImGui gui, FactorioObject? obj, float size = 2f, MilestoneDisplay display = MilestoneDisplay.Normal, SchemeColor bgColor = SchemeColor.None, bool useScale = false, ObjectTooltipOptions tooltipOptions = default) { - gui.BuildFactorioObjectIcon(obj, display, size, useScale); - return gui.BuildFactorioObjectButton(gui.lastRect, obj, bgColor, tooltipOptions); + public static Click BuildFactorioObjectButton(this ImGui gui, FactorioObject? obj, ButtonDisplayStyle displayStyle, ObjectTooltipOptions tooltipOptions = default) { + gui.BuildFactorioObjectIcon(obj, displayStyle); + return gui.BuildFactorioObjectButtonBackground(gui.lastRect, obj, displayStyle.BackgroundColor, tooltipOptions); } - public static Click BuildFactorioObjectButtonWithText(this ImGui gui, FactorioObject? obj, string? extraText = null, float size = 2f, MilestoneDisplay display = MilestoneDisplay.Normal) { + public static Click BuildFactorioObjectButtonWithText(this ImGui gui, FactorioObject? obj, string? extraText = null, IconDisplayStyle? iconDisplayStyle = null) { + iconDisplayStyle ??= IconDisplayStyle.Default; using (gui.EnterRow()) { - gui.BuildFactorioObjectIcon(obj, display, size); + gui.BuildFactorioObjectIcon(obj, iconDisplayStyle); var color = gui.textColor; if (obj != null && !obj.IsAccessible()) { color += 1; @@ -136,7 +165,7 @@ public static Click BuildFactorioObjectButtonWithText(this ImGui gui, FactorioOb gui.BuildText(obj == null ? "None" : obj.locName, TextBlockDisplayStyle.WrappedText with { Color = color }); } - return gui.BuildFactorioObjectButton(gui.lastRect, obj); + return gui.BuildFactorioObjectButtonBackground(gui.lastRect, obj); } public static bool BuildInlineObjectList(this ImGui gui, IEnumerable list, IComparer ordering, string header, [NotNullWhen(true)] out T? selected, int maxCount = 10, @@ -205,12 +234,12 @@ public static void BuildInlineObjectListAndButtonWithNone(this ImGui gui, ICo /// Draw the icon for this object, or an empty box if this is . /// Display this value and unit. /// If , this icon will be displayed at , instead of at 100% scale. - public static Click BuildFactorioObjectWithAmount(this ImGui gui, FactorioObject? goods, DisplayAmount amount, SchemeColor bgColor = SchemeColor.None, TextBlockDisplayStyle? textDisplayStyle = null, bool useScale = true, ObjectTooltipOptions tooltipOptions = default) { + public static Click BuildFactorioObjectWithAmount(this ImGui gui, FactorioObject? goods, DisplayAmount amount, ButtonDisplayStyle buttonDisplayStyle, TextBlockDisplayStyle? textDisplayStyle = null, ObjectTooltipOptions tooltipOptions = default) { textDisplayStyle ??= new(Alignment: RectAlignment.Middle); using (gui.EnterFixedPositioning(3f, 3f, default)) { gui.allocator = RectAllocator.Stretch; gui.spacing = 0f; - Click clicked = gui.BuildFactorioObjectButton(goods, 3f, MilestoneDisplay.Contained, bgColor, useScale, tooltipOptions); + Click clicked = gui.BuildFactorioObjectButton(goods, buttonDisplayStyle, tooltipOptions); if (goods != null) { gui.BuildText(DataUtils.FormatAmount(amount.Value, amount.Unit), textDisplayStyle); if (InputSystem.Instance.control && gui.BuildButton(gui.lastRect, SchemeColor.None, SchemeColor.Grey) == ButtonEvent.MouseOver) { @@ -265,10 +294,10 @@ public static void BuildObjectSelectDropDownWithNone(this ImGui gui, ICollect /// Display this value and unit. If the user edits the value, the new value will be stored in before returning. /// If , the default, the user can adjust the value by using the scroll wheel while hovering over the editable text. /// If , the scroll wheel will be ignored when hovering. - public static GoodsWithAmountEvent BuildFactorioObjectWithEditableAmount(this ImGui gui, FactorioObject? obj, DisplayAmount amount, SchemeColor color = SchemeColor.None, bool useScale = true, bool allowScroll = true, ObjectTooltipOptions tooltipOptions = default) { + public static GoodsWithAmountEvent BuildFactorioObjectWithEditableAmount(this ImGui gui, FactorioObject? obj, DisplayAmount amount, ButtonDisplayStyle buttonDisplayStyle, bool allowScroll = true, ObjectTooltipOptions tooltipOptions = default) { using var group = gui.EnterGroup(default, RectAllocator.Stretch, spacing: 0f); group.SetWidth(3f); - GoodsWithAmountEvent evt = (GoodsWithAmountEvent)gui.BuildFactorioObjectButton(obj, 3f, MilestoneDisplay.Contained, color, useScale, tooltipOptions); + GoodsWithAmountEvent evt = (GoodsWithAmountEvent)gui.BuildFactorioObjectButton(obj, buttonDisplayStyle, tooltipOptions); if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.FactorioObjectInput)) { return GoodsWithAmountEvent.TextEditing; diff --git a/Yafc/Widgets/ObjectTooltip.cs b/Yafc/Widgets/ObjectTooltip.cs index dc0bf8a3..8049ae1c 100644 --- a/Yafc/Widgets/ObjectTooltip.cs +++ b/Yafc/Widgets/ObjectTooltip.cs @@ -520,7 +520,7 @@ private void BuildTechnology(Technology technology, ImGui gui) { using var grid = gui.EnterInlineGrid(3f); foreach (var pack in packs) { grid.Next(); - _ = gui.BuildFactorioObjectWithAmount(pack.goods, pack.amount); + _ = gui.BuildFactorioObjectWithAmount(pack.goods, pack.amount, ButtonDisplayStyle.ProductionTableUnscaled); } } } diff --git a/Yafc/Windows/DependencyExplorer.cs b/Yafc/Windows/DependencyExplorer.cs index 37ca125f..1f637fe4 100644 --- a/Yafc/Windows/DependencyExplorer.cs +++ b/Yafc/Windows/DependencyExplorer.cs @@ -45,7 +45,7 @@ private void DrawFactorioObject(ImGui gui, FactorioId id) { string text = fobj.locName + " (" + fobj.type + ")"; gui.RemainingRow(0.5f).BuildText(text, TextBlockDisplayStyle.WrappedText with { Color = fobj.IsAccessible() ? SchemeColor.BackgroundText : SchemeColor.BackgroundTextFaint }); } - if (gui.BuildFactorioObjectButton(gui.lastRect, fobj, tooltipOptions: new() { ExtendHeader = true }) == Click.Left) { + if (gui.BuildFactorioObjectButtonBackground(gui.lastRect, fobj, tooltipOptions: new() { ExtendHeader = true }) == Click.Left) { Change(fobj); } } diff --git a/Yafc/Windows/MilestonesEditor.cs b/Yafc/Windows/MilestonesEditor.cs index f110dc6f..d1df4a4e 100644 --- a/Yafc/Windows/MilestonesEditor.cs +++ b/Yafc/Windows/MilestonesEditor.cs @@ -26,7 +26,7 @@ protected override void Close(bool save = true) { private void MilestoneDrawer(ImGui gui, FactorioObject element, int index) { using (gui.EnterRow()) { var settings = Project.current.settings; - gui.BuildFactorioObjectIcon(element, MilestoneDisplay.None, 3f); + gui.BuildFactorioObjectIcon(element, new IconDisplayStyle(3f, MilestoneDisplay.None, false)); gui.BuildText(element.locName, maxWidth: width - 16.6f); // Experimentally determined width of the non-text parts of the editor. if (gui.BuildButton(Icon.Close, size: 1f)) { _ = settings.RecordUndo().milestones.Remove(element); diff --git a/Yafc/Windows/MilestonesPanel.cs b/Yafc/Windows/MilestonesPanel.cs index 4fab8d03..31aef793 100644 --- a/Yafc/Windows/MilestonesPanel.cs +++ b/Yafc/Windows/MilestonesPanel.cs @@ -9,7 +9,7 @@ public class MilestonesWidget : VirtualScrollList { private static void MilestoneDrawer(ImGui gui, FactorioObject element, int index) { var settings = Project.current.settings; bool unlocked = settings.Flags(element).HasFlags(ProjectPerItemFlags.MilestoneUnlocked); - if (gui.BuildFactorioObjectButton(element, 3f, display: MilestoneDisplay.None, bgColor: unlocked ? SchemeColor.Primary : SchemeColor.None) == Click.Left) { + if (gui.BuildFactorioObjectButton(element, ButtonDisplayStyle.Milestone(unlocked ? SchemeColor.Primary : SchemeColor.None)) == Click.Left) { if (!unlocked) { var massUnlock = Milestones.Instance.GetMilestoneResult(element); int subIndex = 0; diff --git a/Yafc/Windows/NeverEnoughItemsPanel.cs b/Yafc/Windows/NeverEnoughItemsPanel.cs index af0355e8..273d1510 100644 --- a/Yafc/Windows/NeverEnoughItemsPanel.cs +++ b/Yafc/Windows/NeverEnoughItemsPanel.cs @@ -118,7 +118,7 @@ private void DrawIngredients(ImGui gui, Recipe recipe) { return; } foreach (var ingredient in recipe.ingredients) { - if (gui.BuildFactorioObjectWithAmount(ingredient.goods, ingredient.amount) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(ingredient.goods, ingredient.amount, ButtonDisplayStyle.NeieSmall) == Click.Left) { if (ingredient.variants != null) { gui.ShowDropDown(imGui => imGui.BuildInlineObjectListAndButton(ingredient.variants, DataUtils.DefaultOrdering, SetItem, "Accepted fluid variants")); } @@ -136,7 +136,7 @@ private void DrawProducts(ImGui gui, Recipe recipe) { } for (int i = recipe.products.Length - 1; i >= 0; i--) { var product = recipe.products[i]; - if (gui.BuildFactorioObjectWithAmount(product.goods, product.amount) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(product.goods, product.amount, ButtonDisplayStyle.NeieSmall) == Click.Left) { changing = product.goods; } } @@ -146,7 +146,7 @@ private void DrawTooManyThings(ImGui gui, IEnumerable li using var grid = gui.EnterInlineGrid(3f, 0f, maxElemCount); foreach (var item in list) { grid.Next(); - if (gui.BuildFactorioObjectWithAmount(item.target, item.amount) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(item.target, item.amount, ButtonDisplayStyle.NeieSmall) == Click.Left) { changing = item.target as Goods; } } @@ -178,7 +178,7 @@ private void DrawRecipeEntry(ImGui gui, RecipeEntry entry, bool production) { using (gui.EnterGroup(new Padding(0.5f), production ? RectAllocator.LeftRow : RectAllocator.RightRow, textColor)) { using (gui.EnterFixedPositioning(4f, 0f, default)) { gui.allocator = RectAllocator.Stretch; - _ = gui.BuildFactorioObjectButton(entry.recipe, 4f, MilestoneDisplay.Contained); + _ = gui.BuildFactorioObjectButton(entry.recipe, ButtonDisplayStyle.NeieLarge); using (gui.EnterRow()) { gui.BuildIcon(Icon.Time); gui.BuildText(DataUtils.FormatAmount(entry.recipe.time, UnitOfMeasure.Second), TextBlockDisplayStyle.Centered); @@ -256,7 +256,7 @@ private void DrawEntryFooter(ImGui gui, bool production) { using var grid = gui.EnterInlineGrid(3f); foreach (var fuelUsage in current.fuelFor) { grid.Next(); - _ = gui.BuildFactorioObjectButton(fuelUsage, 3f, MilestoneDisplay.Contained); + _ = gui.BuildFactorioObjectButton(fuelUsage, ButtonDisplayStyle.NeieSmall); } } if (gui.isBuilding) { @@ -305,7 +305,7 @@ private void DrawEntryList(ImGui gui, ReadOnlySpan entries, bool pr if (status == EntryStatus.NotAccessibleWithCurrentMilestones) { var latest = Milestones.Instance.GetHighest(entry.recipe, false); if (latest != prevLatestMilestone) { - _ = gui.BuildFactorioObjectButtonWithText(latest, size: 3f, display: MilestoneDisplay.None); + _ = gui.BuildFactorioObjectButtonWithText(latest, iconDisplayStyle: new(3, MilestoneDisplay.None, false)); prevLatestMilestone = latest; } } @@ -335,14 +335,14 @@ public override void Build(ImGui gui) { for (int i = recent.Count - 1; i >= 0; i--) { var elem = recent[i]; - if (gui.BuildFactorioObjectButton(elem, 3f) == Click.Left) { + if (gui.BuildFactorioObjectButton(elem, ButtonDisplayStyle.NeieSmall) == Click.Left) { changing = elem; } } } using (gui.EnterGroup(new Padding(0.5f), RectAllocator.LeftRow)) { gui.spacing = 0.2f; - gui.BuildFactorioObjectIcon(current, size: 3f); + gui.BuildFactorioObjectIcon(current, ButtonDisplayStyle.NeieSmall); gui.BuildText(current.locName, Font.subheader); gui.allocator = RectAllocator.RightAlign; gui.BuildText(CostAnalysis.GetDisplayCost(current)); @@ -352,7 +352,7 @@ public override void Build(ImGui gui) { } } - if (gui.BuildFactorioObjectButton(gui.lastRect, current, SchemeColor.Grey) == Click.Left) { + if (gui.BuildFactorioObjectButtonBackground(gui.lastRect, current, SchemeColor.Grey) == Click.Left) { SelectSingleObjectPanel.Select(Database.goods.all, "Select item", SetItem); } diff --git a/Yafc/Windows/ProjectPageSettingsPanel.cs b/Yafc/Windows/ProjectPageSettingsPanel.cs index e9ce9df0..17d838a8 100644 --- a/Yafc/Windows/ProjectPageSettingsPanel.cs +++ b/Yafc/Windows/ProjectPageSettingsPanel.cs @@ -26,7 +26,7 @@ private ProjectPageSettingsPanel(ProjectPage? editingPage, Action setIcon) { _ = gui.BuildTextInput(name, out name, "Input name", setInitialFocus: editingPage == null); - if (gui.BuildFactorioObjectButton(icon, 4f, MilestoneDisplay.None, SchemeColor.Grey) == Click.Left) { + if (gui.BuildFactorioObjectButton(icon, new ButtonDisplayStyle(4f, MilestoneDisplay.None, SchemeColor.Grey) with { UseScaleSetting = false }) == Click.Left) { SelectSingleObjectPanel.Select(Database.objects.all, "Select icon", setIcon); } diff --git a/Yafc/Windows/SelectMultiObjectPanel.cs b/Yafc/Windows/SelectMultiObjectPanel.cs index 62a1e96c..2ce3223c 100644 --- a/Yafc/Windows/SelectMultiObjectPanel.cs +++ b/Yafc/Windows/SelectMultiObjectPanel.cs @@ -29,7 +29,8 @@ public static void Select(IEnumerable list, string header, Action selec } protected override void NonNullElementDrawer(ImGui gui, FactorioObject element) { - Click click = gui.BuildFactorioObjectButton(element, 2.5f, MilestoneDisplay.Contained, results.Contains(element) ? SchemeColor.Primary : SchemeColor.None, true, new() { ExtendHeader = extendHeader }); + SchemeColor bgColor = results.Contains(element) ? SchemeColor.Primary : SchemeColor.None; + Click click = gui.BuildFactorioObjectButton(element, ButtonDisplayStyle.SelectObjectPanel(bgColor), new() { ExtendHeader = extendHeader }); if (checkMark(element)) { gui.DrawIcon(Rect.SideRect(gui.lastRect.TopLeft + new Vector2(1, 0), gui.lastRect.BottomRight - new Vector2(0, 1)), Icon.Check, SchemeColor.Green); diff --git a/Yafc/Windows/SelectSingleObjectPanel.cs b/Yafc/Windows/SelectSingleObjectPanel.cs index 2fb17b30..db1d9df6 100644 --- a/Yafc/Windows/SelectSingleObjectPanel.cs +++ b/Yafc/Windows/SelectSingleObjectPanel.cs @@ -34,7 +34,7 @@ public static void SelectWithNone(IEnumerable list, string header, Action< => Instance.Select(list, header, selectItem, ordering, (obj, mappedAction) => mappedAction(obj), true, noneTooltip); protected override void NonNullElementDrawer(ImGui gui, FactorioObject element) { - if (gui.BuildFactorioObjectButton(element, 2.5f, MilestoneDisplay.Contained, useScale: true, tooltipOptions: new() { ExtendHeader = extendHeader }) == Click.Left) { + if (gui.BuildFactorioObjectButton(element, ButtonDisplayStyle.SelectObjectPanel(SchemeColor.None), tooltipOptions: new() { ExtendHeader = extendHeader }) == Click.Left) { CloseWithResult(element); } } diff --git a/Yafc/Windows/ShoppingListScreen.cs b/Yafc/Windows/ShoppingListScreen.cs index 9d4d4b2f..52e458f1 100644 --- a/Yafc/Windows/ShoppingListScreen.cs +++ b/Yafc/Windows/ShoppingListScreen.cs @@ -17,10 +17,10 @@ public class ShoppingListScreen : PseudoScreen { private void ElementDrawer(ImGui gui, (FactorioObject obj, float count) element, int index) { using (gui.EnterRow()) { - gui.BuildFactorioObjectIcon(element.obj, MilestoneDisplay.Contained); + gui.BuildFactorioObjectIcon(element.obj, new IconDisplayStyle(2, MilestoneDisplay.Contained, false)); gui.RemainingRow().BuildText(DataUtils.FormatAmount(element.count, UnitOfMeasure.None, "x") + ": " + element.obj.locName); } - _ = gui.BuildFactorioObjectButton(gui.lastRect, element.obj); + _ = gui.BuildFactorioObjectButtonBackground(gui.lastRect, element.obj); } public static void Show(Dictionary counts) { diff --git a/Yafc/Workspace/AutoPlannerView.cs b/Yafc/Workspace/AutoPlannerView.cs index 702f3723..095ba45a 100644 --- a/Yafc/Workspace/AutoPlannerView.cs +++ b/Yafc/Workspace/AutoPlannerView.cs @@ -18,7 +18,7 @@ protected override void BuildPageTooltip(ImGui gui, AutoPlanner contents) { using var grid = gui.EnterInlineGrid(3f, 1f); foreach (var goal in contents.goals) { grid.Next(); - _ = gui.BuildFactorioObjectWithAmount(goal.item, new(goal.amount, goal.item.flowUnitOfMeasure)); + _ = gui.BuildFactorioObjectWithAmount(goal.item, new(goal.amount, goal.item.flowUnitOfMeasure), ButtonDisplayStyle.ProductionTableUnscaled); } } @@ -37,7 +37,7 @@ void Page1(ImGui gui, ref bool valid) { var elem = goal[i]; grid.Next(); DisplayAmount amount = new(elem.amount, elem.item.flowUnitOfMeasure); - if (gui.BuildFactorioObjectWithEditableAmount(elem.item, amount) == GoodsWithAmountEvent.TextEditing) { + if (gui.BuildFactorioObjectWithEditableAmount(elem.item, amount, ButtonDisplayStyle.ProductionTableUnscaled) == GoodsWithAmountEvent.TextEditing) { if (amount.Value != 0f) { elem.amount = amount.Value; } @@ -90,7 +90,7 @@ protected override void BuildContent(ImGui gui) { } } grid.Next(); - if (gui.BuildFactorioObjectWithAmount(recipe.recipe, new(recipe.recipesPerSecond, UnitOfMeasure.PerSecond), color) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(recipe.recipe, new(recipe.recipesPerSecond, UnitOfMeasure.PerSecond), ButtonDisplayStyle.ProductionTableScaled(color)) == Click.Left) { selectedRecipe = recipe; } } diff --git a/Yafc/Workspace/ProductionSummary/ProductionSummaryView.cs b/Yafc/Workspace/ProductionSummary/ProductionSummaryView.cs index bded06e4..0be18f9b 100644 --- a/Yafc/Workspace/ProductionSummary/ProductionSummaryView.cs +++ b/Yafc/Workspace/ProductionSummary/ProductionSummaryView.cs @@ -168,7 +168,7 @@ public override void BuildHeader(ImGui gui) { var moveHandle = gui.statePosition; moveHandle.Height = 5f; - if (gui.BuildFactorioObjectWithAmount(goods, new(view.model.GetTotalFlow(goods), goods.flowUnitOfMeasure), view.filteredGoods == goods ? SchemeColor.Primary : SchemeColor.None) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(goods, new(view.model.GetTotalFlow(goods), goods.flowUnitOfMeasure), ButtonDisplayStyle.ProductionTableScaled(view.filteredGoods == goods ? SchemeColor.Primary : SchemeColor.None)) == Click.Left) { view.ApplyFilter(goods); } @@ -181,7 +181,7 @@ public override void BuildHeader(ImGui gui) { public override void BuildElement(ImGui gui, ProductionSummaryEntry data) { float amount = data.GetAmount(goods); if (amount != 0) { - if (gui.BuildFactorioObjectWithAmount(goods, new(data.GetAmount(goods), goods.flowUnitOfMeasure)) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(goods, new(data.GetAmount(goods), goods.flowUnitOfMeasure), ButtonDisplayStyle.ProductionTableUnscaled) == Click.Left) { view.ApplyFilter(goods); } } @@ -303,7 +303,7 @@ protected override void BuildContent(ImGui gui) { using var inlineGrid = gui.EnterInlineGrid(3f, 1f); foreach (var (goods, amount) in model.sortedFlow) { inlineGrid.Next(); - if (gui.BuildFactorioObjectWithAmount(goods, new(amount, goods.flowUnitOfMeasure), model.columnsExist.Contains(goods) ? SchemeColor.Primary : SchemeColor.None) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(goods, new(amount, goods.flowUnitOfMeasure), ButtonDisplayStyle.ProductionTableScaled(model.columnsExist.Contains(goods) ? SchemeColor.Primary : SchemeColor.None)) == Click.Left) { AddOrRemoveColumn(goods); } } diff --git a/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs b/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs index a7f1e149..ed25b89d 100644 --- a/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs +++ b/Yafc/Workspace/ProductionTable/ModuleCustomizationScreen.cs @@ -30,7 +30,7 @@ public override void Build(ImGui gui) { BuildHeader(gui, "Module customization"); if (template != null) { using (gui.EnterRow()) { - if (gui.BuildFactorioObjectButton(template.icon) == Click.Left) { + if (gui.BuildFactorioObjectButton(template.icon, ButtonDisplayStyle.Default) == Click.Left) { SelectSingleObjectPanel.SelectWithNone(Database.objects.all, "Select icon", x => { template.RecordUndo().icon = x; Rebuild(); @@ -46,7 +46,7 @@ public override void Build(ImGui gui) { for (int i = 0; i < template.filterEntities.Count; i++) { var entity = template.filterEntities[i]; grid.Next(); - gui.BuildFactorioObjectIcon(entity, MilestoneDisplay.Contained); + gui.BuildFactorioObjectIcon(entity, new(2, MilestoneDisplay.Contained, false)); if (gui.BuildMouseOverIcon(Icon.Close, SchemeColor.Error)) { template.RecordUndo().filterEntities.RemoveAt(i); } @@ -167,7 +167,7 @@ private void DrawRecipeModules(ImGui gui, EntityBeacon? beacon, ref ModuleEffect foreach (RecipeRowCustomModule rowCustomModule in list) { grid.Next(); DisplayAmount amount = rowCustomModule.fixedCount; - switch (gui.BuildFactorioObjectWithEditableAmount(rowCustomModule.module, amount)) { + switch (gui.BuildFactorioObjectWithEditableAmount(rowCustomModule.module, amount, ButtonDisplayStyle.ProductionTableUnscaled)) { case GoodsWithAmountEvent.LeftButtonClick: SelectSingleObjectPanel.SelectWithNone(GetModules(beacon), "Select module", sel => { if (sel == null) { diff --git a/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs b/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs index 7d1fa506..bbb97d68 100644 --- a/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs +++ b/Yafc/Workspace/ProductionTable/ModuleFillerParametersScreen.cs @@ -25,7 +25,7 @@ private ModuleFillerParametersScreen(ModuleFillerParameters modules) { private void ListDrawer(ImGui gui, KeyValuePair element, int index) { (EntityCrafter crafter, BeaconOverrideConfiguration config) = element; DisplayAmount amount = config.beaconCount; - GoodsWithAmountEvent click = gui.BuildFactorioObjectWithEditableAmount(crafter, amount, allowScroll: false); + GoodsWithAmountEvent click = gui.BuildFactorioObjectWithEditableAmount(crafter, amount, ButtonDisplayStyle.ProductionTableUnscaled, allowScroll: false); gui.DrawIcon(new(gui.lastRect.X, gui.lastRect.Y, 1.25f, 1.25f), config.beacon.icon, SchemeColor.Source); gui.DrawIcon(new(gui.lastRect.TopRight - new Vector2(1.25f, 0), new Vector2(1.25f, 1.25f)), config.beaconModule.icon, SchemeColor.Source); switch (click) { @@ -140,7 +140,7 @@ public override void Build(ImGui gui) { using (gui.EnterRow()) { foreach ((EntityCrafter crafter, BeaconOverrideConfiguration beaconInfo) in modules.overrideCrafterBeacons) { DisplayAmount amount = beaconInfo.beaconCount; - GoodsWithAmountEvent click = gui.BuildFactorioObjectWithEditableAmount(crafter, amount); + GoodsWithAmountEvent click = gui.BuildFactorioObjectWithEditableAmount(crafter, amount, ButtonDisplayStyle.ProductionTableUnscaled); gui.DrawIcon(new Rect(gui.lastRect.TopLeft, new Vector2(1.25f, 1.25f)), beaconInfo.beacon.icon, SchemeColor.Source); gui.DrawIcon(new Rect(gui.lastRect.TopRight - new Vector2(1.25f, 0), new Vector2(1.25f, 1.25f)), beaconInfo.beaconModule.icon, SchemeColor.Source); switch (click) { diff --git a/Yafc/Workspace/ProductionTable/ProductionTableView.cs b/Yafc/Workspace/ProductionTable/ProductionTableView.cs index 93e78739..9dcd17e3 100644 --- a/Yafc/Workspace/ProductionTable/ProductionTableView.cs +++ b/Yafc/Workspace/ProductionTable/ProductionTableView.cs @@ -100,7 +100,7 @@ private void BuildRowMarker(ImGui gui, RecipeRow row) { private class RecipeColumn(ProductionTableView view) : ProductionTableDataColumn(view, "Recipe", 13f, 13f, 30f, widthStorage: nameof(Preferences.recipeColumnWidth)) { public override void BuildElement(ImGui gui, RecipeRow recipe) { gui.spacing = 0.5f; - switch (gui.BuildFactorioObjectButton(recipe.recipe, 3f)) { + switch (gui.BuildFactorioObjectButton(recipe.recipe, ButtonDisplayStyle.ProductionTableUnscaled)) { case Click.Left: gui.ShowDropDown(delegate (ImGui imgui) { view.DrawRecipeTagSelect(imgui, recipe); @@ -282,7 +282,7 @@ public override void BuildElement(ImGui gui, RecipeRow recipe) { group.SetWidth(3f); if (recipe.fixedBuildings > 0) { DisplayAmount amount = recipe.fixedBuildings; - GoodsWithAmountEvent evt = gui.BuildFactorioObjectWithEditableAmount(recipe.entity, amount, useScale: false); + GoodsWithAmountEvent evt = gui.BuildFactorioObjectWithEditableAmount(recipe.entity, amount, ButtonDisplayStyle.ProductionTableUnscaled); if (evt == GoodsWithAmountEvent.TextEditing && amount.Value >= 0) { recipe.RecordUndo().fixedBuildings = amount.Value; } @@ -290,7 +290,7 @@ public override void BuildElement(ImGui gui, RecipeRow recipe) { click = (Click)evt; } else { - click = gui.BuildFactorioObjectWithAmount(recipe.entity, recipe.buildingCount, useScale: false); + click = gui.BuildFactorioObjectWithAmount(recipe.entity, recipe.buildingCount, ButtonDisplayStyle.ProductionTableUnscaled); } if (recipe.builtBuildings != null) { @@ -339,7 +339,7 @@ private static void BuildSolarPanelAccumulatorView(ImGui gui, RecipeRow recipe) var accumulator = recipe.GetVariant(Database.allAccumulators); float requiredMj = recipe.entity?.craftingSpeed * recipe.buildingCount * (70 / 0.7f) ?? 0; // 70 seconds of charge time to last through the night float requiredAccumulators = requiredMj / accumulator.accumulatorCapacity; - if (gui.BuildFactorioObjectWithAmount(accumulator, requiredAccumulators) == Click.Left) { + if (gui.BuildFactorioObjectWithAmount(accumulator, requiredAccumulators, ButtonDisplayStyle.ProductionTableUnscaled) == Click.Left) { ShowAccumulatorDropdown(gui, recipe, accumulator); } } @@ -565,7 +565,7 @@ public override void BuildElement(ImGui gui, RecipeRow recipe) { void drawItem(ImGui gui, FactorioObject? item, int count) { grid.Next(); - switch (gui.BuildFactorioObjectWithAmount(item, count, useScale: false)) { + switch (gui.BuildFactorioObjectWithAmount(item, count, ButtonDisplayStyle.ProductionTableUnscaled)) { case Click.Left: ShowModuleDropDown(gui, recipe); break; @@ -584,15 +584,15 @@ private void ShowModuleTemplateTooltip(ImGui gui, ModuleTemplate template) => gu using var grid = imGui.EnterInlineGrid(3f, 1f); foreach (var module in template.list) { grid.Next(); - _ = imGui.BuildFactorioObjectWithAmount(module.module, module.fixedCount); + _ = imGui.BuildFactorioObjectWithAmount(module.module, module.fixedCount, ButtonDisplayStyle.ProductionTableUnscaled); } if (template.beacon != null) { grid.Next(); - _ = imGui.BuildFactorioObjectWithAmount(template.beacon, template.CalcBeaconCount()); + _ = imGui.BuildFactorioObjectWithAmount(template.beacon, template.CalcBeaconCount(), ButtonDisplayStyle.ProductionTableUnscaled); foreach (var module in template.beaconList) { grid.Next(); - _ = imGui.BuildFactorioObjectWithAmount(module.module, module.fixedCount); + _ = imGui.BuildFactorioObjectWithAmount(module.module, module.fixedCount, ButtonDisplayStyle.ProductionTableUnscaled); } } }); @@ -770,7 +770,7 @@ void dropDownContent(ImGui gui) { using (var grid = gui.EnterInlineGrid(3f)) { foreach (var variant in variants) { grid.Next(); - if (gui.BuildFactorioObjectButton(variant, 3f, MilestoneDisplay.Contained, variant == goods ? SchemeColor.Primary : SchemeColor.None, tooltipOptions: HintLocations.OnProducingRecipes) == Click.Left && + if (gui.BuildFactorioObjectButton(variant, ButtonDisplayStyle.ProductionTableScaled(variant == goods ? SchemeColor.Primary : SchemeColor.None), tooltipOptions: HintLocations.OnProducingRecipes) == Click.Left && variant != goods) { recipe!.RecordUndo().ChangeVariant(goods, variant); // null-forgiving: If variants is not null, neither is recipe: Only the call from BuildGoodsIcon sets variants, and the only call to BuildGoodsIcon that sets variants also sets recipe. _ = gui.CloseDropdown(); @@ -926,7 +926,7 @@ private void DrawDesiredProduct(ImGui gui, ProductionLink element) { ObjectTooltipOptions tooltipOptions = element.amount < 0 ? HintLocations.OnConsumingRecipes : HintLocations.OnProducingRecipes; DisplayAmount amount = new(element.amount, element.goods.flowUnitOfMeasure); - switch (gui.BuildFactorioObjectWithEditableAmount(element.goods, amount, iconColor, tooltipOptions: tooltipOptions)) { + switch (gui.BuildFactorioObjectWithEditableAmount(element.goods, amount, ButtonDisplayStyle.ProductionTableScaled(iconColor), tooltipOptions: tooltipOptions)) { case GoodsWithAmountEvent.LeftButtonClick: OpenProductDropdown(gui, gui.lastRect, element.goods, element.amount, element, ProductDropdownType.DesiredProduct, null, element.owner); break; @@ -980,7 +980,7 @@ private void BuildGoodsIcon(ImGui gui, Goods? goods, ProductionLink? link, float textColor = SchemeColor.BackgroundTextFaint; } - switch (gui.BuildFactorioObjectWithAmount(goods, new(amount, goods?.flowUnitOfMeasure ?? UnitOfMeasure.None), iconColor, TextBlockDisplayStyle.Centered with { Color = textColor }, tooltipOptions: tooltipOptions)) { + switch (gui.BuildFactorioObjectWithAmount(goods, new(amount, goods?.flowUnitOfMeasure ?? UnitOfMeasure.None), ButtonDisplayStyle.ProductionTableScaled(iconColor), TextBlockDisplayStyle.Centered with { Color = textColor }, tooltipOptions: tooltipOptions)) { case Click.Left when goods is not null: OpenProductDropdown(gui, gui.lastRect, goods, amount, link, dropdownType, recipe, context, variants); break; @@ -1094,7 +1094,7 @@ private void BuildBeltInserterInfo(ImGui gui, float amount, float buildingCount) bool click = false; using (gui.EnterRow()) { - click |= gui.BuildFactorioObjectButton(belt) == Click.Left; + click |= gui.BuildFactorioObjectButton(belt, ButtonDisplayStyle.Default) == Click.Left; gui.BuildText(DataUtils.FormatAmount(beltCount, UnitOfMeasure.None)); if (buildingsPerHalfBelt > 0f) { gui.BuildText("(Buildings per half belt: " + DataUtils.FormatAmount(buildingsPerHalfBelt, UnitOfMeasure.None) + ")"); @@ -1104,7 +1104,7 @@ private void BuildBeltInserterInfo(ImGui gui, float amount, float buildingCount) using (gui.EnterRow()) { int capacity = prefs.inserterCapacity; float inserterBase = inserter.inserterSwingTime * amount / capacity; - click |= gui.BuildFactorioObjectButton(inserter) == Click.Left; + click |= gui.BuildFactorioObjectButton(inserter, ButtonDisplayStyle.Default) == Click.Left; string text = DataUtils.FormatAmount(inserterBase, UnitOfMeasure.None); if (buildingCount > 1) { text += " (" + DataUtils.FormatAmount(inserterBase / buildingCount, UnitOfMeasure.None) + "/building)"; @@ -1114,9 +1114,9 @@ private void BuildBeltInserterInfo(ImGui gui, float amount, float buildingCount) if (capacity > 1) { float withBeltSwingTime = inserter.inserterSwingTime + (2f * (capacity - 1.5f) / belt.beltItemsPerSecond); float inserterToBelt = amount * withBeltSwingTime / capacity; - click |= gui.BuildFactorioObjectButton(belt) == Click.Left; + click |= gui.BuildFactorioObjectButton(belt, ButtonDisplayStyle.Default) == Click.Left; gui.AllocateSpacing(-1.5f); - click |= gui.BuildFactorioObjectButton(inserter) == Click.Left; + click |= gui.BuildFactorioObjectButton(inserter, ButtonDisplayStyle.Default) == Click.Left; text = DataUtils.FormatAmount(inserterToBelt, UnitOfMeasure.None, "~"); if (buildingCount > 1) { text += " (" + DataUtils.FormatAmount(inserterToBelt / buildingCount, UnitOfMeasure.None) + "/b)"; diff --git a/Yafc/Workspace/SummaryView.cs b/Yafc/Workspace/SummaryView.cs index b9e19672..2b458ee0 100644 --- a/Yafc/Workspace/SummaryView.cs +++ b/Yafc/Workspace/SummaryView.cs @@ -105,7 +105,7 @@ private static void DrawProvideProduct(ImGui gui, ProductionLink element, Projec gui.allocator = RectAllocator.Stretch; gui.spacing = 0f; DisplayAmount amount = new(element.amount, element.goods.flowUnitOfMeasure); - GoodsWithAmountEvent evt = gui.BuildFactorioObjectWithEditableAmount(element.goods, amount, iconColor); + GoodsWithAmountEvent evt = gui.BuildFactorioObjectWithEditableAmount(element.goods, amount, ButtonDisplayStyle.ProductionTableScaled(iconColor)); if (evt == GoodsWithAmountEvent.TextEditing && amount.Value != 0) { SetProviderAmount(element, page, amount.Value); } @@ -132,7 +132,7 @@ private static void DrawRequestProduct(ImGui gui, ProductionTableFlow flow, bool gui.allocator = RectAllocator.Stretch; gui.spacing = 0f; - _ = gui.BuildFactorioObjectWithAmount(flow.goods, new(-flow.amount, flow.goods.flowUnitOfMeasure), iconColor); + _ = gui.BuildFactorioObjectWithAmount(flow.goods, new(-flow.amount, flow.goods.flowUnitOfMeasure), ButtonDisplayStyle.ProductionTableScaled(iconColor)); } private static void SetProviderAmount(ProductionLink element, ProjectPage page, float newAmount) { diff --git a/changelog.txt b/changelog.txt index 8901edb7..b65d3d15 100644 --- a/changelog.txt +++ b/changelog.txt @@ -19,6 +19,9 @@ Version Date: Bugfixes: - Refuse to accept negative numbers in several places where they don't make sense. + Internal changes: + - Refactor a lot of the drawing code to increase both UI consistency and consistency in being able to pass + options to methods that should accept them. ---------------------------------------------------------------------------------------------------------------------- Version 0.8.0 Date: August 3rd 2024