Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add building count tooltips 101 #213

Merged
merged 2 commits into from
Jul 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Yafc.UI/Core/Rect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,6 @@ public override int GetHashCode() {
public readonly Rect Expand(float amount) => new Rect(X - amount, Y - amount, Width + (2 * amount), Height + (2 * amount));

public static Rect Square(Vector2 center, float side) => new Rect(center.X - (side * 0.5f), center.Y - (side * 0.5f), side, side);
public static Rect Square(float centerX, float centerY, float side) => new Rect(centerX - (side * 0.5f), centerY - (side * 0.5f), side, side);
}
}
46 changes: 46 additions & 0 deletions Yafc.UI/ImGui/ImGuiUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -382,5 +382,51 @@ public static bool CloseDropdown(this ImGui gui) {
gui.PropagateMessage<CloseDropdownEvent>(default);
return true;
}

/// <summary>
/// Draws a row with a (?) help icon at its right side, and a tooltip when the user hovers over the icon.
/// </summary>
/// <param name="tooltip">The tooltip that should be displayed when the user hovers over the (?) icon.</param>
/// <param name="rightJustify">If <see langword="true"/>, the default, the help icon will be as far right as possible.
/// If false, it will be still be drawn at the right end of the row, but as far left as possible.</param>
public static IDisposable EnterRowWithHelpIcon(this ImGui gui, string tooltip, bool rightJustify = true) => new RowWithHelpIcon(gui, tooltip, rightJustify);

/// <summary>
/// The class that sets up and stores the state needed to build a row with a help icon.
/// </summary>
private sealed class RowWithHelpIcon : IDisposable {
private readonly ImGui gui;
private readonly string tooltip;
private readonly ImGui.Context row;
private readonly float helpCenterX;
private readonly ImGui.Context group;

public RowWithHelpIcon(ImGui gui, string tooltip, bool rightJustify) {
this.gui = gui;
this.tooltip = tooltip;
row = gui.EnterRow(); // using (gui.EnterRow()) {
if (rightJustify) {
gui.allocator = RectAllocator.RightRow;
helpCenterX = gui.AllocateRect(1, 1).Center.X;
group = gui.EnterGroup(new Padding(), RectAllocator.RemainingRow); // using (gui.EnterGroup(...)) { // Required to produce the expected spacing/padding behavior.
gui.allocator = RectAllocator.LeftRow;
}
}

public void Dispose() {
Rect rect;
if (helpCenterX != 0) { // if (rightJustify)
group.Dispose(); // end using block for EnterGroup
rect = Rect.Square(helpCenterX, gui.lastRect.Center.Y, 1.25f);
}
else {
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.
rect = Rect.Square(rect.Center, 1.25f); // Get a vertically-centered rect that's actually 1.25 x 1.25.
}
gui.DrawIcon(rect, Icon.Help, SchemeColor.BackgroundText);
gui.BuildButton(rect, SchemeColor.None, SchemeColor.Grey).WithTooltip(gui, tooltip, rect);
row.Dispose(); // end using block for EnterRow
}
}
}
}
2 changes: 1 addition & 1 deletion Yafc/Widgets/ImmediateWidgets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public static bool BuildInlineObjectList<T>(this ImGui gui, IEnumerable<T> list,
}

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

Expand Down
41 changes: 14 additions & 27 deletions Yafc/Windows/PreferencesScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,21 @@ public override void Build(ImGui gui) {
gui.BuildText("Fluid production/consumption:", Font.subheader);
BuildUnitPerTime(gui, true, prefs);

drawInputRowWithTooltip(gui, "Pollution cost modifier", "0 for off, 100% for old default",
gui => {
if (gui.BuildFloatInput(settings.PollutionCostModifier, out float pollutionCostModifier, UnitOfMeasure.Percent, new Padding(0.5f))) {
settings.RecordUndo().PollutionCostModifier = pollutionCostModifier;
gui.Rebuild();
}
});
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;
gui.Rebuild();
}
}

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.",
gui => {
if (gui.BuildFloatInput(prefs.iconScale, out float iconScale, UnitOfMeasure.Percent, new Padding(0.5f)) && iconScale > 0 && iconScale <= 1) {
prefs.RecordUndo().iconScale = iconScale;
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;
gui.Rebuild();
}
}

ChooseObject(gui, "Default belt:", Database.allBelts, prefs.defaultBelt, s => {
prefs.RecordUndo().defaultBelt = s;
Expand Down Expand Up @@ -100,19 +100,6 @@ public override void Build(ImGui gui) {
if (settings.justChanged) {
Project.current.RecalculateDisplayPages();
}

static void drawInputRowWithTooltip(ImGui gui, string text, string tooltip, Action<ImGui> handleInput) {
using (gui.EnterRow()) {
gui.BuildText(text, topOffset: 0.5f);
gui.AllocateSpacing();
gui.allocator = RectAllocator.RightRow;
var rect = gui.AllocateRect(1, 1);
handleInput(gui);
rect = new Rect(rect.Center.X, gui.lastRect.Center.Y, 0, 0).Expand(.625f);
gui.DrawIcon(rect, Icon.Help, SchemeColor.BackgroundText);
gui.BuildButton(rect, SchemeColor.None, SchemeColor.Grey).WithTooltip(gui, tooltip, rect);
}
}
}

protected override void ReturnPressed() => Close();
Expand Down
5 changes: 4 additions & 1 deletion Yafc/Windows/WelcomeScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ protected override void BuildContents(ImGui gui) {
gui.BuildText("In-game objects language:");
}

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

Expand Down
81 changes: 45 additions & 36 deletions Yafc/Workspace/ProductionTable/ProductionTableView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -367,57 +367,66 @@ private static void ShowEntityDropdown(ImGui imgui, RecipeRow recipe) => imgui.S
}
}, "Select crafting entity", extra: x => DataUtils.FormatAmount(x.craftingSpeed, UnitOfMeasure.Percent));

if (recipe.fixedBuildings > 0f) {
ButtonEvent evt = gui.BuildButton("Clear fixed building count");
if (willResetFixed) {
evt.WithTooltip(gui, "Shortcut: right-click");
}
if (evt && gui.CloseDropdown()) {
recipe.RecordUndo().fixedBuildings = 0f;
gui.AllocateSpacing(0.5f);

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?'")) {
gui.allocator = RectAllocator.RemainingRow;
if (recipe.fixedBuildings > 0f) {
ButtonEvent evt = gui.BuildButton("Clear fixed building count");
if (willResetFixed) {
evt.WithTooltip(gui, "Shortcut: right-click");
}
if (evt && gui.CloseDropdown()) {
recipe.RecordUndo().fixedBuildings = 0f;
}
}
}
else {
if (gui.BuildButton("Set fixed building count") && gui.CloseDropdown()) {
else if (gui.BuildButton("Set fixed building count") && gui.CloseDropdown()) {
recipe.RecordUndo().fixedBuildings = recipe.buildingCount <= 0f ? 1f : recipe.buildingCount;
}
}

if (recipe.builtBuildings != null) {
ButtonEvent evt = gui.BuildButton("Clear built building count");
if (willResetBuilt) {
evt.WithTooltip(gui, "Shortcut: right-click");
}
if (evt && gui.CloseDropdown()) {
recipe.RecordUndo().builtBuildings = null;
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.")) {
gui.allocator = RectAllocator.RemainingRow;
if (recipe.builtBuildings != null) {
ButtonEvent evt = gui.BuildButton("Clear built building count");
if (willResetBuilt) {
evt.WithTooltip(gui, "Shortcut: right-click");
}
if (evt && gui.CloseDropdown()) {
recipe.RecordUndo().builtBuildings = null;
}
}
}
else {
if (gui.BuildButton("Set built building count") && gui.CloseDropdown()) {
else if (gui.BuildButton("Set built building count") && gui.CloseDropdown()) {
recipe.RecordUndo().builtBuildings = Math.Max(0, Convert.ToInt32(Math.Ceiling(recipe.buildingCount)));
}
}

if (recipe.entity != null && gui.BuildButton("Create single building blueprint") && gui.CloseDropdown()) {
BlueprintEntity entity = new BlueprintEntity { index = 1, name = recipe.entity.name };
if (recipe.recipe is not Mechanics) {
entity.recipe = recipe.recipe.name;
}
if (recipe.entity != null) {
using (gui.EnterRowWithHelpIcon("Generate a blueprint for one of these buildings, with the recipe and internal modules set.")) {
gui.allocator = RectAllocator.RemainingRow;
if (gui.BuildButton("Create single building blueprint") && gui.CloseDropdown()) {
BlueprintEntity entity = new BlueprintEntity { index = 1, name = recipe.entity.name };
if (recipe.recipe is not Mechanics) {
entity.recipe = recipe.recipe.name;
}

var modules = recipe.parameters.modules.modules;
if (modules != null) {
entity.items = [];
foreach (var (module, count, beacon) in modules) {
if (!beacon) {
entity.items[module.name] = count;
var modules = recipe.parameters.modules.modules;
if (modules != null) {
entity.items = [];
foreach (var (module, count, beacon) in modules) {
if (!beacon) {
entity.items[module.name] = count;
}
}
}
BlueprintString bp = new BlueprintString(recipe.recipe.locName) { blueprint = { entities = { entity } } };
_ = SDL.SDL_SetClipboardText(bp.ToBpString());
}
}
BlueprintString bp = new BlueprintString(recipe.recipe.locName) { blueprint = { entities = { entity } } };
_ = SDL.SDL_SetClipboardText(bp.ToBpString());
}

if (recipe.recipe.crafters.Length > 1) {
BuildFavorites(gui, recipe.entity, "Add building to favorites");
if (recipe.recipe.crafters.Length > 1) {
BuildFavorites(gui, recipe.entity, "Add building to favorites");
}
}
});

Expand Down
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Date:
Features:
- Autofocus the project name field when you create a new project
- When opening the main window, use the same column widths as when it was last closed.
- Add explanatory tips for the buttons in the building dropdown.
Bugfixes:
- Sometimes, deleting and/or right-click resetting modules would not work.
----------------------------------------------------------------------------------------------------------------------
Expand Down