diff --git a/src/lib/components/CanvasView.svelte b/src/lib/components/CanvasView.svelte index 08e97d4..5b2b27f 100644 --- a/src/lib/components/CanvasView.svelte +++ b/src/lib/components/CanvasView.svelte @@ -21,6 +21,7 @@ import { StrokeRecorder, hitStroke } from '$lib/ink/stroke'; import { pageCssVars } from '$lib/editor/pageStyle'; import { downloadCanvas } from './download'; + import PageSizeDialog from './PageSizeDialog.svelte'; import PageView from './PageView.svelte'; import Toolbar from './Toolbar.svelte'; @@ -241,15 +242,9 @@ menu.show(x, y, items); } - function customSize(id: string) { - const page = doc.pages[id]; - const mm = (pt: number) => Math.round((pt / 72) * 25.4); - const answer = prompt('Page size in millimetres (width × height)', `${mm(page.width)} × ${mm(page.height)}`); - const m = answer && /^\s*(\d+(?:\.\d+)?)\s*[x×*,\s]\s*(\d+(?:\.\d+)?)\s*$/i.exec(answer); - if (!m) return; - const pt = (v: string) => Math.min(5000, Math.max(50, (parseFloat(v) / 25.4) * 72)); - keepAnchor(id, () => doc.resizePage(id, pt(m[1]), pt(m[2]))); - } + /** Page whose custom-size dialog is open. */ + let sizing = $state(null); + const customSize = (id: string) => (sizing = id); const activeMenuPos = $derived.by(() => { const id = doc.activeId; @@ -551,7 +546,7 @@ } function onKeyDown(e: KeyboardEvent) { - if (workspace.settingsOpen) return; + if (workspace.settingsOpen || sizing) return; const mod = e.ctrlKey || e.metaKey; const k = e.key.toLowerCase(); @@ -707,6 +702,19 @@ {/if} + {#if sizing && doc.pages[sizing]} + {@const id = sizing} + (sizing = null)} + onapply={(w, h) => { + sizing = null; + keepAnchor(id, () => doc.resizePage(id, w, h)); + }} + /> + {/if} + fitPage(doc.activeId)} onfitall={fitAll} /> diff --git a/src/lib/components/PageSizeDialog.svelte b/src/lib/components/PageSizeDialog.svelte new file mode 100644 index 0000000..de320df --- /dev/null +++ b/src/lib/components/PageSizeDialog.svelte @@ -0,0 +1,173 @@ + + + e.key === 'Escape' && onclose()} /> + + +
e.target === e.currentTarget && onclose()}> +
{ + e.preventDefault(); + apply(); + }} + > +

Page size

+
+ {#each PAGE_PRESETS as p (p.label)} + + {/each} +
+
+ + + + mm +
+ {#if !valid} +

Sizes must be between {toMm(MIN_PT)} and {toMm(MAX_PT)} mm.

+ {/if} +
+ + +
+
+
+ +