Skip to content

Commit 3c357b0

Browse files
authored
Add building count tooltips 101 (#213)
This closes #101, and should make it easy for similar tooltips to be added in other locations.
2 parents 0ae9d9c + 21c92f7 commit 3c357b0

File tree

7 files changed

+112
-65
lines changed

7 files changed

+112
-65
lines changed

Yafc.UI/Core/Rect.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,5 +126,6 @@ public override int GetHashCode() {
126126
public readonly Rect Expand(float amount) => new Rect(X - amount, Y - amount, Width + (2 * amount), Height + (2 * amount));
127127

128128
public static Rect Square(Vector2 center, float side) => new Rect(center.X - (side * 0.5f), center.Y - (side * 0.5f), side, side);
129+
public static Rect Square(float centerX, float centerY, float side) => new Rect(centerX - (side * 0.5f), centerY - (side * 0.5f), side, side);
129130
}
130131
}

Yafc.UI/ImGui/ImGuiUtils.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,5 +382,51 @@ public static bool CloseDropdown(this ImGui gui) {
382382
gui.PropagateMessage<CloseDropdownEvent>(default);
383383
return true;
384384
}
385+
386+
/// <summary>
387+
/// Draws a row with a (?) help icon at its right side, and a tooltip when the user hovers over the icon.
388+
/// </summary>
389+
/// <param name="tooltip">The tooltip that should be displayed when the user hovers over the (?) icon.</param>
390+
/// <param name="rightJustify">If <see langword="true"/>, the default, the help icon will be as far right as possible.
391+
/// If false, it will be still be drawn at the right end of the row, but as far left as possible.</param>
392+
public static IDisposable EnterRowWithHelpIcon(this ImGui gui, string tooltip, bool rightJustify = true) => new RowWithHelpIcon(gui, tooltip, rightJustify);
393+
394+
/// <summary>
395+
/// The class that sets up and stores the state needed to build a row with a help icon.
396+
/// </summary>
397+
private sealed class RowWithHelpIcon : IDisposable {
398+
private readonly ImGui gui;
399+
private readonly string tooltip;
400+
private readonly ImGui.Context row;
401+
private readonly float helpCenterX;
402+
private readonly ImGui.Context group;
403+
404+
public RowWithHelpIcon(ImGui gui, string tooltip, bool rightJustify) {
405+
this.gui = gui;
406+
this.tooltip = tooltip;
407+
row = gui.EnterRow(); // using (gui.EnterRow()) {
408+
if (rightJustify) {
409+
gui.allocator = RectAllocator.RightRow;
410+
helpCenterX = gui.AllocateRect(1, 1).Center.X;
411+
group = gui.EnterGroup(new Padding(), RectAllocator.RemainingRow); // using (gui.EnterGroup(...)) { // Required to produce the expected spacing/padding behavior.
412+
gui.allocator = RectAllocator.LeftRow;
413+
}
414+
}
415+
416+
public void Dispose() {
417+
Rect rect;
418+
if (helpCenterX != 0) { // if (rightJustify)
419+
group.Dispose(); // end using block for EnterGroup
420+
rect = Rect.Square(helpCenterX, gui.lastRect.Center.Y, 1.25f);
421+
}
422+
else {
423+
rect = gui.AllocateRect(1.25f, 1.25f); // Despite requesting 1.25 x 1.25, rect will be 1.25 x RowHeight, which might be greater than 1.25.
424+
rect = Rect.Square(rect.Center, 1.25f); // Get a vertically-centered rect that's actually 1.25 x 1.25.
425+
}
426+
gui.DrawIcon(rect, Icon.Help, SchemeColor.BackgroundText);
427+
gui.BuildButton(rect, SchemeColor.None, SchemeColor.Grey).WithTooltip(gui, tooltip, rect);
428+
row.Dispose(); // end using block for EnterRow
429+
}
430+
}
385431
}
386432
}

Yafc/Widgets/ImmediateWidgets.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ public static bool BuildInlineObjectList<T>(this ImGui gui, IEnumerable<T> list,
156156
}
157157

158158
if (checkMark != null && gui.isBuilding && checkMark(elem)) {
159-
gui.DrawIcon(Rect.Square(new Vector2(gui.lastRect.Right - 1f, gui.lastRect.Center.Y), 1.5f), Icon.Check, SchemeColor.Green);
159+
gui.DrawIcon(Rect.Square(gui.lastRect.Right - 1f, gui.lastRect.Center.Y, 1.5f), Icon.Check, SchemeColor.Green);
160160
}
161161
}
162162

Yafc/Windows/PreferencesScreen.cs

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,21 @@ public override void Build(ImGui gui) {
3838
gui.BuildText("Fluid production/consumption:", Font.subheader);
3939
BuildUnitPerTime(gui, true, prefs);
4040

41-
drawInputRowWithTooltip(gui, "Pollution cost modifier", "0 for off, 100% for old default",
42-
gui => {
43-
if (gui.BuildFloatInput(settings.PollutionCostModifier, out float pollutionCostModifier, UnitOfMeasure.Percent, new Padding(0.5f))) {
44-
settings.RecordUndo().PollutionCostModifier = pollutionCostModifier;
45-
gui.Rebuild();
46-
}
47-
});
41+
using (gui.EnterRowWithHelpIcon("0 for off, 100% for old default")) {
42+
gui.BuildText("Pollution cost modifier", topOffset: 0.5f);
43+
if (gui.BuildFloatInput(settings.PollutionCostModifier, out float pollutionCostModifier, UnitOfMeasure.Percent, new Padding(0.5f))) {
44+
settings.RecordUndo().PollutionCostModifier = pollutionCostModifier;
45+
gui.Rebuild();
46+
}
47+
}
4848

49-
drawInputRowWithTooltip(gui, "Display scale for linkable icons", "Some mod icons have little or no transparency, hiding the background color. This setting reduces the size of icons that could hide link information.",
50-
gui => {
51-
if (gui.BuildFloatInput(prefs.iconScale, out float iconScale, UnitOfMeasure.Percent, new Padding(0.5f)) && iconScale > 0 && iconScale <= 1) {
52-
prefs.RecordUndo().iconScale = iconScale;
53-
gui.Rebuild();
54-
}
55-
});
49+
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.")) {
50+
gui.BuildText("Display scale for linkable icons", topOffset: 0.5f);
51+
if (gui.BuildFloatInput(prefs.iconScale, out float iconScale, UnitOfMeasure.Percent, new Padding(0.5f)) && iconScale > 0 && iconScale <= 1) {
52+
prefs.RecordUndo().iconScale = iconScale;
53+
gui.Rebuild();
54+
}
55+
}
5656

5757
ChooseObject(gui, "Default belt:", Database.allBelts, prefs.defaultBelt, s => {
5858
prefs.RecordUndo().defaultBelt = s;
@@ -100,19 +100,6 @@ public override void Build(ImGui gui) {
100100
if (settings.justChanged) {
101101
Project.current.RecalculateDisplayPages();
102102
}
103-
104-
static void drawInputRowWithTooltip(ImGui gui, string text, string tooltip, Action<ImGui> handleInput) {
105-
using (gui.EnterRow()) {
106-
gui.BuildText(text, topOffset: 0.5f);
107-
gui.AllocateSpacing();
108-
gui.allocator = RectAllocator.RightRow;
109-
var rect = gui.AllocateRect(1, 1);
110-
handleInput(gui);
111-
rect = new Rect(rect.Center.X, gui.lastRect.Center.Y, 0, 0).Expand(.625f);
112-
gui.DrawIcon(rect, Icon.Help, SchemeColor.BackgroundText);
113-
gui.BuildButton(rect, SchemeColor.None, SchemeColor.Grey).WithTooltip(gui, tooltip, rect);
114-
}
115-
}
116103
}
117104

118105
protected override void ReturnPressed() => Close();

Yafc/Windows/WelcomeScreen.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,10 @@ protected override void BuildContents(ImGui gui) {
142142
gui.BuildText("In-game objects language:");
143143
}
144144

145-
using (gui.EnterRow()) {
145+
using (gui.EnterRowWithHelpIcon("""
146+
If checked, YAFC will only suggest production or consumption recipes that have a net production or consumption of that item or fluid.
147+
For example, kovarex enrichment will not be suggested when adding recipes that produce U-238 or consume U-235.
148+
""", false)) {
146149
gui.BuildCheckBox("Use net production/consumption when analyzing recipes", netProduction, out netProduction);
147150
}
148151

Yafc/Workspace/ProductionTable/ProductionTableView.cs

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -367,57 +367,66 @@ private static void ShowEntityDropdown(ImGui imgui, RecipeRow recipe) => imgui.S
367367
}
368368
}, "Select crafting entity", extra: x => DataUtils.FormatAmount(x.craftingSpeed, UnitOfMeasure.Percent));
369369

370-
if (recipe.fixedBuildings > 0f) {
371-
ButtonEvent evt = gui.BuildButton("Clear fixed building count");
372-
if (willResetFixed) {
373-
evt.WithTooltip(gui, "Shortcut: right-click");
374-
}
375-
if (evt && gui.CloseDropdown()) {
376-
recipe.RecordUndo().fixedBuildings = 0f;
370+
gui.AllocateSpacing(0.5f);
371+
372+
using (gui.EnterRowWithHelpIcon("Tell YAFC how many buildings it must use when solving this page.\nUse this to ask questions like 'What does it take to handle the output of ten miners?'")) {
373+
gui.allocator = RectAllocator.RemainingRow;
374+
if (recipe.fixedBuildings > 0f) {
375+
ButtonEvent evt = gui.BuildButton("Clear fixed building count");
376+
if (willResetFixed) {
377+
evt.WithTooltip(gui, "Shortcut: right-click");
378+
}
379+
if (evt && gui.CloseDropdown()) {
380+
recipe.RecordUndo().fixedBuildings = 0f;
381+
}
377382
}
378-
}
379-
else {
380-
if (gui.BuildButton("Set fixed building count") && gui.CloseDropdown()) {
383+
else if (gui.BuildButton("Set fixed building count") && gui.CloseDropdown()) {
381384
recipe.RecordUndo().fixedBuildings = recipe.buildingCount <= 0f ? 1f : recipe.buildingCount;
382385
}
383386
}
384387

385-
if (recipe.builtBuildings != null) {
386-
ButtonEvent evt = gui.BuildButton("Clear built building count");
387-
if (willResetBuilt) {
388-
evt.WithTooltip(gui, "Shortcut: right-click");
389-
}
390-
if (evt && gui.CloseDropdown()) {
391-
recipe.RecordUndo().builtBuildings = null;
388+
using (gui.EnterRowWithHelpIcon("Tell YAFC how many of these buildings you have in your factory.\nYAFC will warn you if you need to build more buildings.")) {
389+
gui.allocator = RectAllocator.RemainingRow;
390+
if (recipe.builtBuildings != null) {
391+
ButtonEvent evt = gui.BuildButton("Clear built building count");
392+
if (willResetBuilt) {
393+
evt.WithTooltip(gui, "Shortcut: right-click");
394+
}
395+
if (evt && gui.CloseDropdown()) {
396+
recipe.RecordUndo().builtBuildings = null;
397+
}
392398
}
393-
}
394-
else {
395-
if (gui.BuildButton("Set built building count") && gui.CloseDropdown()) {
399+
else if (gui.BuildButton("Set built building count") && gui.CloseDropdown()) {
396400
recipe.RecordUndo().builtBuildings = Math.Max(0, Convert.ToInt32(Math.Ceiling(recipe.buildingCount)));
397401
}
398402
}
399403

400-
if (recipe.entity != null && gui.BuildButton("Create single building blueprint") && gui.CloseDropdown()) {
401-
BlueprintEntity entity = new BlueprintEntity { index = 1, name = recipe.entity.name };
402-
if (recipe.recipe is not Mechanics) {
403-
entity.recipe = recipe.recipe.name;
404-
}
404+
if (recipe.entity != null) {
405+
using (gui.EnterRowWithHelpIcon("Generate a blueprint for one of these buildings, with the recipe and internal modules set.")) {
406+
gui.allocator = RectAllocator.RemainingRow;
407+
if (gui.BuildButton("Create single building blueprint") && gui.CloseDropdown()) {
408+
BlueprintEntity entity = new BlueprintEntity { index = 1, name = recipe.entity.name };
409+
if (recipe.recipe is not Mechanics) {
410+
entity.recipe = recipe.recipe.name;
411+
}
405412

406-
var modules = recipe.parameters.modules.modules;
407-
if (modules != null) {
408-
entity.items = [];
409-
foreach (var (module, count, beacon) in modules) {
410-
if (!beacon) {
411-
entity.items[module.name] = count;
413+
var modules = recipe.parameters.modules.modules;
414+
if (modules != null) {
415+
entity.items = [];
416+
foreach (var (module, count, beacon) in modules) {
417+
if (!beacon) {
418+
entity.items[module.name] = count;
419+
}
420+
}
412421
}
422+
BlueprintString bp = new BlueprintString(recipe.recipe.locName) { blueprint = { entities = { entity } } };
423+
_ = SDL.SDL_SetClipboardText(bp.ToBpString());
413424
}
414425
}
415-
BlueprintString bp = new BlueprintString(recipe.recipe.locName) { blueprint = { entities = { entity } } };
416-
_ = SDL.SDL_SetClipboardText(bp.ToBpString());
417-
}
418426

419-
if (recipe.recipe.crafters.Length > 1) {
420-
BuildFavorites(gui, recipe.entity, "Add building to favorites");
427+
if (recipe.recipe.crafters.Length > 1) {
428+
BuildFavorites(gui, recipe.entity, "Add building to favorites");
429+
}
421430
}
422431
});
423432

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Date:
1616
Features:
1717
- Autofocus the project name field when you create a new project
1818
- When opening the main window, use the same column widths as when it was last closed.
19+
- Add explanatory tips for the buttons in the building dropdown.
1920
Bugfixes:
2021
- Sometimes, deleting and/or right-click resetting modules would not work.
2122
----------------------------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)