Skip to content

Commit 412f62c

Browse files
committed
Add IconDisplayStyles and ButtonDisplayStyles for FactorioObjectIcons and Buttons.
1 parent 9e4216c commit 412f62c

18 files changed

+166
-71
lines changed

Yafc/Utils/ObjectDisplayStyles.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
namespace Yafc.UI;
2+
3+
/// <summary>
4+
/// Contains the display parameters for FactorioObjectIcons.
5+
/// </summary>
6+
/// <param name="Size">The icon size. The production tables use size 3.</param>
7+
/// <param name="MilestoneDisplay">The <see cref="Yafc.MilestoneDisplay"/> option to use when drawing the icon.</param>
8+
/// <param name="UseScaleSetting">Whether or not to obey the <see cref="Model.ProjectPreferences.iconScale"/> setting.</param>
9+
public record IconDisplayStyle(float Size, MilestoneDisplay MilestoneDisplay, bool UseScaleSetting) {
10+
/// <summary>
11+
/// Gets the default icon style: Size 2, <see cref="MilestoneDisplay.Normal"/>, and not scaled.
12+
/// </summary>
13+
public static IconDisplayStyle Default { get; } = new(2, MilestoneDisplay.Normal, false);
14+
}
15+
16+
/// <summary>
17+
/// Contains the display parameters for FactorioObjectButtons. Buttons with a background color draw a scaled icon
18+
/// (<c><see cref="IconDisplayStyle.UseScaleSetting"/> = <see langword="true"/></c>) by default.
19+
/// </summary>
20+
/// <param name="Size">The icon size. The production tables use size 3.</param>
21+
/// <param name="MilestoneDisplay">The <see cref="MilestoneDisplay"/> option to use when drawing the icon.</param>
22+
/// <param name="BackgroundColor">The background color to display behind the icon.</param>
23+
public record ButtonDisplayStyle(float Size, MilestoneDisplay MilestoneDisplay, SchemeColor BackgroundColor) : IconDisplayStyle(Size, MilestoneDisplay, true) {
24+
/// <summary>
25+
/// Creates a new <see cref="ButtonDisplayStyle"/> for buttons that do not have a background color. These buttons will not obey the <see cref="Model.ProjectPreferences.iconScale"/> setting.
26+
/// </summary>
27+
/// <param name="size">The icon size. The production tables use size 3.</param>
28+
/// <param name="milestoneDisplay">The <see cref="MilestoneDisplay"/> option to use when drawing the icon.</param>
29+
public ButtonDisplayStyle(float size, MilestoneDisplay milestoneDisplay) : this(size, milestoneDisplay, SchemeColor.None) => UseScaleSetting = false;
30+
31+
/// <summary>
32+
/// Gets the default button style: Size 2, <see cref="MilestoneDisplay.Normal"/>, no background, and not scaled.
33+
/// </summary>
34+
public static new ButtonDisplayStyle Default { get; } = new(2, MilestoneDisplay.Normal);
35+
/// <summary>
36+
/// Gets the button style for the <see cref="SelectObjectPanel{T}"/>s: Size 2.5, <see cref="MilestoneDisplay.Contained"/>, and scaled.
37+
/// </summary>
38+
/// <param name="backgroundColor">The background color to use for this button.</param>
39+
public static ButtonDisplayStyle SelectObjectPanel(SchemeColor backgroundColor) => new(2.5f, MilestoneDisplay.Contained, backgroundColor);
40+
/// <summary>
41+
/// Gets the button style for production table buttons with a background: Size 2.5, <see cref="MilestoneDisplay.Contained"/>, and scaled.
42+
/// </summary>
43+
/// <param name="backgroundColor">The background color to use for this button.</param>
44+
public static ButtonDisplayStyle ProductionTableScaled(SchemeColor backgroundColor) => new(3, MilestoneDisplay.Contained, backgroundColor);
45+
/// <summary>
46+
/// Gets the button style for production table buttons with no background: Size 2.5, <see cref="MilestoneDisplay.Contained"/>, and not scaled.
47+
/// </summary>
48+
public static ButtonDisplayStyle ProductionTableUnscaled { get; } = new(3, MilestoneDisplay.Contained);
49+
/// <summary>
50+
/// Gets the button style for small buttons in the Never Enough Items Explorer: Size 3, <see cref="MilestoneDisplay.Contained"/>, and not scaled.
51+
/// </summary>
52+
public static ButtonDisplayStyle NeieSmall { get; } = new(3, MilestoneDisplay.Contained);
53+
/// <summary>
54+
/// Gets the button style for large buttons in the Never Enough Items Explorer: Size 4, <see cref="MilestoneDisplay.Contained"/>, and not scaled.
55+
/// </summary>
56+
public static ButtonDisplayStyle NeieLarge { get; } = new(4, MilestoneDisplay.Contained);
57+
/// <summary>
58+
/// Gets the button style for the Milestones display buttons: Size 3, <see cref="MilestoneDisplay.None"/>, and scaled.
59+
/// </summary>
60+
/// <param name="backgroundColor">The background color to use for this button.</param>
61+
public static ButtonDisplayStyle Milestone(SchemeColor backgroundColor) => new(3, MilestoneDisplay.None, backgroundColor);
62+
}

Yafc/Widgets/ImmediateWidgets.cs

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,40 @@
88
using Yafc.UI;
99

1010
namespace Yafc {
11+
12+
// Contained draws the milestone like this
13+
// +----+
14+
// | |
15+
// | +-+
16+
// | | |
17+
// +--+-+
18+
// Normal draws the milestone like this
19+
// +----+
20+
// | |
21+
// | |
22+
// | +-+
23+
// +---| |
24+
// +-+
1125
public enum MilestoneDisplay {
26+
/// <summary>
27+
/// Draw the highest locked milestone centered on the lower-right corner of the base icon.
28+
/// </summary>
1229
Normal,
30+
/// <summary>
31+
/// Draw the highest locked milestone with its lower-right corner aligned with the lower-right corner of the base icon.
32+
/// </summary>
1333
Contained,
14-
All,
15-
AllContained,
34+
/// <summary>
35+
/// Draw the highest milestone, regardless of (un)lock state, centered on the lower-right corner of the base icon.
36+
/// </summary>
37+
Always,
38+
/// <summary>
39+
/// Draw the highest milestone, regardless of (un)lock state, with its lower-right corner aligned with the lower-right corner of the base icon.
40+
/// </summary>
41+
ContainedAlways,
42+
/// <summary>
43+
/// Do not draw a milestone icon.
44+
/// </summary>
1645
None
1746
}
1847

@@ -32,26 +61,26 @@ public enum Click {
3261
public static class ImmediateWidgets {
3362
/// <summary>Draws the icon belonging to a <see cref="FactorioObject"/>, or an empty box as a placeholder if no object is available.</summary>
3463
/// <param name="obj">Draw the icon for this object, or an empty box if this is <see langword="null"/>.</param>
35-
/// <param name="useScale">If <see langword="true"/>, this icon will be displayed at <see cref="ProjectPreferences.iconScale"/>, instead of at 100% scale.</param>
36-
public static void BuildFactorioObjectIcon(this ImGui gui, FactorioObject? obj, MilestoneDisplay display = MilestoneDisplay.Normal, float size = 2f, bool useScale = false) {
64+
public static void BuildFactorioObjectIcon(this ImGui gui, FactorioObject? obj, IconDisplayStyle? displayStyle = null) {
65+
displayStyle ??= IconDisplayStyle.Default;
3766
if (obj == null) {
38-
gui.BuildIcon(Icon.Empty, size, SchemeColor.BackgroundTextFaint);
67+
gui.BuildIcon(Icon.Empty, displayStyle.Size, SchemeColor.BackgroundTextFaint);
3968
return;
4069
}
4170

4271
var color = obj.IsAccessible() ? SchemeColor.Source : SchemeColor.SourceFaint;
43-
if (useScale) {
44-
Rect rect = gui.AllocateRect(size, size, RectAlignment.Middle);
45-
gui.DrawIcon(rect.Expand(size * (Project.current.preferences.iconScale - 1) / 2), obj.icon, color);
72+
if (displayStyle.UseScaleSetting) {
73+
Rect rect = gui.AllocateRect(displayStyle.Size, displayStyle.Size, RectAlignment.Middle);
74+
gui.DrawIcon(rect.Expand(displayStyle.Size * (Project.current.preferences.iconScale - 1) / 2), obj.icon, color);
4675
}
4776
else {
48-
gui.BuildIcon(obj.icon, size, color);
77+
gui.BuildIcon(obj.icon, displayStyle.Size, color);
4978
}
50-
if (gui.isBuilding && display != MilestoneDisplay.None) {
51-
bool contain = (display & MilestoneDisplay.Contained) != 0;
52-
var milestone = Milestones.Instance.GetHighest(obj, display >= MilestoneDisplay.All);
79+
if (gui.isBuilding && displayStyle.MilestoneDisplay != MilestoneDisplay.None) {
80+
bool contain = (displayStyle.MilestoneDisplay & MilestoneDisplay.Contained) != 0;
81+
FactorioObject? milestone = Milestones.Instance.GetHighest(obj, displayStyle.MilestoneDisplay >= MilestoneDisplay.Always);
5382
if (milestone != null) {
54-
Vector2 psize = new Vector2(size / 2f);
83+
Vector2 psize = new Vector2(displayStyle.Size / 2f);
5584
var delta = contain ? psize : psize / 2f;
5685
Rect milestoneIcon = new Rect(gui.lastRect.BottomRight - delta, psize);
5786
var icon = milestone == Database.voidEnergy ? DataUtils.HandIcon : milestone.icon;
@@ -70,7 +99,7 @@ public static bool BuildFloatInput(this ImGui gui, DisplayAmount amount, TextBox
7099
return false;
71100
}
72101

73-
public static Click BuildFactorioObjectButton(this ImGui gui, Rect rect, FactorioObject? obj, SchemeColor bgColor = SchemeColor.None, ObjectTooltipOptions tooltipOptions = default) {
102+
public static Click BuildFactorioObjectButtonBackground(this ImGui gui, Rect rect, FactorioObject? obj, SchemeColor bgColor = SchemeColor.None, ObjectTooltipOptions tooltipOptions = default) {
74103
SchemeColor overColor;
75104
if (bgColor == SchemeColor.None) {
76105
overColor = SchemeColor.Grey;
@@ -109,15 +138,15 @@ public static Click BuildFactorioObjectButton(this ImGui gui, Rect rect, Factori
109138

110139
/// <summary>Draws a button displaying the icon belonging to a <see cref="FactorioObject"/>, or an empty box as a placeholder if no object is available.</summary>
111140
/// <param name="obj">Draw the icon for this object, or an empty box if this is <see langword="null"/>.</param>
112-
/// <param name="useScale">If <see langword="true"/>, this icon will be displayed at <see cref="ProjectPreferences.iconScale"/>, instead of at 100% scale.</param>
113-
public static Click BuildFactorioObjectButton(this ImGui gui, FactorioObject? obj, float size = 2f, MilestoneDisplay display = MilestoneDisplay.Normal, SchemeColor bgColor = SchemeColor.None, bool useScale = false, ObjectTooltipOptions tooltipOptions = default) {
114-
gui.BuildFactorioObjectIcon(obj, display, size, useScale);
115-
return gui.BuildFactorioObjectButton(gui.lastRect, obj, bgColor, tooltipOptions);
141+
public static Click BuildFactorioObjectButton(this ImGui gui, FactorioObject? obj, ButtonDisplayStyle displayStyle, ObjectTooltipOptions tooltipOptions = default) {
142+
gui.BuildFactorioObjectIcon(obj, displayStyle);
143+
return gui.BuildFactorioObjectButtonBackground(gui.lastRect, obj, displayStyle.BackgroundColor, tooltipOptions);
116144
}
117145

118-
public static Click BuildFactorioObjectButtonWithText(this ImGui gui, FactorioObject? obj, string? extraText = null, float size = 2f, MilestoneDisplay display = MilestoneDisplay.Normal) {
146+
public static Click BuildFactorioObjectButtonWithText(this ImGui gui, FactorioObject? obj, string? extraText = null, IconDisplayStyle? iconDisplayStyle = null) {
147+
iconDisplayStyle ??= IconDisplayStyle.Default;
119148
using (gui.EnterRow()) {
120-
gui.BuildFactorioObjectIcon(obj, display, size);
149+
gui.BuildFactorioObjectIcon(obj, iconDisplayStyle);
121150
var color = gui.textColor;
122151
if (obj != null && !obj.IsAccessible()) {
123152
color += 1;
@@ -136,7 +165,7 @@ public static Click BuildFactorioObjectButtonWithText(this ImGui gui, FactorioOb
136165
gui.BuildText(obj == null ? "None" : obj.locName, TextBlockDisplayStyle.WrappedText with { Color = color });
137166
}
138167

139-
return gui.BuildFactorioObjectButton(gui.lastRect, obj);
168+
return gui.BuildFactorioObjectButtonBackground(gui.lastRect, obj);
140169
}
141170

142171
public static bool BuildInlineObjectList<T>(this ImGui gui, IEnumerable<T> list, IComparer<T> ordering, string header, [NotNullWhen(true)] out T? selected, int maxCount = 10,
@@ -205,12 +234,12 @@ public static void BuildInlineObjectListAndButtonWithNone<T>(this ImGui gui, ICo
205234
/// <param name="goods">Draw the icon for this object, or an empty box if this is <see langword="null"/>.</param>
206235
/// <param name="amount">Display this value and unit.</param>
207236
/// <param name="useScale">If <see langword="true"/>, this icon will be displayed at <see cref="ProjectPreferences.iconScale"/>, instead of at 100% scale.</param>
208-
public static Click BuildFactorioObjectWithAmount(this ImGui gui, FactorioObject? goods, DisplayAmount amount, SchemeColor bgColor = SchemeColor.None, TextBlockDisplayStyle? textDisplayStyle = null, bool useScale = true, ObjectTooltipOptions tooltipOptions = default) {
237+
public static Click BuildFactorioObjectWithAmount(this ImGui gui, FactorioObject? goods, DisplayAmount amount, ButtonDisplayStyle buttonDisplayStyle, TextBlockDisplayStyle? textDisplayStyle = null, ObjectTooltipOptions tooltipOptions = default) {
209238
textDisplayStyle ??= new(Alignment: RectAlignment.Middle);
210239
using (gui.EnterFixedPositioning(3f, 3f, default)) {
211240
gui.allocator = RectAllocator.Stretch;
212241
gui.spacing = 0f;
213-
Click clicked = gui.BuildFactorioObjectButton(goods, 3f, MilestoneDisplay.Contained, bgColor, useScale, tooltipOptions);
242+
Click clicked = gui.BuildFactorioObjectButton(goods, buttonDisplayStyle, tooltipOptions);
214243
if (goods != null) {
215244
gui.BuildText(DataUtils.FormatAmount(amount.Value, amount.Unit), textDisplayStyle);
216245
if (InputSystem.Instance.control && gui.BuildButton(gui.lastRect, SchemeColor.None, SchemeColor.Grey) == ButtonEvent.MouseOver) {
@@ -265,10 +294,10 @@ public static void BuildObjectSelectDropDownWithNone<T>(this ImGui gui, ICollect
265294
/// <param name="amount">Display this value and unit. If the user edits the value, the new value will be stored in <see cref="DisplayAmount.Value"/> before returning.</param>
266295
/// <param name="allowScroll">If <see langword="true"/>, the default, the user can adjust the value by using the scroll wheel while hovering over the editable text.
267296
/// If <see langword="false"/>, the scroll wheel will be ignored when hovering.</param>
268-
public static GoodsWithAmountEvent BuildFactorioObjectWithEditableAmount(this ImGui gui, FactorioObject? obj, DisplayAmount amount, SchemeColor color = SchemeColor.None, bool useScale = true, bool allowScroll = true, ObjectTooltipOptions tooltipOptions = default) {
297+
public static GoodsWithAmountEvent BuildFactorioObjectWithEditableAmount(this ImGui gui, FactorioObject? obj, DisplayAmount amount, ButtonDisplayStyle buttonDisplayStyle, bool allowScroll = true, ObjectTooltipOptions tooltipOptions = default) {
269298
using var group = gui.EnterGroup(default, RectAllocator.Stretch, spacing: 0f);
270299
group.SetWidth(3f);
271-
GoodsWithAmountEvent evt = (GoodsWithAmountEvent)gui.BuildFactorioObjectButton(obj, 3f, MilestoneDisplay.Contained, color, useScale, tooltipOptions);
300+
GoodsWithAmountEvent evt = (GoodsWithAmountEvent)gui.BuildFactorioObjectButton(obj, buttonDisplayStyle, tooltipOptions);
272301

273302
if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.FactorioObjectInput)) {
274303
return GoodsWithAmountEvent.TextEditing;

Yafc/Widgets/ObjectTooltip.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ private void BuildTechnology(Technology technology, ImGui gui) {
520520
using var grid = gui.EnterInlineGrid(3f);
521521
foreach (var pack in packs) {
522522
grid.Next();
523-
_ = gui.BuildFactorioObjectWithAmount(pack.goods, pack.amount);
523+
_ = gui.BuildFactorioObjectWithAmount(pack.goods, pack.amount, ButtonDisplayStyle.ProductionTableUnscaled);
524524
}
525525
}
526526
}

Yafc/Windows/DependencyExplorer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ private void DrawFactorioObject(ImGui gui, FactorioId id) {
4545
string text = fobj.locName + " (" + fobj.type + ")";
4646
gui.RemainingRow(0.5f).BuildText(text, TextBlockDisplayStyle.WrappedText with { Color = fobj.IsAccessible() ? SchemeColor.BackgroundText : SchemeColor.BackgroundTextFaint });
4747
}
48-
if (gui.BuildFactorioObjectButton(gui.lastRect, fobj, tooltipOptions: new() { ExtendHeader = true }) == Click.Left) {
48+
if (gui.BuildFactorioObjectButtonBackground(gui.lastRect, fobj, tooltipOptions: new() { ExtendHeader = true }) == Click.Left) {
4949
Change(fobj);
5050
}
5151
}

Yafc/Windows/MilestonesEditor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ protected override void Close(bool save = true) {
2626
private void MilestoneDrawer(ImGui gui, FactorioObject element, int index) {
2727
using (gui.EnterRow()) {
2828
var settings = Project.current.settings;
29-
gui.BuildFactorioObjectIcon(element, MilestoneDisplay.None, 3f);
29+
gui.BuildFactorioObjectIcon(element, new IconDisplayStyle(3f, MilestoneDisplay.None, false));
3030
gui.BuildText(element.locName, maxWidth: width - 16.6f); // Experimentally determined width of the non-text parts of the editor.
3131
if (gui.BuildButton(Icon.Close, size: 1f)) {
3232
_ = settings.RecordUndo().milestones.Remove(element);

Yafc/Windows/MilestonesPanel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public class MilestonesWidget : VirtualScrollList<FactorioObject> {
99
private static void MilestoneDrawer(ImGui gui, FactorioObject element, int index) {
1010
var settings = Project.current.settings;
1111
bool unlocked = settings.Flags(element).HasFlags(ProjectPerItemFlags.MilestoneUnlocked);
12-
if (gui.BuildFactorioObjectButton(element, 3f, display: MilestoneDisplay.None, bgColor: unlocked ? SchemeColor.Primary : SchemeColor.None) == Click.Left) {
12+
if (gui.BuildFactorioObjectButton(element, ButtonDisplayStyle.Milestone(unlocked ? SchemeColor.Primary : SchemeColor.None)) == Click.Left) {
1313
if (!unlocked) {
1414
var massUnlock = Milestones.Instance.GetMilestoneResult(element);
1515
int subIndex = 0;

0 commit comments

Comments
 (0)