Skip to content

Commit

Permalink
Use all available width, and sometimes multiple lines, for milestones…
Browse files Browse the repository at this point in the history
… in the tooltip header. (#357)

I added one or two (dozen) extra milestones, and decided I'd rather see
the second version of this tooltip:

![image](https://github.com/user-attachments/assets/73d24edc-b015-4ce6-9037-f13acc8a9e41)

When it comes to Promethium science pack, there's a preference that
allows you to set which of these you see. (It also lets you pick one or
two lines for Assembly machine 3.) Because I felt like it, that
preference isn't shown unless changing it can change what you see
(meaning you have objects with at least 23 milestones.) The default
value of the preference shows the bottom option in both images.

![image](https://github.com/user-attachments/assets/f369aa6f-ba48-4603-911f-d7df6d1e1068)
  • Loading branch information
shpaass authored Nov 19, 2024
2 parents 6b0561f + fa3f9fe commit d75ff3d
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 8 deletions.
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

0 comments on commit d75ff3d

Please sign in to comment.