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.
this.snapshotPrivacyFilterEnabled = Plugin.Config.PrivacyFilterEnabled;
this.snapshotPrivacyPersistChannels = Plugin.Config.PrivacyPersistChannels;
this.snapshotPrivacyPersistUnknownChannels = Plugin.Config.PrivacyPersistUnknownChannels;
this.snapshotPrivacyPersistUnknownChannels = Plugin
.Config
.PrivacyPersistUnknownChannels;
this.snapshotRetentionEnabled = Plugin.Config.RetentionEnabled;
this.snapshotRetentionDefaultDays = Plugin.Config.RetentionDefaultDays;
this.snapshotRetentionPerChannelDays = Plugin.Config.RetentionPerChannelDays;
+178 -51
View File
@@ -24,7 +24,12 @@ public sealed class FirstRunWizard : Window
// and the forge-announce workflow; pinning it locally keeps the
// 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 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;
@@ -64,11 +69,22 @@ public sealed class FirstRunWizard : Window
switch (_state.CurrentStep)
{
case 1: DrawStepWelcome(); break;
case 2: DrawStepPrivacy(); break;
case 3: DrawStepPowerSettings(); break;
case 4: DrawStepDone(); break;
default: _state.CurrentStep = 1; DrawStepWelcome(); break;
case 1:
DrawStepWelcome();
break;
case 2:
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 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.
@@ -96,7 +116,8 @@ public sealed class FirstRunWizard : Window
private void DrawFooter(bool showBack, bool showSkip, string primaryLabel, Action onPrimary)
{
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();
// Push the footer to the bottom of the window so step contents
@@ -175,8 +196,12 @@ public sealed class FirstRunWizard : Window
ImGui.Spacing();
ImGui.TextWrapped(HellionStrings.Wizard_Step1_Footer_Hint);
DrawFooter(showBack: false, showSkip: true, HellionStrings.Wizard_Nav_Next,
() => _state.CurrentStep = 2);
DrawFooter(
showBack: false,
showSkip: true,
HellionStrings.Wizard_Nav_Next,
() => _state.CurrentStep = 2
);
}
private void DrawStepPrivacy()
@@ -186,51 +211,92 @@ public sealed class FirstRunWizard : Window
// Reserve footer height (separator + spacing + button row) so the
// 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 cardWidth = (grid.X - ImGui.GetStyle().ItemSpacing.X) / 2f;
var cardHeight = (grid.Y - footerReserve - ImGui.GetStyle().ItemSpacing.Y) / 2f;
// Top row.
DrawProfileCard(PrivacyProfile.PrivacyFirst, "🔒",
DrawProfileCard(
PrivacyProfile.PrivacyFirst,
"🔒",
HellionStrings.Wizard_Profile_PrivacyFirst_Heading,
HellionStrings.Wizard_Profile_PrivacyFirst_Description,
recommended: false, cardWidth, cardHeight);
recommended: false,
cardWidth,
cardHeight
);
ImGui.SameLine();
DrawProfileCard(PrivacyProfile.Casual, "💬",
DrawProfileCard(
PrivacyProfile.Casual,
"💬",
HellionStrings.Wizard_Profile_Casual_Heading,
HellionStrings.Wizard_Profile_Casual_Description,
recommended: true, cardWidth, cardHeight);
recommended: true,
cardWidth,
cardHeight
);
// Bottom row.
DrawProfileCard(PrivacyProfile.Roleplay, "🎭",
DrawProfileCard(
PrivacyProfile.Roleplay,
"🎭",
HellionStrings.Wizard_Profile_Roleplay_Heading,
HellionStrings.Wizard_Profile_Roleplay_Description,
recommended: false, cardWidth, cardHeight);
recommended: false,
cardWidth,
cardHeight
);
ImGui.SameLine();
DrawProfileCard(PrivacyProfile.FullHistory, "📚",
DrawProfileCard(
PrivacyProfile.FullHistory,
"📚",
HellionStrings.Wizard_Profile_FullHistory_Heading,
HellionStrings.Wizard_Profile_FullHistory_Description,
recommended: false, cardWidth, cardHeight);
recommended: false,
cardWidth,
cardHeight
);
ImGui.Spacing();
ImGui.TextDisabled(HellionStrings.Wizard_Step2_RecommendedFooter);
DrawFooter(showBack: true, showSkip: true, HellionStrings.Wizard_Nav_Next,
() => _state.CurrentStep = 3);
DrawFooter(
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;
// GetStyleColorVec4 returns a pointer to the live style entry in
// Dalamud.Bindings.ImGui, which would require unsafe. Use the U32
// packed-colour overload of PushColor for the default branch so we
// 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 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)
return;
@@ -290,7 +356,12 @@ public sealed class FirstRunWizard : Window
}
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;
if (!filterPrev)
@@ -303,8 +374,16 @@ public sealed class FirstRunWizard : Window
using (ImRaii.PushColor(ImGuiCol.Text, ForgeBronze))
ImGui.TextUnformatted(HellionStrings.Wizard_Step3_Section_TellTabs);
var preload = _state.PendingAutoTellTabsHistoryPreload ?? Plugin.Config.AutoTellTabsHistoryPreload;
if (ImGui.SliderInt(HellionStrings.Wizard_Step3_AutoTellTabsHistoryPreload_Label, ref preload, 0, 100))
var preload =
_state.PendingAutoTellTabsHistoryPreload ?? Plugin.Config.AutoTellTabsHistoryPreload;
if (
ImGui.SliderInt(
HellionStrings.Wizard_Step3_AutoTellTabsHistoryPreload_Label,
ref preload,
0,
100
)
)
_state.PendingAutoTellTabsHistoryPreload = preload;
ImGui.Spacing();
@@ -325,11 +404,18 @@ public sealed class FirstRunWizard : Window
// territory and would clutter the first-run flow.
var currentSlug = _state.PendingTheme ?? Plugin.Config.Theme;
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)
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)
{
@@ -344,8 +430,12 @@ public sealed class FirstRunWizard : Window
}
}
DrawFooter(showBack: true, showSkip: true, HellionStrings.Wizard_Nav_Next,
() => _state.CurrentStep = 4);
DrawFooter(
showBack: true,
showSkip: true,
HellionStrings.Wizard_Nav_Next,
() => _state.CurrentStep = 4
);
}
private void DrawStepDone()
@@ -378,51 +468,74 @@ public sealed class FirstRunWizard : Window
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.Roleplay => HellionStrings.Wizard_Profile_Roleplay_Heading,
PrivacyProfile.FullHistory => HellionStrings.Wizard_Profile_FullHistory_Heading,
_ => 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 =
(_state.PendingLoadPreviousSession ?? false)
? HellionStrings.Wizard_Step3_LoadPreviousSession_Label
: HellionStrings.Wizard_Step4_Summary_Unchanged;
ImGui.TextWrapped(string.Format(HellionStrings.Wizard_Step4_Summary_History, historyLabel));
ImGui.TextWrapped(
string.Format(HellionStrings.Wizard_Step4_Summary_History, historyLabel)
);
var preloadValue = _state.PendingAutoTellTabsHistoryPreload ?? Plugin.Config.AutoTellTabsHistoryPreload;
ImGui.TextWrapped(string.Format(HellionStrings.Wizard_Step4_Summary_TellTabs, preloadValue));
var preloadValue =
_state.PendingAutoTellTabsHistoryPreload
?? Plugin.Config.AutoTellTabsHistoryPreload;
ImGui.TextWrapped(
string.Format(HellionStrings.Wizard_Step4_Summary_TellTabs, preloadValue)
);
var compact = _state.PendingUseCompactDensity ?? Plugin.Config.UseCompactDensity;
var pretty = _state.PendingPrettierTimestamps ?? Plugin.Config.PrettierTimestamps;
var themeSlug = _state.PendingTheme ?? Plugin.Config.Theme;
var themeName = Plugin.ThemeRegistry.Get(themeSlug).Name;
var visualParts = new List<string>();
if (compact) visualParts.Add(HellionStrings.Wizard_Step3_UseCompactDensity_Label);
if (pretty) visualParts.Add(HellionStrings.Wizard_Step3_PrettierTimestamps_Label);
if (compact)
visualParts.Add(HellionStrings.Wizard_Step3_UseCompactDensity_Label);
if (pretty)
visualParts.Add(HellionStrings.Wizard_Step3_PrettierTimestamps_Label);
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();
// 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))
ImGui.TextWrapped(string.Format(HellionStrings.Wizard_Step4_TestHint, preloadForHint));
ImGui.Spacing();
ImGui.TextDisabled(HellionStrings.Wizard_Step4_SettingsHint);
DrawFooter(showBack: true, showSkip: false, HellionStrings.Wizard_Nav_Finish, () =>
DrawFooter(
showBack: true,
showSkip: false,
HellionStrings.Wizard_Nav_Finish,
() =>
{
CommitPending();
Plugin.Config.FirstRunCompleted = true;
Plugin.SaveConfig();
IsOpen = false;
});
}
);
}
// Writes only non-null pending values back to Config. A null pending
@@ -433,20 +546,32 @@ public sealed class FirstRunWizard : Window
{
switch (_state.PendingProfile)
{
case PrivacyProfile.PrivacyFirst: ApplyPrivacyFirst(); break;
case PrivacyProfile.Casual: ApplyCasual(); break;
case PrivacyProfile.Roleplay: ApplyRoleplay(); break;
case PrivacyProfile.FullHistory: ApplyFullHistory(); break;
case PrivacyProfile.PrivacyFirst:
ApplyPrivacyFirst();
break;
case PrivacyProfile.Casual:
ApplyCasual();
break;
case PrivacyProfile.Roleplay:
ApplyRoleplay();
break;
case PrivacyProfile.FullHistory:
ApplyFullHistory();
break;
}
if (_state.PendingLoadPreviousSession.HasValue)
Plugin.Config.LoadPreviousSession = _state.PendingLoadPreviousSession.Value;
if (_state.PendingFilterIncludePreviousSessions.HasValue)
Plugin.Config.FilterIncludePreviousSessions = _state.PendingFilterIncludePreviousSessions.Value;
Plugin.Config.FilterIncludePreviousSessions = _state
.PendingFilterIncludePreviousSessions
.Value;
if (_state.PendingAutoTellTabsHistoryPreload.HasValue)
Plugin.Config.AutoTellTabsHistoryPreload = _state.PendingAutoTellTabsHistoryPreload.Value;
Plugin.Config.AutoTellTabsHistoryPreload = _state
.PendingAutoTellTabsHistoryPreload
.Value;
if (_state.PendingUseCompactDensity.HasValue)
Plugin.Config.UseCompactDensity = _state.PendingUseCompactDensity.Value;
@@ -517,11 +642,13 @@ public sealed class FirstRunWizard : Window
// Test-only entry point so SelfTests/WizardStateSmokeStep can advance
// 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
// 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
{