UX improvements

This commit is contained in:
2026-02-28 00:57:11 -06:00
parent 6607bae2b5
commit f5378a55ed
6 changed files with 132 additions and 97 deletions

View File

@@ -778,36 +778,12 @@ int main(int argc, char* argv[])
dragonx::util::PerfLog::instance().init(perfPath);
}
// If the user had a font scale > 1.0 saved, app.init() rebuilt fonts
// at that scale. Resize the window now so the larger UI fits.
{
float fs = dragonx::ui::Layout::userFontScale();
if (fs > 1.01f) {
int curW = 0, curH = 0;
SDL_GetWindowSize(window, &curW, &curH);
int newW = (int)lroundf(curW * fs);
int newH = (int)lroundf(curH * fs);
// Clamp to display work area
SDL_DisplayID did = SDL_GetDisplayForWindow(window);
if (did) {
SDL_Rect usable;
if (SDL_GetDisplayUsableBounds(did, &usable)) {
newW = std::min(newW, usable.w);
newH = std::min(newH, usable.h);
}
}
float hwDpi = dragonx::ui::Layout::rawDpiScale();
SDL_SetWindowSize(window, newW, newH);
SDL_SetWindowMinimumSize(window,
(int)(1024 * hwDpi * fs),
(int)(720 * hwDpi * fs));
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
DEBUG_LOGF("Font-scale startup: window %dx%d -> %dx%d (fontScale %.1f)\n",
curW, curH, newW, newH, fs);
}
}
// NOTE: No font-scale startup resize here. The saved window size
// already includes any font-scale inflation from the previous session
// (save divides by dpiScale but not fontScale). Multiplying by
// fontScale again would compound the effect on every restart.
// The per-frame font-scale block in the main loop handles resizing
// when the user actually changes the slider.
// Handle pending payment URI from command line
if (!pendingURI.empty()) {
@@ -1057,6 +1033,11 @@ int main(int argc, char* argv[])
lastKnownH = waitEvent.window.data2;
}
}
// Window restored from minimized — trigger immediate data refresh
if (waitEvent.type == SDL_EVENT_WINDOW_RESTORED &&
waitEvent.window.windowID == SDL_GetWindowID(window)) {
app.refreshNow();
}
// Handle DPI change that arrived while idle (same logic as poll loop)
if (waitEvent.type == SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED &&
waitEvent.window.windowID == SDL_GetWindowID(window)) {
@@ -1193,6 +1174,11 @@ int main(int argc, char* argv[])
lastKnownH = event.window.data2;
}
}
// Window restored from minimized — trigger immediate data refresh
if (event.type == SDL_EVENT_WINDOW_RESTORED &&
event.window.windowID == SDL_GetWindowID(window)) {
app.refreshNow();
}
// Handle DPI/display scale changes (e.g. window dragged to a
// different-DPI monitor, or user changes Windows scaling)
if (event.type == SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED &&
@@ -1295,18 +1281,38 @@ int main(int argc, char* argv[])
// Pre-frame: font atlas rebuilds and schema hot-reload must
// happen BEFORE NewFrame() because NewFrame() caches font ptrs.
float prevFontScale = dragonx::ui::Layout::userFontScale();
app.preFrame();
// If font scale changed (user dragged the slider), resize window
// Smooth font-scale: compensate visual font size via FontScaleMain
// when the atlas hasn't been rebuilt yet (during slider drag).
// After atlas rebuild, atlasScale == userFontScale so this is 1.0.
{
float userFS = dragonx::ui::Layout::userFontScale();
float atlasFS = dragonx::ui::Layout::fontAtlasScale();
if (atlasFS > 0.001f)
ImGui::GetStyle().FontScaleMain = userFS / atlasFS;
}
// If font scale changed, resize window proportionally.
// anchorW/H = the window size at the moment the anchor was set.
// anchorFS = the font scale at that moment.
// target = anchorW * curFS / anchorFS (symmetric, no drift).
{
static float anchorFS = 0.0f;
static int anchorW = 0, anchorH = 0;
float curFS = dragonx::ui::Layout::userFontScale();
if (std::fabs(curFS - prevFontScale) > 0.001f) {
int curW = 0, curH = 0;
SDL_GetWindowSize(window, &curW, &curH);
float ratio = curFS / prevFontScale;
int newW = (int)lroundf(curW * ratio);
int newH = (int)lroundf(curH * ratio);
if (anchorFS < 0.001f) {
// First frame: the current window IS the reference for
// whatever font scale is loaded — no resize.
anchorFS = curFS;
SDL_GetWindowSize(window, &anchorW, &anchorH);
}
if (std::fabs(curFS - anchorFS) > 0.001f) {
float ratio = curFS / anchorFS;
int newW = (int)lroundf((float)anchorW * ratio);
int newH = (int)lroundf((float)anchorH * ratio);
// Clamp to display work area
SDL_DisplayID did = SDL_GetDisplayForWindow(window);
@@ -1319,14 +1325,21 @@ int main(int argc, char* argv[])
}
float hwDpi = dragonx::ui::Layout::rawDpiScale();
SDL_SetWindowSize(window, newW, newH);
// Update minimum size BEFORE resizing so the window can
// actually shrink when the font scale decreases.
SDL_SetWindowMinimumSize(window,
(int)(1024 * hwDpi * curFS),
(int)(720 * hwDpi * curFS));
SDL_SetWindowSize(window, newW, newH);
lastKnownW = newW;
lastKnownH = newH;
DEBUG_LOGF("Font-scale resize: %dx%d -> %dx%d (%.1fx -> %.1fx)\n",
curW, curH, newW, newH, prevFontScale, curFS);
// Update anchor so we don't re-fire every frame.
// The new anchor becomes the current size/scale so
// subsequent slider movements are relative to here.
anchorW = newW;
anchorH = newH;
anchorFS = curFS;
}
}