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

Use all available width, and sometimes multiple lines, for milestones in the tooltip header. #357

Merged
merged 2 commits into from
Nov 19, 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
3 changes: 3 additions & 0 deletions Yafc.Model/Math/Bits.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Numerics;

namespace Yafc.Model;
Expand Down Expand Up @@ -333,4 +334,6 @@ public override readonly string ToString() {

return bitsString.ToString();
}

public readonly int PopCount() => data?.Sum(BitOperations.PopCount) ?? 0;
}
2 changes: 2 additions & 0 deletions Yafc.Model/Model/Project.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ public class ProjectPreferences(Project owner) : ModelObject<Project>(owner) {
/// The scale to use when drawing icons that have information stored in their background color, stored as a ratio from 0 to 1.
/// </summary>
public float iconScale { get; set; } = .9f;
/// <summary>The maximum number of milestone icons in each line when drawing tooltip headers.</summary>
public int maxMilestonesPerTooltipLine { get; set; } = 28;
public bool showMilestoneOnInaccessible { get; set; } = true;

protected internal override void AfterDeserialize() {
Expand Down
40 changes: 32 additions & 8 deletions Yafc/Widgets/ObjectTooltip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,43 @@ private void BuildHeader(ImGui gui) {
gui.BuildText(name, new TextBlockDisplayStyle(Font.header, true));
var milestoneMask = Milestones.Instance.GetMilestoneResult(target.target);
if (milestoneMask.HighestBitSet() > 0 && (target.target.IsAccessible() || Project.current.preferences.showMilestoneOnInaccessible)) {
float spacing = MathF.Min((22f / Milestones.Instance.currentMilestones.Length) - 1f, 0f);
using (gui.EnterRow(spacing)) {
int maskBit = 1;
foreach (var milestone in Milestones.Instance.currentMilestones) {
if (milestoneMask[maskBit]) {
gui.BuildIcon(milestone.icon, 1f, SchemeColor.Source);
}
int milestoneCount = milestoneMask.PopCount();
if (milestoneMask[0]) {
milestoneCount--; // Bit 0 is accessibility, not a milestone flag.
}

maskBit++;
// All rows except the last will show at least 22 milestones.
// If displaying more items per row (up to the user's limit) reduces the number of rows, squish the milestones together slightly.
int maxItemsPerRow = Project.current.preferences.maxMilestonesPerTooltipLine;
const int minItemsPerRow = 22;
int rows = (milestoneCount + maxItemsPerRow - 1) / maxItemsPerRow;
int itemsPerRow = Math.Max((milestoneCount + rows - 1) / rows, minItemsPerRow);
// 22.5 is the width of the available area of the tooltip. The original code used spacings from -1 (100% overlap) to 0
// (no overlap). At the default max of 28 per row, we allow spacings of -0.196 (19.6% overlap) to 0.023 (2.3% stretch).
float spacing = 22.5f / itemsPerRow - 1f;

using var milestones = Milestones.Instance.currentMilestones.AsEnumerable().GetEnumerator();
int maskBit = 1;
for (int i = 0; i < rows; i++) {
using (gui.EnterRow(spacing)) {
// Draw itemsPerRow items, then exit this row and allocate a new one
for (int j = 0; j < itemsPerRow; /* increment after drawing a milestone */) {
if (!milestones.MoveNext()) {
goto doneDrawing;
}
if (milestoneMask[maskBit]) {
gui.BuildIcon(milestones.Current.icon, 1f, SchemeColor.Source);
j++;
}

maskBit++;
}
}
}
doneDrawing:;
}
}

if (gui.isBuilding) {
gui.DrawRectangle(gui.lastRect, SchemeColor.Primary);
}
Expand Down
14 changes: 14 additions & 0 deletions Yafc/Windows/PreferencesScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,20 @@ private static void DrawGeneral(ImGui gui) {
}
}

// Don't show this preference if it isn't relevant.
// (Takes ~3ms for pY, which would concern me in the regular UI, but should be fine here.)
if (Database.objects.all.Any(o => Milestones.Instance.GetMilestoneResult(o).PopCount() > 22)) {
string overlapMessage = "Some tooltips may want to show multiple rows of milestones. Increasing this number will draw fewer lines in some tooltips, by forcing the milestones to overlap.\n\n"
+ "Minimum: 22\nDefault: 28";
using (gui.EnterRowWithHelpIcon(overlapMessage)) {
gui.BuildText("Maximum milestones per line in tooltips:", topOffset: 0.5f);
if (gui.BuildIntegerInput(preferences.maxMilestonesPerTooltipLine, out int newIntValue) && newIntValue >= 22) {
preferences.RecordUndo().maxMilestonesPerTooltipLine = newIntValue;
gui.Rebuild();
}
}
}

using (gui.EnterRow()) {
gui.BuildText("Reactor layout:", topOffset: 0.5f);
if (gui.BuildTextInput(settings.reactorSizeX + "x" + settings.reactorSizeY, out string newSize, null, delayed: true)) {
Expand Down
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Date:
- Add dependency information for tree and resource spawns, fluid pumping, and asteroid mining.
- (SA) Locations (except nauvis) are now part of the default milestone list.
- Milestone overlays can be displayed on inaccessible objects.
- With 22+ milestones, tooltip headers don't draw them unnecessarily overlapped, and can use multiple lines.
Internal changes:
- Dependency and automation analysis allows more ORs, e.g. "(spawner and capture-ammo) or item-to-place".
----------------------------------------------------------------------------------------------------------------------
Expand Down