feat(wizard): modernize the first-run wizard to the current design language
The first-run wizard predated the modal-unification pass and was the least on-brand surface left — a flat Surface() slab with a 3-card masonry whose inactive steps were heavily greyed (alpha 165) and whose focused card used a hard 2px border + a hand-drawn offset shadow. Keeping the working phase logic and the "see all steps at once" masonry: - Reveal the skin backdrop: the app already paints its marble / gradient / acrylic backdrop behind every window (drawWindowBackdrop), so drop the opaque Surface() fill (transparent WindowBg) and lay a gentle theme-tinted scrim over it. The wizard now sits on the same rich backdrop as the rest of the app. - Focused card lifts with the shared DrawCardDropShadow (the uniform, non- clipping card shadow) instead of a bespoke offset rect, and a softer 1.5px accent ring. - Inactive cards get lighter veils (upcoming 165->115, completed 110->70) so they read as "waiting" / "done" rather than disabled-grey. - Warmer header: a one-line subtitle under the welcome title. Verified on the headless sweep across all four phases (appearance / bootstrap / encrypt / pin) on marble + obsidian at 1.0 and 1.5x DPI — backdrop shows, cards float cleanly, geometry scales, nothing clipped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -121,16 +121,21 @@ void App::renderFirstRunWizard() {
|
||||
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse;
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0)); // reveal the skin backdrop behind
|
||||
ImGui::Begin("##FirstRunWizard", nullptr, flags);
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
ImDrawList* dl = ImGui::GetWindowDrawList();
|
||||
ImVec2 winPos = ImGui::GetWindowPos();
|
||||
ImVec2 winSize = ImGui::GetWindowSize();
|
||||
|
||||
// Background fill
|
||||
ImU32 bgCol = ui::material::Surface();
|
||||
dl->AddRectFilled(winPos, ImVec2(winPos.x + winSize.x, winPos.y + winSize.y), bgCol);
|
||||
// The app's skin backdrop (marble / gradient / acrylic) is already painted behind every window by
|
||||
// drawWindowBackdrop(); reveal it here instead of a flat Surface() slab, under a gentle theme-tinted
|
||||
// scrim so the wizard cards and text keep their contrast on busy skins.
|
||||
ImU32 bgCol = ui::material::Surface(); // still used by the completed / not-reached card overlays
|
||||
dl->AddRectFilled(winPos, ImVec2(winPos.x + winSize.x, winPos.y + winSize.y),
|
||||
ui::material::WithAlpha(ui::material::Background(), 120));
|
||||
|
||||
// --- Determine which of the 3 masonry sections is focused ---
|
||||
// 0 = Appearance, 1 = Bootstrap, 2 = Encrypt + PIN
|
||||
@@ -188,7 +193,14 @@ void App::renderFirstRunWizard() {
|
||||
ImVec2 wts = titleFont->CalcTextSizeA(titleFont->LegacySize, FLT_MAX, 0, welcomeTitle);
|
||||
dl->AddText(titleFont, titleFont->LegacySize,
|
||||
ImVec2(winPos.x + (winSize.x - wts.x) * 0.5f, headerCy), textCol, welcomeTitle);
|
||||
headerCy += wts.y + 16.0f * dp;
|
||||
headerCy += wts.y + 6.0f * dp;
|
||||
|
||||
// Warmer, less-sparse header: a one-line subtitle under the welcome (dimmed body).
|
||||
const char* welcomeSub = "A few quick choices and your full node is ready.";
|
||||
ImVec2 sts = bodyFont->CalcTextSizeA(bodyFont->LegacySize, FLT_MAX, 0, welcomeSub);
|
||||
dl->AddText(bodyFont, bodyFont->LegacySize,
|
||||
ImVec2(winPos.x + (winSize.x - sts.x) * 0.5f, headerCy), dimCol, welcomeSub);
|
||||
headerCy += sts.y + 16.0f * dp;
|
||||
}
|
||||
|
||||
// --- Masonry: 2 columns ---
|
||||
@@ -223,11 +235,8 @@ void App::renderFirstRunWizard() {
|
||||
// Background (channel 0)
|
||||
dl->ChannelsSetCurrent(0);
|
||||
if (state == 1) {
|
||||
// Focused card: subtle drop shadow
|
||||
float shadowOff = 3.0f * dp;
|
||||
dl->AddRectFilled(
|
||||
ImVec2(cMin.x + shadowOff, cMin.y + shadowOff), ImVec2(cMax.x + shadowOff, cMax.y + shadowOff),
|
||||
IM_COL32(0, 0, 0, 35), cardRound);
|
||||
// Focused card lifts off the backdrop with the app's uniform card shadow (not a hard offset).
|
||||
ui::material::DrawCardDropShadow(dl, cMin, cMax, cardRound);
|
||||
}
|
||||
// Use DrawGlassPanel for proper acrylic/opacity/noise/theme effects
|
||||
ui::material::GlassPanelSpec glass;
|
||||
@@ -237,14 +246,14 @@ void App::renderFirstRunWizard() {
|
||||
// Overlays & borders (channel 2)
|
||||
dl->ChannelsSetCurrent(2);
|
||||
if (state == 1) {
|
||||
// Focused: accent border
|
||||
dl->AddRect(cMin, cMax, ui::material::Primary(), cardRound, 0, 2.0f * dp);
|
||||
// Focused: soft accent ring
|
||||
dl->AddRect(cMin, cMax, ui::material::Primary(), cardRound, 0, 1.5f * dp);
|
||||
} else if (state == 2) {
|
||||
// Completed: dim overlay (preserves color)
|
||||
dl->AddRectFilled(cMin, cMax, (bgCol & 0x00FFFFFF) | IM_COL32(0, 0, 0, 110), cardRound);
|
||||
// Completed: a light veil — reads as "done", not disabled.
|
||||
dl->AddRectFilled(cMin, cMax, (bgCol & 0x00FFFFFF) | IM_COL32(0, 0, 0, 70), cardRound);
|
||||
} else {
|
||||
// Not reached: heavy overlay (creates greyscale look)
|
||||
dl->AddRectFilled(cMin, cMax, (bgCol & 0x00FFFFFF) | IM_COL32(0, 0, 0, 165), cardRound);
|
||||
// Upcoming: a gentle veil — reads as "waiting", not greyed-out.
|
||||
dl->AddRectFilled(cMin, cMax, (bgCol & 0x00FFFFFF) | IM_COL32(0, 0, 0, 115), cardRound);
|
||||
}
|
||||
|
||||
dl->ChannelsSetCurrent(1);
|
||||
|
||||
Reference in New Issue
Block a user