Bumps the faction-legend swatch and shrinks the pattern tile so the
pattern is legible at swatch-size rather than showing just 1-2 tile
repeats.
- On-screen legend: hex 28 → 32 px, pattern tile scaled by swatch/96
with a 4 px floor — yields ~6 repeats across the swatch.
- PNG legend: swatch fontSize*1.1 → fontSize*1.7, lineHeight floored
at swatch+4 so rows don't overlap; pattern shrunk by the same ratio.
- renderHexPreview gains an optional patternScaleMultiplier param so
callers (legend, palette, future small-swatch contexts) can shrink
the pattern without touching the user's scale slider value.
Also bundles the prior 1.3.0 follow-up fixes (hex-shaped on-map-scale
preview, palette tile refresh-on-save, thin outline default + slider)
since those were committed locally on top of 1.3.0.
Three refinements to the 1.3.0 overlay pattern editor based on user
feedback:
- Preview: was a 120×36 rect at the pattern's own scale. Now a hex
polygon at the live on-map hex size (read from .duckmage-hex,
falling back to 96 px), in the configured orientation — so the
preview shows exactly what the overlay will look like on the map.
- Palette tiles: were never updating on Save because the picker
re-read style from the metadata cache, which lags Obsidian's
frontmatter write by a tick. The editor's onSaved callback now
passes the new OverlayStyle directly, so the picker renders from
the editor's in-memory state and updates immediately.
- Outline width: was hardcoded to gapPx*2+2 (often 14-22 px), which
made overlay borders read as solid blobs. Now per-overlay,
defaulting to 1.5 px, with a slider (0-20, step 0.5) in the editor.
Persisted as faction-outline-width / region-outline-width
frontmatter keys. Crank it up to recover the old thick-blob look.
Adds per-overlay pattern fills so factions and regions can be visually
distinguished when they overlap (issue #25). Each faction note and each
region note now carries a pattern, scale, and opacity in its
frontmatter, edited via the existing FactionEditor / GeoRegionEditor
modals (dropdown + sliders + live preview swatch).
Pattern set (10 total): solid (the existing flat fill, default),
diagonal stripes ↗ / ↖, crosshatch, polka dots, grid, zigzag,
triangles, scales, checker.
On screen: SVG <pattern> defs are deduped per (key,color,scale) and
referenced from each overlay path's fill. Stroke stays solid color so
blob boundaries remain crisp. Per-overlay opacity replaces the
hardcoded 0.45 group opacity.
PNG export: mirrored via Canvas patterns built from an offscreen tile
per (key,color,scale), cached for the render pass.
Backwards compatible — overlays without the new frontmatter keys fall
back to solid + 0.45 opacity, matching pre-1.3.0 behavior.
- Sentence-case: rephrase "GM" → "Game master"; remove disable comments;
autofixer lowercases "🎲 Open tables view" / "← Back" to comply
- no-static-styles-assignment: dynamic colors now use CSS custom properties
(--duckmage-bg / --duckmage-border-color / --duckmage-fg) consumed by
existing classes; static positions moved to small modifier classes
(duckmage-rt-roll-btn-spaced, duckmage-wf-steps-list, etc.); terrain
toolbar uses is-terrain-preview / is-eyedropper-active toggles;
createIconEl uses new duckmage-masked-icon class
- Popout-window compat: setTimeout / clearTimeout / requestAnimationFrame
→ window.X; document.X → activeDocument.X across all view/modal files
- Unnecessary `as ArrayBuffer`: replace `data.buffer.slice(...) as ArrayBuffer`
with `new ArrayBuffer + Uint8Array.set` — gets a real ArrayBuffer without
the assertion (also avoids ArrayBufferLike narrowing)
- Deprecated SettingTab.display(): extract body into private renderSettings();
display() and post-action refresh both call it
- eslint.config: add activeDocument + activeWindow to globals so the renamed
identifiers don't trip no-undef
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a unified export pipeline under src/export/ with exporters for single notes,
structured hexes, maps (with reference table), random tables, and workflows
(with rolled samples). PDF rendering reuses Obsidian's MarkdownRenderer + theme
CSS; map PNG/PDF goes through a dedicated canvas renderer.
UI surface:
- "Export" tab in MapModal (PNG/PDF with overlay + size options)
- "Export" link in HexEditorModal + HexExportModal
- "Export PDF/Markdown" links in RandomTableView header
- "Export…" button in WorkflowEditorModal + WorkflowExportModal
- Commands: export current note (PDF/MD), current hex, current workflow
- File-menu items on any .md file: Export to PDF / Markdown
Other:
- New `exportFolder` setting (defaults to {worldFolder}/exports)
- hexGeometry: add hexSize / hexCenter / hexPolygonPoints / gridBoundingBox
- HexTableView + HexEditorModal: first-wins on duplicate palette names
(matches HexMapView's .find() behaviour)
- Tests: unit + integration suites for all exporters; sim-vault fixture
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
feat: tabbed Maps modal; faction hover tooltip; map starting coordinates; default map/submap sizes in settings
- Maps modal refactored into three tabs: Maps (switch/delete), Properties (rename, terrain theme), New map (labeled fields, size presets)
- Faction overlay hover shows each faction on its own line with color swatch via custom floating tooltip div
- New map and submap creation accept starting X/Y coordinates; hex filenames and labels both reflect the chosen origin (gridOffset initialized accordingly)
- Map switching via modal now goes through switchToMap so viewport save/restore applies correctly
- Added defaultNewMapCols/Rows and defaultSubmapCols/Rows settings; new-map forms pre-fill from these
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Undo/redo now covers all paint tool types: terrain (existing), icon
override, faction link paint/erase, and region paint/erase. Each
stroke is committed on mouseup using the same Map-per-stroke pattern
as terrain.
- Fix: undoing an icon override now restores the underlying terrain icon
(previously left the hex blank).
- Fix: "Remove icon override" context menu item now calls renderGrid so
the icon disappears immediately without a reload.
- Multiple tokens on the same hex now spread out using preset offset
patterns (2=left/right, 3=triangle, 4=2×2, 5=pentagon, 6+=ring) so
all tokens are visible with slight overlap. Spread radius scales with
hex size.
- Hovered token rises above stacked siblings via z-index on :hover.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- folder tree view in link-table modal (collapsed by default, filter expands all)
- shared renderFolderTree utility; RandomTableView refactored to use it
- submap picker: filterable list replaces combo-dropdown; terrain theme swatch per map
- map terrain theme: per-map terrainType field drives submap center-dot color and swatch in switch-map list
- erase mode for paths/factions/regions: "Remove" tile + enters erase immediately
- submap link tool: blip animation on hex after linking
- hex map view header updates to active map name on switch
- fix: link-table modal scopes folder tree to tablesFolder only (was leaking vault-wide folders)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Single right-click while any drawing tool is active now opens a context
menu with "Switch <toolname>" (where applicable) and "Exit tool", replacing
the old double-right-click-to-exit gesture and the "↩ map mode" toolbar
button that caused layout shift (fixes#17).
New PainterContextMenu class is designed for subclass extension via
extraOptions() — individual tools can inject additional items later.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prevents MapLinkModal and SubmapPickerModal from being too short to show
the combo dropdown without triggering a scroll.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
position:fixed failed because Obsidian's modal CSS animation sets transform on
.modal, making fixed children position relative to it (not the viewport).
Instead, toggle .duckmage-combo-open on .modal-content (overflow-y:visible)
while the dropdown is open so the absolute-positioned dropdown doesn't trigger
the scroll container.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Combo dropdown now uses position:fixed with JS-calculated viewport coords so it
never causes the modal's overflow-y:auto container to scroll
- MapLinkModal: map filter and link text both start blank; link text auto-fills
on map selection only if still empty
- SubmapPickerModal: focus opens all maps (blank query)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Right-click hex → "Link submap" writes duckmage-submap frontmatter
- Hex flower shows centre dot (hidden when no link) that navigates into the submap
- Centre dot centering is orientation-aware (flat-top top:24px, pointy-top top:20px)
- ← Back button appears next to map dropdown (via flex nav group) after submap drill-in
- "Insert map link" editor context menu inserts obsidian://duckmage-openmap URI
- Map rename updates all duckmage-submap references via updateSubmapReferences()
- HexEditorOptions refactored: onNavigate/onModalClose/onSwitchMap in options object
- 10 new tests for submap frontmatter helpers and rename propagation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Tokens placed per-hex link to vault notes; support circle/square shape,
sm/md/lg size, fill color, optional border color, icon, and description
- TokenInfoModal shows note content (formatted via MarkdownRenderer, images
included) with jump-to-hex, open-note, edit, and two-step remove actions
- Edit flow reopens TokenModal pre-filled; proxy notes handle multiple tokens
referencing the same source note
- Icon picker replaced with scrollable palette grid (2-row cap, drag-to-reorder,
hide/show) in both HexEditorModal and TokenModal; order persisted in settings
- Token layer toggle added to layers menu (default on)
- Fix metadata-cache race on token delete (wasToken check prevents missed updates)
- Token preview rendered inline in TokenModal title row; real-time color preview
via native input event on color pickers
- Bump version to 1.1.6
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix map pixelation on zoom: bake CSS scale() into viewport font-size after
scroll wheel settles so the DOM renders natively at the zoomed resolution
instead of upscaling a compositor bitmap; redraw SVG overlays after bake
- Fix terrain brush size persisting when switching to icon tool: reset
paintBrushSize to 1 on icon mode entry
- Add shrink (−) buttons paired with each expand (+) button: fade in on hover,
positioned to the right for top/bottom and below for left/right; clicking a
clean row/col shrinks immediately and trashes the hex notes; clicking a dirty
row/col shows a red OK? confirm state (3 s timeout) before deleting
- Fix stale terrain showing after delete+re-expand: pass null terrain/icon
overrides for newly-added edge hexes so cached frontmatter from deleted files
cannot bleed through
- Add iconsFolder to onboarding wizard folder generation step
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace hover-fade "Delete" button with a fixed 20×20px ✕ button always
visible in each map row
- Hide the ✕ entirely when only one map remains (deletion blocked)
- Remove red background from confirmation row; use muted text instead
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each map row in the switch-map list now shows a "Delete" button (visible on
hover). Clicking it enters an inline confirmation state showing the map name
and a warning that hex notes will be trashed. Confirming calls
fileManager.trashFile() on the hex folder (if it exists), removes the map
entry from settings, reassigns defaultMap/activeMapName to the next available
map, saves, and re-renders. Cancelling returns to normal without changes.
Fixes#3 — map entries left dangling after manual folder deletion are now
cleanly removable through the UI.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New SetupWizardView (ItemView): 4-step welcome → folders → map → done
- Wizard auto-opens on first install (setupComplete/setupDismissed flags)
- Folder step creates all world subfolders and ensures hex template exists
- Map step creates the first hex grid; done step shows recommended next steps
- "Open hex map" from done step opens map with terrain picker + toolbar open
- Re-run wizard button added to settings tab
- Fix: loadAvailableIcons() now runs inside onLayoutReady (vault readiness)
- Fix: migrateHexFilesToDefaultRegion() no longer creates world/hexes/default
on fresh installs — scans candidates first, early-returns if none found
- Fix: loadHexTemplate() falls back to built-in default instead of returning null
- Fix: terrain toolbar button re-opens picker when clicked while active
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>