style(wizard): reflow FirstRunWizard and WizardStateSmokeStep to csharpier

Preflight Block E (`dotnet csharpier check`) flagged two reflows
in the v1.5.2 code: the ForgeBronzeDim Vector4 constant needed
multi-line form, and a handful of switch arms / long Plugin.Config
chains in WizardStateSmokeStep needed line-breaks at csharpier's
print-width. Pure formatting — zero functional change. Block D
build stays clean, Block E now passes.
This commit is contained in:
2026-05-18 23:46:00 +02:00
parent 271a6ae650
commit 35efdd4628
2 changed files with 188 additions and 59 deletions
@@ -72,7 +72,9 @@ internal sealed class WizardStateSmokeStep : ISelfTestStep
// restore them after the assert. Keeps /xlperf idempotent. // restore them after the assert. Keeps /xlperf idempotent.
this.snapshotPrivacyFilterEnabled = Plugin.Config.PrivacyFilterEnabled; this.snapshotPrivacyFilterEnabled = Plugin.Config.PrivacyFilterEnabled;
this.snapshotPrivacyPersistChannels = Plugin.Config.PrivacyPersistChannels; this.snapshotPrivacyPersistChannels = Plugin.Config.PrivacyPersistChannels;
this.snapshotPrivacyPersistUnknownChannels = Plugin.Config.PrivacyPersistUnknownChannels; this.snapshotPrivacyPersistUnknownChannels = Plugin
.Config
.PrivacyPersistUnknownChannels;
this.snapshotRetentionEnabled = Plugin.Config.RetentionEnabled; this.snapshotRetentionEnabled = Plugin.Config.RetentionEnabled;
this.snapshotRetentionDefaultDays = Plugin.Config.RetentionDefaultDays; this.snapshotRetentionDefaultDays = Plugin.Config.RetentionDefaultDays;
this.snapshotRetentionPerChannelDays = Plugin.Config.RetentionPerChannelDays; this.snapshotRetentionPerChannelDays = Plugin.Config.RetentionPerChannelDays;
+185 -58
View File
@@ -24,7 +24,12 @@ public sealed class FirstRunWizard : Window
// and the forge-announce workflow; pinning it locally keeps the // and the forge-announce workflow; pinning it locally keeps the
// wizard render path free of registry lookups during draw. // wizard render path free of registry lookups during draw.
private static readonly Vector4 ForgeBronze = new(0xC2 / 255f, 0x41 / 255f, 0x0C / 255f, 1f); private static readonly Vector4 ForgeBronze = new(0xC2 / 255f, 0x41 / 255f, 0x0C / 255f, 1f);
private static readonly Vector4 ForgeBronzeDim = new(0xC2 / 255f, 0x41 / 255f, 0x0C / 255f, 0.3f); private static readonly Vector4 ForgeBronzeDim = new(
0xC2 / 255f,
0x41 / 255f,
0x0C / 255f,
0.3f
);
private const int TotalSteps = 4; private const int TotalSteps = 4;
@@ -64,11 +69,22 @@ public sealed class FirstRunWizard : Window
switch (_state.CurrentStep) switch (_state.CurrentStep)
{ {
case 1: DrawStepWelcome(); break; case 1:
case 2: DrawStepPrivacy(); break; DrawStepWelcome();
case 3: DrawStepPowerSettings(); break; break;
case 4: DrawStepDone(); break; case 2:
default: _state.CurrentStep = 1; DrawStepWelcome(); break; DrawStepPrivacy();
break;
case 3:
DrawStepPowerSettings();
break;
case 4:
DrawStepDone();
break;
default:
_state.CurrentStep = 1;
DrawStepWelcome();
break;
} }
} }
@@ -86,7 +102,11 @@ public sealed class FirstRunWizard : Window
{ {
var color = (i + 1) == _state.CurrentStep ? ForgeBronze : ForgeBronzeDim; var color = (i + 1) == _state.CurrentStep ? ForgeBronze : ForgeBronzeDim;
var packed = ImGui.GetColorU32(color); var packed = ImGui.GetColorU32(color);
draw.AddCircleFilled(new Vector2(startX + i * spacing, cursor.Y + radius), radius, packed); draw.AddCircleFilled(
new Vector2(startX + i * spacing, cursor.Y + radius),
radius,
packed
);
} }
// Reserve vertical space the circles consumed so the next widget starts below them. // Reserve vertical space the circles consumed so the next widget starts below them.
@@ -96,7 +116,8 @@ public sealed class FirstRunWizard : Window
private void DrawFooter(bool showBack, bool showSkip, string primaryLabel, Action onPrimary) private void DrawFooter(bool showBack, bool showSkip, string primaryLabel, Action onPrimary)
{ {
var spacing = ImGui.GetStyle().ItemSpacing.Y; var spacing = ImGui.GetStyle().ItemSpacing.Y;
var primaryWidth = ImGui.CalcTextSize(primaryLabel).X + ImGui.GetStyle().FramePadding.X * 2 + 16f; var primaryWidth =
ImGui.CalcTextSize(primaryLabel).X + ImGui.GetStyle().FramePadding.X * 2 + 16f;
var avail = ImGui.GetContentRegionAvail(); var avail = ImGui.GetContentRegionAvail();
// Push the footer to the bottom of the window so step contents // Push the footer to the bottom of the window so step contents
@@ -175,8 +196,12 @@ public sealed class FirstRunWizard : Window
ImGui.Spacing(); ImGui.Spacing();
ImGui.TextWrapped(HellionStrings.Wizard_Step1_Footer_Hint); ImGui.TextWrapped(HellionStrings.Wizard_Step1_Footer_Hint);
DrawFooter(showBack: false, showSkip: true, HellionStrings.Wizard_Nav_Next, DrawFooter(
() => _state.CurrentStep = 2); showBack: false,
showSkip: true,
HellionStrings.Wizard_Nav_Next,
() => _state.CurrentStep = 2
);
} }
private void DrawStepPrivacy() private void DrawStepPrivacy()
@@ -186,51 +211,92 @@ public sealed class FirstRunWizard : Window
// Reserve footer height (separator + spacing + button row) so the // Reserve footer height (separator + spacing + button row) so the
// 2x2 grid uses the rest of the window. // 2x2 grid uses the rest of the window.
var footerReserve = ImGui.GetFrameHeightWithSpacing() + ImGui.GetStyle().ItemSpacing.Y * 3 + ImGui.GetTextLineHeight(); var footerReserve =
ImGui.GetFrameHeightWithSpacing()
+ ImGui.GetStyle().ItemSpacing.Y * 3
+ ImGui.GetTextLineHeight();
var grid = ImGui.GetContentRegionAvail(); var grid = ImGui.GetContentRegionAvail();
var cardWidth = (grid.X - ImGui.GetStyle().ItemSpacing.X) / 2f; var cardWidth = (grid.X - ImGui.GetStyle().ItemSpacing.X) / 2f;
var cardHeight = (grid.Y - footerReserve - ImGui.GetStyle().ItemSpacing.Y) / 2f; var cardHeight = (grid.Y - footerReserve - ImGui.GetStyle().ItemSpacing.Y) / 2f;
// Top row. // Top row.
DrawProfileCard(PrivacyProfile.PrivacyFirst, "🔒", DrawProfileCard(
PrivacyProfile.PrivacyFirst,
"🔒",
HellionStrings.Wizard_Profile_PrivacyFirst_Heading, HellionStrings.Wizard_Profile_PrivacyFirst_Heading,
HellionStrings.Wizard_Profile_PrivacyFirst_Description, HellionStrings.Wizard_Profile_PrivacyFirst_Description,
recommended: false, cardWidth, cardHeight); recommended: false,
cardWidth,
cardHeight
);
ImGui.SameLine(); ImGui.SameLine();
DrawProfileCard(PrivacyProfile.Casual, "💬", DrawProfileCard(
PrivacyProfile.Casual,
"💬",
HellionStrings.Wizard_Profile_Casual_Heading, HellionStrings.Wizard_Profile_Casual_Heading,
HellionStrings.Wizard_Profile_Casual_Description, HellionStrings.Wizard_Profile_Casual_Description,
recommended: true, cardWidth, cardHeight); recommended: true,
cardWidth,
cardHeight
);
// Bottom row. // Bottom row.
DrawProfileCard(PrivacyProfile.Roleplay, "🎭", DrawProfileCard(
PrivacyProfile.Roleplay,
"🎭",
HellionStrings.Wizard_Profile_Roleplay_Heading, HellionStrings.Wizard_Profile_Roleplay_Heading,
HellionStrings.Wizard_Profile_Roleplay_Description, HellionStrings.Wizard_Profile_Roleplay_Description,
recommended: false, cardWidth, cardHeight); recommended: false,
cardWidth,
cardHeight
);
ImGui.SameLine(); ImGui.SameLine();
DrawProfileCard(PrivacyProfile.FullHistory, "📚", DrawProfileCard(
PrivacyProfile.FullHistory,
"📚",
HellionStrings.Wizard_Profile_FullHistory_Heading, HellionStrings.Wizard_Profile_FullHistory_Heading,
HellionStrings.Wizard_Profile_FullHistory_Description, HellionStrings.Wizard_Profile_FullHistory_Description,
recommended: false, cardWidth, cardHeight); recommended: false,
cardWidth,
cardHeight
);
ImGui.Spacing(); ImGui.Spacing();
ImGui.TextDisabled(HellionStrings.Wizard_Step2_RecommendedFooter); ImGui.TextDisabled(HellionStrings.Wizard_Step2_RecommendedFooter);
DrawFooter(showBack: true, showSkip: true, HellionStrings.Wizard_Nav_Next, DrawFooter(
() => _state.CurrentStep = 3); showBack: true,
showSkip: true,
HellionStrings.Wizard_Nav_Next,
() => _state.CurrentStep = 3
);
} }
private void DrawProfileCard(PrivacyProfile profile, string emoji, string heading, string description, bool recommended, float width, float height) private void DrawProfileCard(
PrivacyProfile profile,
string emoji,
string heading,
string description,
bool recommended,
float width,
float height
)
{ {
var isSelected = _state.PendingProfile == profile; var isSelected = _state.PendingProfile == profile;
// GetStyleColorVec4 returns a pointer to the live style entry in // GetStyleColorVec4 returns a pointer to the live style entry in
// Dalamud.Bindings.ImGui, which would require unsafe. Use the U32 // Dalamud.Bindings.ImGui, which would require unsafe. Use the U32
// packed-colour overload of PushColor for the default branch so we // packed-colour overload of PushColor for the default branch so we
// can stay in safe code while still matching the current border. // can stay in safe code while still matching the current border.
var borderColor = isSelected ? ImGui.GetColorU32(ForgeBronze) : ImGui.GetColorU32(ImGuiCol.Border); var borderColor = isSelected
? ImGui.GetColorU32(ForgeBronze)
: ImGui.GetColorU32(ImGuiCol.Border);
using var _border = ImRaii.PushColor(ImGuiCol.Border, borderColor); using var _border = ImRaii.PushColor(ImGuiCol.Border, borderColor);
using var child = ImRaii.Child($"##profile-card-{profile}", new Vector2(width, height), true); using var child = ImRaii.Child(
$"##profile-card-{profile}",
new Vector2(width, height),
true
);
if (!child.Success) if (!child.Success)
return; return;
@@ -290,7 +356,12 @@ public sealed class FirstRunWizard : Window
} }
var filterPrev = _state.PendingFilterIncludePreviousSessions ?? true; var filterPrev = _state.PendingFilterIncludePreviousSessions ?? true;
if (ImGui.Checkbox(HellionStrings.Wizard_Step3_FilterIncludePreviousSessions_Label, ref filterPrev)) if (
ImGui.Checkbox(
HellionStrings.Wizard_Step3_FilterIncludePreviousSessions_Label,
ref filterPrev
)
)
{ {
_state.PendingFilterIncludePreviousSessions = filterPrev; _state.PendingFilterIncludePreviousSessions = filterPrev;
if (!filterPrev) if (!filterPrev)
@@ -303,8 +374,16 @@ public sealed class FirstRunWizard : Window
using (ImRaii.PushColor(ImGuiCol.Text, ForgeBronze)) using (ImRaii.PushColor(ImGuiCol.Text, ForgeBronze))
ImGui.TextUnformatted(HellionStrings.Wizard_Step3_Section_TellTabs); ImGui.TextUnformatted(HellionStrings.Wizard_Step3_Section_TellTabs);
var preload = _state.PendingAutoTellTabsHistoryPreload ?? Plugin.Config.AutoTellTabsHistoryPreload; var preload =
if (ImGui.SliderInt(HellionStrings.Wizard_Step3_AutoTellTabsHistoryPreload_Label, ref preload, 0, 100)) _state.PendingAutoTellTabsHistoryPreload ?? Plugin.Config.AutoTellTabsHistoryPreload;
if (
ImGui.SliderInt(
HellionStrings.Wizard_Step3_AutoTellTabsHistoryPreload_Label,
ref preload,
0,
100
)
)
_state.PendingAutoTellTabsHistoryPreload = preload; _state.PendingAutoTellTabsHistoryPreload = preload;
ImGui.Spacing(); ImGui.Spacing();
@@ -325,11 +404,18 @@ public sealed class FirstRunWizard : Window
// territory and would clutter the first-run flow. // territory and would clutter the first-run flow.
var currentSlug = _state.PendingTheme ?? Plugin.Config.Theme; var currentSlug = _state.PendingTheme ?? Plugin.Config.Theme;
var builtIns = Plugin.ThemeRegistry.AllBuiltIns().ToList(); var builtIns = Plugin.ThemeRegistry.AllBuiltIns().ToList();
var currentIndex = builtIns.FindIndex(t => string.Equals(t.Slug, currentSlug, StringComparison.OrdinalIgnoreCase)); var currentIndex = builtIns.FindIndex(t =>
string.Equals(t.Slug, currentSlug, StringComparison.OrdinalIgnoreCase)
);
if (currentIndex < 0) if (currentIndex < 0)
currentIndex = 0; currentIndex = 0;
using (var combo = ImRaii.Combo(HellionStrings.Wizard_Step3_Theme_Label, builtIns[currentIndex].Name)) using (
var combo = ImRaii.Combo(
HellionStrings.Wizard_Step3_Theme_Label,
builtIns[currentIndex].Name
)
)
{ {
if (combo.Success) if (combo.Success)
{ {
@@ -344,8 +430,12 @@ public sealed class FirstRunWizard : Window
} }
} }
DrawFooter(showBack: true, showSkip: true, HellionStrings.Wizard_Nav_Next, DrawFooter(
() => _state.CurrentStep = 4); showBack: true,
showSkip: true,
HellionStrings.Wizard_Nav_Next,
() => _state.CurrentStep = 4
);
} }
private void DrawStepDone() private void DrawStepDone()
@@ -378,51 +468,74 @@ public sealed class FirstRunWizard : Window
var profileLabel = _state.PendingProfile switch var profileLabel = _state.PendingProfile switch
{ {
PrivacyProfile.PrivacyFirst => HellionStrings.Wizard_Profile_PrivacyFirst_Heading, PrivacyProfile.PrivacyFirst =>
HellionStrings.Wizard_Profile_PrivacyFirst_Heading,
PrivacyProfile.Casual => HellionStrings.Wizard_Profile_Casual_Heading, PrivacyProfile.Casual => HellionStrings.Wizard_Profile_Casual_Heading,
PrivacyProfile.Roleplay => HellionStrings.Wizard_Profile_Roleplay_Heading, PrivacyProfile.Roleplay => HellionStrings.Wizard_Profile_Roleplay_Heading,
PrivacyProfile.FullHistory => HellionStrings.Wizard_Profile_FullHistory_Heading, PrivacyProfile.FullHistory => HellionStrings.Wizard_Profile_FullHistory_Heading,
_ => HellionStrings.Wizard_Step4_Summary_Unchanged, _ => HellionStrings.Wizard_Step4_Summary_Unchanged,
}; };
ImGui.TextWrapped(string.Format(HellionStrings.Wizard_Step4_Summary_Profile, profileLabel)); ImGui.TextWrapped(
string.Format(HellionStrings.Wizard_Step4_Summary_Profile, profileLabel)
);
var historyLabel = (_state.PendingLoadPreviousSession ?? false) var historyLabel =
? HellionStrings.Wizard_Step3_LoadPreviousSession_Label (_state.PendingLoadPreviousSession ?? false)
: HellionStrings.Wizard_Step4_Summary_Unchanged; ? HellionStrings.Wizard_Step3_LoadPreviousSession_Label
ImGui.TextWrapped(string.Format(HellionStrings.Wizard_Step4_Summary_History, historyLabel)); : HellionStrings.Wizard_Step4_Summary_Unchanged;
ImGui.TextWrapped(
string.Format(HellionStrings.Wizard_Step4_Summary_History, historyLabel)
);
var preloadValue = _state.PendingAutoTellTabsHistoryPreload ?? Plugin.Config.AutoTellTabsHistoryPreload; var preloadValue =
ImGui.TextWrapped(string.Format(HellionStrings.Wizard_Step4_Summary_TellTabs, preloadValue)); _state.PendingAutoTellTabsHistoryPreload
?? Plugin.Config.AutoTellTabsHistoryPreload;
ImGui.TextWrapped(
string.Format(HellionStrings.Wizard_Step4_Summary_TellTabs, preloadValue)
);
var compact = _state.PendingUseCompactDensity ?? Plugin.Config.UseCompactDensity; var compact = _state.PendingUseCompactDensity ?? Plugin.Config.UseCompactDensity;
var pretty = _state.PendingPrettierTimestamps ?? Plugin.Config.PrettierTimestamps; var pretty = _state.PendingPrettierTimestamps ?? Plugin.Config.PrettierTimestamps;
var themeSlug = _state.PendingTheme ?? Plugin.Config.Theme; var themeSlug = _state.PendingTheme ?? Plugin.Config.Theme;
var themeName = Plugin.ThemeRegistry.Get(themeSlug).Name; var themeName = Plugin.ThemeRegistry.Get(themeSlug).Name;
var visualParts = new List<string>(); var visualParts = new List<string>();
if (compact) visualParts.Add(HellionStrings.Wizard_Step3_UseCompactDensity_Label); if (compact)
if (pretty) visualParts.Add(HellionStrings.Wizard_Step3_PrettierTimestamps_Label); visualParts.Add(HellionStrings.Wizard_Step3_UseCompactDensity_Label);
if (pretty)
visualParts.Add(HellionStrings.Wizard_Step3_PrettierTimestamps_Label);
visualParts.Add(themeName); visualParts.Add(themeName);
ImGui.TextWrapped(string.Format(HellionStrings.Wizard_Step4_Summary_Visual, string.Join(", ", visualParts))); ImGui.TextWrapped(
string.Format(
HellionStrings.Wizard_Step4_Summary_Visual,
string.Join(", ", visualParts)
)
);
} }
} }
ImGui.Spacing(); ImGui.Spacing();
// Inline FR-3 hint with placeholder for preload count. // Inline FR-3 hint with placeholder for preload count.
var preloadForHint = _state.PendingAutoTellTabsHistoryPreload ?? Plugin.Config.AutoTellTabsHistoryPreload; var preloadForHint =
_state.PendingAutoTellTabsHistoryPreload ?? Plugin.Config.AutoTellTabsHistoryPreload;
using (ImRaii.PushColor(ImGuiCol.Text, ForgeBronze)) using (ImRaii.PushColor(ImGuiCol.Text, ForgeBronze))
ImGui.TextWrapped(string.Format(HellionStrings.Wizard_Step4_TestHint, preloadForHint)); ImGui.TextWrapped(string.Format(HellionStrings.Wizard_Step4_TestHint, preloadForHint));
ImGui.Spacing(); ImGui.Spacing();
ImGui.TextDisabled(HellionStrings.Wizard_Step4_SettingsHint); ImGui.TextDisabled(HellionStrings.Wizard_Step4_SettingsHint);
DrawFooter(showBack: true, showSkip: false, HellionStrings.Wizard_Nav_Finish, () => DrawFooter(
{ showBack: true,
CommitPending(); showSkip: false,
Plugin.Config.FirstRunCompleted = true; HellionStrings.Wizard_Nav_Finish,
Plugin.SaveConfig(); () =>
IsOpen = false; {
}); CommitPending();
Plugin.Config.FirstRunCompleted = true;
Plugin.SaveConfig();
IsOpen = false;
}
);
} }
// Writes only non-null pending values back to Config. A null pending // Writes only non-null pending values back to Config. A null pending
@@ -433,20 +546,32 @@ public sealed class FirstRunWizard : Window
{ {
switch (_state.PendingProfile) switch (_state.PendingProfile)
{ {
case PrivacyProfile.PrivacyFirst: ApplyPrivacyFirst(); break; case PrivacyProfile.PrivacyFirst:
case PrivacyProfile.Casual: ApplyCasual(); break; ApplyPrivacyFirst();
case PrivacyProfile.Roleplay: ApplyRoleplay(); break; break;
case PrivacyProfile.FullHistory: ApplyFullHistory(); break; case PrivacyProfile.Casual:
ApplyCasual();
break;
case PrivacyProfile.Roleplay:
ApplyRoleplay();
break;
case PrivacyProfile.FullHistory:
ApplyFullHistory();
break;
} }
if (_state.PendingLoadPreviousSession.HasValue) if (_state.PendingLoadPreviousSession.HasValue)
Plugin.Config.LoadPreviousSession = _state.PendingLoadPreviousSession.Value; Plugin.Config.LoadPreviousSession = _state.PendingLoadPreviousSession.Value;
if (_state.PendingFilterIncludePreviousSessions.HasValue) if (_state.PendingFilterIncludePreviousSessions.HasValue)
Plugin.Config.FilterIncludePreviousSessions = _state.PendingFilterIncludePreviousSessions.Value; Plugin.Config.FilterIncludePreviousSessions = _state
.PendingFilterIncludePreviousSessions
.Value;
if (_state.PendingAutoTellTabsHistoryPreload.HasValue) if (_state.PendingAutoTellTabsHistoryPreload.HasValue)
Plugin.Config.AutoTellTabsHistoryPreload = _state.PendingAutoTellTabsHistoryPreload.Value; Plugin.Config.AutoTellTabsHistoryPreload = _state
.PendingAutoTellTabsHistoryPreload
.Value;
if (_state.PendingUseCompactDensity.HasValue) if (_state.PendingUseCompactDensity.HasValue)
Plugin.Config.UseCompactDensity = _state.PendingUseCompactDensity.Value; Plugin.Config.UseCompactDensity = _state.PendingUseCompactDensity.Value;
@@ -517,11 +642,13 @@ public sealed class FirstRunWizard : Window
// Test-only entry point so SelfTests/WizardStateSmokeStep can advance // Test-only entry point so SelfTests/WizardStateSmokeStep can advance
// the state machine without spawning ImGui input events. // the state machine without spawning ImGui input events.
internal void TestOnly_AdvanceTo(int step) => _state.CurrentStep = Math.Clamp(step, 1, TotalSteps); internal void TestOnly_AdvanceTo(int step) =>
_state.CurrentStep = Math.Clamp(step, 1, TotalSteps);
// Test-only setter so the smoke-test can pin a profile selection // Test-only setter so the smoke-test can pin a profile selection
// without driving the ImGui card-click path. // without driving the ImGui card-click path.
internal void TestOnly_SetPendingProfile(PrivacyProfile profile) => _state.PendingProfile = profile; internal void TestOnly_SetPendingProfile(PrivacyProfile profile) =>
_state.PendingProfile = profile;
internal enum PrivacyProfile internal enum PrivacyProfile
{ {