From 66f2cf3652900cf3e5208a96db6839b8bf6f7fea Mon Sep 17 00:00:00 2001
From: Dale McCoy <21223975+DaleStan@users.noreply.github.com>
Date: Sat, 8 Jun 2024 16:23:45 -0400
Subject: [PATCH 1/3] feature: Allow additional data to be displayed in
tooltips.
---
Yafc/Widgets/ObjectTooltip.cs | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/Yafc/Widgets/ObjectTooltip.cs b/Yafc/Widgets/ObjectTooltip.cs
index 8049ae1c..4584210c 100644
--- a/Yafc/Widgets/ObjectTooltip.cs
+++ b/Yafc/Widgets/ObjectTooltip.cs
@@ -145,6 +145,8 @@ protected override void BuildContents(ImGui gui) {
private void BuildCommon(FactorioObject target, ImGui gui) {
BuildHeader(gui);
using (gui.EnterGroup(contentPadding)) {
+ tooltipOptions.DrawBelowHeader?.Invoke(gui);
+
if (InputSystem.Instance.control) {
gui.BuildText(target.typeDotName);
}
@@ -545,8 +547,18 @@ public struct ObjectTooltipOptions {
/// Gets or sets flags indicating where hints should be displayed in the tooltip.
///
public HintLocations HintLocations { get; set; }
+ ///
+ /// Gets or sets a value that, if not null, will be called after drawing the tooltip header.
+ ///
+ public DrawBelowHeader? DrawBelowHeader { get; set; }
// Reduce boilerplate by permitting unambiguous and relatively obvious implicit conversions.
public static implicit operator ObjectTooltipOptions(HintLocations hintLocations) => new() { HintLocations = hintLocations };
+ public static implicit operator ObjectTooltipOptions(DrawBelowHeader drawBelowHeader) => new() { DrawBelowHeader = drawBelowHeader };
}
+
+ ///
+ /// Called to draw additional information in the tooltip after drawing the tooltip header.
+ ///
+ public delegate void DrawBelowHeader(ImGui gui);
}
From 145bc40121be7fcd13da6ad3c3050948a8c9ab4c Mon Sep 17 00:00:00 2001
From: Dale McCoy <21223975+DaleStan@users.noreply.github.com>
Date: Mon, 9 Sep 2024 03:14:40 -0400
Subject: [PATCH 2/3] feature(#271): Show link warnings in tooltips, in
addition to dropdowns.
---
Yafc.Model/Model/ProductionTableContent.cs | 29 +++++++++++++
.../ProductionTable/ProductionTableView.cs | 41 ++++++++-----------
changelog.txt | 10 ++---
3 files changed, 51 insertions(+), 29 deletions(-)
diff --git a/Yafc.Model/Model/ProductionTableContent.cs b/Yafc.Model/Model/ProductionTableContent.cs
index f0060730..bd787d34 100644
--- a/Yafc.Model/Model/ProductionTableContent.cs
+++ b/Yafc.Model/Model/ProductionTableContent.cs
@@ -638,6 +638,35 @@ public enum Flags {
[SkipSerialization] public HashSet capturedRecipes { get; } = [];
internal int solverIndex;
public float dualValue { get; internal set; }
+
+ public IEnumerable LinkWarnings {
+ get {
+ if (!flags.HasFlags(Flags.HasProduction)) {
+ yield return "This link has no production (Link ignored)";
+ }
+
+ if (!flags.HasFlags(Flags.HasConsumption)) {
+ yield return "This link has no consumption (Link ignored)";
+ }
+
+ if (flags.HasFlags(Flags.ChildNotMatched)) {
+ yield return "Nested table link has unmatched production/consumption. These unmatched products are not captured by this link.";
+ }
+
+ if (!flags.HasFlags(Flags.HasProductionAndConsumption) && owner.owner is RecipeRow recipeRow && recipeRow.FindLink(goods, out _)) {
+ yield return "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.";
+ }
+
+ if (flags.HasFlags(Flags.LinkRecursiveNotMatched)) {
+ if (notMatchedFlow <= 0f) {
+ yield return "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.";
+ }
+ else {
+ yield return "YAFC was unable to satisfy this link (Overproduction). You can allow overproduction for this link to solve the error.";
+ }
+ }
+ }
+ }
}
public record RecipeRowIngredient(Goods? Goods, float Amount, ProductionLink? Link, Goods[]? Variants) {
diff --git a/Yafc/Workspace/ProductionTable/ProductionTableView.cs b/Yafc/Workspace/ProductionTable/ProductionTableView.cs
index 0d701d78..087ed9b5 100644
--- a/Yafc/Workspace/ProductionTable/ProductionTableView.cs
+++ b/Yafc/Workspace/ProductionTable/ProductionTableView.cs
@@ -777,29 +777,8 @@ void dropDownContent(ImGui gui) {
}
if (link != null) {
- if (!link.flags.HasFlags(ProductionLink.Flags.HasProduction)) {
- 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)", 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.", 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", 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.", TextBlockDisplayStyle.ErrorText);
- }
- else {
- gui.BuildText("YAFC was unable to satisfy this link (Overproduction). You can allow overproduction for this link to solve the error.", TextBlockDisplayStyle.ErrorText);
- }
+ foreach (string warning in link.LinkWarnings) {
+ gui.BuildText(warning, TextBlockDisplayStyle.ErrorText);
}
}
@@ -1017,6 +996,14 @@ private void DrawDesiredProduct(ImGui gui, ProductionLink element) {
}
ObjectTooltipOptions tooltipOptions = element.amount < 0 ? HintLocations.OnConsumingRecipes : HintLocations.OnProducingRecipes;
+ if (element.LinkWarnings is IEnumerable warnings) {
+ tooltipOptions.DrawBelowHeader = gui => {
+ foreach (string warning in warnings) {
+ gui.BuildText(warning, TextBlockDisplayStyle.ErrorText);
+ }
+ };
+ }
+
DisplayAmount amount = new(element.amount, element.goods.flowUnitOfMeasure);
switch (gui.BuildFactorioObjectWithEditableAmount(element.goods, amount, ButtonDisplayStyle.ProductionTableScaled(iconColor), tooltipOptions: tooltipOptions)) {
case GoodsWithAmountEvent.LeftButtonClick:
@@ -1075,6 +1062,14 @@ private void BuildGoodsIcon(ImGui gui, Goods? goods, ProductionLink? link, float
GoodsWithAmountEvent evt;
DisplayAmount displayAmount = new(amount, goods?.flowUnitOfMeasure ?? UnitOfMeasure.None);
+ if (link?.LinkWarnings is IEnumerable warnings) {
+ tooltipOptions.DrawBelowHeader += gui => {
+ foreach (string warning in warnings) {
+ gui.BuildText(warning, TextBlockDisplayStyle.ErrorText);
+ }
+ };
+ }
+
if (recipe != null && recipe.fixedBuildings > 0
&& ((dropdownType == ProductDropdownType.Fuel && recipe.fixedFuel)
|| (dropdownType == ProductDropdownType.Ingredient && recipe.fixedIngredient == goods)
diff --git a/changelog.txt b/changelog.txt
index 6773d5ae..ffa6ac1e 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -15,15 +15,13 @@
// Internal changes:
// Changes to the code that do not affect the behavior of the program.
----------------------------------------------------------------------------------------------------------------------
-Version: 0.10.1
-Date:
- Bugfixes:
- - Fixed recipes now become accessible when their crafter does.
-----------------------------------------------------------------------------------------------------------------------
Version: 0.10.0
Date:
- Feature:
+ Features:
- Add OSX-arm64 build.
+ - Display link warnings in both the tooltips and the dropdowns.
+ Bugfixes:
+ - Fixed recipes now become accessible when their crafter does.
----------------------------------------------------------------------------------------------------------------------
Version: 0.9.1
Date: September 8th 2024
From 3d1c00a62173d23b3bfe889adfc30a13a74adf8b Mon Sep 17 00:00:00 2001
From: Dale McCoy <21223975+DaleStan@users.noreply.github.com>
Date: Mon, 9 Sep 2024 13:21:44 -0400
Subject: [PATCH 3/3] refactor: Rename "extendHeader" to "showTypeInHeader"
---
Yafc/Widgets/ObjectTooltip.cs | 4 ++--
Yafc/Windows/DependencyExplorer.cs | 2 +-
Yafc/Windows/SelectMultiObjectPanel.cs | 2 +-
Yafc/Windows/SelectObjectPanel.cs | 6 +++---
Yafc/Windows/SelectSingleObjectPanel.cs | 2 +-
5 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/Yafc/Widgets/ObjectTooltip.cs b/Yafc/Widgets/ObjectTooltip.cs
index 4584210c..fd903a49 100644
--- a/Yafc/Widgets/ObjectTooltip.cs
+++ b/Yafc/Widgets/ObjectTooltip.cs
@@ -36,7 +36,7 @@ public ObjectTooltip() : base(new Padding(0f, 0f, 0f, 0.5f), 25f) { }
private void BuildHeader(ImGui gui) {
using (gui.EnterGroup(new Padding(1f, 0.5f), RectAllocator.LeftAlign, spacing: 0f)) {
string name = target.text;
- if (tooltipOptions.ExtendHeader && target is not Goods) {
+ if (tooltipOptions.ShowTypeInHeader && target is not Goods) {
name = name + " (" + target.target.type + ")";
}
@@ -542,7 +542,7 @@ public struct ObjectTooltipOptions {
/// If and the target object is not a , this tooltip will specify the type of object.
/// e.g. "Radar" is the item, "Radar (Recipe)" is the recipe, and "Radar (Entity)" is the building.
///
- public bool ExtendHeader { get; set; }
+ public bool ShowTypeInHeader { get; set; }
///
/// Gets or sets flags indicating where hints should be displayed in the tooltip.
///
diff --git a/Yafc/Windows/DependencyExplorer.cs b/Yafc/Windows/DependencyExplorer.cs
index 1f637fe4..9413ca35 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.BuildFactorioObjectButtonBackground(gui.lastRect, fobj, tooltipOptions: new() { ExtendHeader = true }) == Click.Left) {
+ if (gui.BuildFactorioObjectButtonBackground(gui.lastRect, fobj, tooltipOptions: new() { ShowTypeInHeader = true }) == Click.Left) {
Change(fobj);
}
}
diff --git a/Yafc/Windows/SelectMultiObjectPanel.cs b/Yafc/Windows/SelectMultiObjectPanel.cs
index 2ce3223c..a030208e 100644
--- a/Yafc/Windows/SelectMultiObjectPanel.cs
+++ b/Yafc/Windows/SelectMultiObjectPanel.cs
@@ -30,7 +30,7 @@ public static void Select(IEnumerable list, string header, Action selec
protected override void NonNullElementDrawer(ImGui gui, FactorioObject element) {
SchemeColor bgColor = results.Contains(element) ? SchemeColor.Primary : SchemeColor.None;
- Click click = gui.BuildFactorioObjectButton(element, ButtonDisplayStyle.SelectObjectPanel(bgColor), new() { ExtendHeader = extendHeader });
+ Click click = gui.BuildFactorioObjectButton(element, ButtonDisplayStyle.SelectObjectPanel(bgColor), new() { ShowTypeInHeader = showTypeInHeader });
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/SelectObjectPanel.cs b/Yafc/Windows/SelectObjectPanel.cs
index da120eb0..cdbc4191 100644
--- a/Yafc/Windows/SelectObjectPanel.cs
+++ b/Yafc/Windows/SelectObjectPanel.cs
@@ -17,9 +17,9 @@ public abstract class SelectObjectPanel : PseudoScreenWithResult {
private string? noneTooltip;
///
/// If and the object being hovered is not a , the should specify the type of object.
- /// See also .
+ /// See also .
///
- protected bool extendHeader { get; private set; }
+ protected bool showTypeInHeader { get; private set; }
protected SelectObjectPanel() : base(40f) => list = new SearchableList(30, new Vector2(2.5f, 2.5f), ElementDrawer, ElementFilter);
@@ -39,7 +39,7 @@ public abstract class SelectObjectPanel : PseudoScreenWithResult {
protected void Select(IEnumerable list, string header, Action selectItem, IComparer? ordering, Action> mapResult, bool allowNone, string? noneTooltip = null) where U : FactorioObject {
_ = MainScreen.Instance.ShowPseudoScreen(this);
this.noneTooltip = noneTooltip;
- extendHeader = typeof(U) == typeof(FactorioObject);
+ showTypeInHeader = typeof(U) == typeof(FactorioObject);
List data = new List(list);
ordering ??= DataUtils.DefaultOrdering;
data.Sort(ordering!); // null-forgiving: We don't have any nulls in the list yet.
diff --git a/Yafc/Windows/SelectSingleObjectPanel.cs b/Yafc/Windows/SelectSingleObjectPanel.cs
index db1d9df6..3d1ba7ef 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, ButtonDisplayStyle.SelectObjectPanel(SchemeColor.None), tooltipOptions: new() { ExtendHeader = extendHeader }) == Click.Left) {
+ if (gui.BuildFactorioObjectButton(element, ButtonDisplayStyle.SelectObjectPanel(SchemeColor.None), tooltipOptions: new() { ShowTypeInHeader = showTypeInHeader }) == Click.Left) {
CloseWithResult(element);
}
}