Scale stage 2: continuous uiScale setting + the (-) 100% (+) stepper
AppSettings.textSize (compact|default|large) becomes uiScale: number, 0.5-4 in 0.1 steps, default 1. One shared clampUiScale (next to the effectiveConcurrency precedent) defines "valid" for the store, the service and the stepper: clamp to range, snap to the step grid, strip float noise, and map NaN/Infinity to 1. - SettingsStore.load migrates legacy files (compact/default/large -> 0.9/1/1.2, never over an explicit uiScale) and clamps ALWAYS, not just on migration — buildPreload writes this value into every window's root font-size, so a hand-edited settings.json (uiScale: 100) must not be able to render the UI unusable. Verified against 100, 0.001, -3, NaN, Infinity and float noise; migration verified against a real legacy file. - SettingsService: applyUiScale sets the root font-size (16 * scale, removed entirely at 1 per the delete-when-default rule). Rides the existing settingsChanged broadcast, so open editor/manager windows follow live. - buildPreload bakes the same font-size so the first paint is already scaled — without it every window opens at 100% and snaps. - Both tab-bars: the 3-button Interface row becomes the stepper. Clicking the percentage resets to 100% (tooltip says so). i18n: compact/default/large dropped, smaller/larger/reset added, all 7 locales. Verified live, win7 + modern: scale 1 is pixel-identical to the pre-work baseline (opaque interior diff exactly 0); 0.5x is a real dense mode (~2x rows); 2x scales title bar, tabs, rows, icons and controls together with text contained in its boxes — which is what stage 1c's 7.css bridge bought; 4x is enormous but coherent, and the win7 title-bar controls stay on-screen at the default window size. The known caveat stands: no minimum window size exists, so 4x in a small window is legal but cramped. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+6
-1
@@ -59,7 +59,12 @@ export function buildPreload(
|
||||
if (settings.theme !== "system") dataset["theme"] = settings.theme;
|
||||
if (settings.darkTone !== "dark") dataset["darkTone"] = settings.darkTone;
|
||||
if (settings.accent !== "graphite") dataset["accent"] = settings.accent;
|
||||
if (settings.textSize !== "default") dataset["text"] = settings.textSize;
|
||||
// interface scale: mirrors SettingsService.applyUiScale so the FIRST paint
|
||||
// is already scaled — without this every window opens at 100% and snaps.
|
||||
// Written as an inline style, not a data attribute: the scale is continuous.
|
||||
if (settings.uiScale !== 1) {
|
||||
script += `document.documentElement.style.fontSize=${JSON.stringify(`${16 * settings.uiScale}px`)};`;
|
||||
}
|
||||
for (const [key, value] of Object.entries(dataset)) {
|
||||
script += `document.documentElement.dataset[${JSON.stringify(key)}]=${JSON.stringify(value)};`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user