Commit Graph
61 Commits
Author SHA1 Message Date
Gert Pellin 39e7fb1d4f Export: PNG with a transparent background (#784)
The renderer lays every slide background over white (as PowerPoint does),
so a PNG export was always opaque. A new transparentBackground option leaves
the slide background out (both the white underlay and the background fill),
so only what is on the slide is drawn over transparency. Shapes filled with
the background (useBgFill) still show it.

- render: RenderOpts::transparent_background
- engine: file.export {transparentBackground} (PNG only; other formats
  refuse it and write nothing), file.render {transparentBackground}
- UI: Transparent background checkbox in the Export dialog (PNG) and in
  File > Export > Change File Type > PNG; the web download honours it
- CLI: render --transparent
2026-10-16 16:30:52 +02:00
midasmatterhorn 2568c55afa control: a request that timed out while queued is abandoned, never run late (#719) 2026-10-15 00:37:58 +03:00
Brandon Thomas 081c9fdc5e Merge the landing branch into land-r7
# Conflicts:
#	apps/deckcraft-cli/src/main.rs
#	apps/deckcraft-cli/tests/cli.rs
#	crates/engine/src/cmd/file.rs
#	crates/engine/src/cmd/text.rs
#	crates/engine/src/lib.rs
#	crates/engine/src/tests.rs
#	crates/ui-egui/src/canvas.rs
#	crates/ui-egui/src/lib.rs
#	crates/ui-egui/src/textures.rs
2026-10-14 15:34:15 -04:00
Brandon Thomas 9fc910886c Merge PR #247 from isaac-levine: MCP: confine file access with --automation-read-root and --automation-write-root
# Conflicts:
#	apps/deckcraft-cli/src/main.rs
#	crates/engine/src/cmd/file.rs
#	crates/engine/src/lib.rs
2026-10-14 15:25:09 -04:00
Brandon ThomasandClaude Opus 5.5 d66833b7c2 Fix up merged PRs: land-r6's changes fitted to the landing branch
- review.thesaurus's params doc parses under describe's grammar; describe's edit.copy test
  expects the landing branch's {text, html?} answer.
- The Language dialog test picks the landing branch's "Français (France)" entry; the Format
  Background test allows the pane's title to appear twice.
- Progress docs rebuilt from the landing branch's versions with land-r6's rows applied on top,
  so the union merge no longer drops the pen-pressure, ui.pointer and ui.key rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 15:23:16 -04:00
Brandon Thomas 91eb9d8884 Merge the landing branch into land-r6
# Conflicts:
#	crates/engine/src/tests.rs
#	crates/engine/src/tools.rs
#	crates/ui-egui/src/canvas.rs
#	crates/ui-egui/src/dialogs.rs
#	crates/ui-egui/src/lib.rs
#	crates/ui-egui/src/panes.rs
#	crates/ui-egui/src/ribbon.rs
#	crates/ui-egui/src/status.rs
#	crates/ui-egui/src/textures.rs
#	crates/ui-egui/src/thumbs.rs
2026-10-14 15:14:21 -04:00
Brandon Thomas f800acee47 Merge the startup, clipboard, animation-preview and UI PRs integrated on land-r5 (#644 #652 #655 #702 #571 #539 #674 #648 #697 #479 #369 #368)
# Conflicts:
#	crates/ui-egui/src/canvas.rs
#	crates/ui-egui/src/ribbon.rs
2026-10-14 14:58:48 -04:00
Brandon ThomasandClaude Opus 5.5 afc387cdc5 Merge PR #468 from NikitkaRa: Media: a failed or stalled audio output hands the clock back to wall time (#417)
Fix-up in the merge (review): a just-started stream gets 5 s for its first callback before it
counts as stalled (slow Bluetooth devices), and the failure count resets once a restarted
stream delivers, so one bad start no longer silences media for the session.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 14:57:54 -04:00
Brandon ThomasandClaude Opus 5.5 ed13dd6158 Fix up merged PRs: GIF export goes through main's export path
The Export dialog's GIF choice runs through SlideApp::export_as (desktop and web download),
.gif is a writable output extension for convert/run, and the CLI help pages describe GIF output
and --export-params. A file.export `slides` range string ("1-3,5") works for GIF as for PDF.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 14:54:35 -04:00
Brandon Thomas c354f02279 Merge PR #177 from Mathiasko: Export: animated GIF of the deck (Export… dialog, CLI, MCP) (#171)
# Conflicts:
#	apps/deckcraft-cli/src/main.rs
#	crates/engine/src/cmd/file.rs
#	crates/engine/src/lib.rs
#	crates/mcp/src/tests.rs
#	crates/mcp/src/tools.rs
#	crates/ui-egui/src/dialogs.rs
2026-10-14 14:52:34 -04:00
Brandon Thomas e9923c6c42 Merge PR #368 from NikitkaRa: A tabbed slide body is an outline, and --help exits (#360)
# Conflicts:
#	apps/deckcraft/src/main.rs
#	crates/engine/src/cmd/slide.rs
#	crates/engine/src/cmd/text.rs
2026-10-14 14:45:23 -04:00
Brandon Thomas 5fbdb6c79e Merge PR #479 from NikitkaRa: Web: keep a picked file on the document and slide that asked for it
# Conflicts:
#	crates/ui-egui/src/lib.rs
2026-10-14 14:43:55 -04:00
Brandon ThomasandClaude Opus 5.5 3b28496c36 Fix up merged PRs: main's newer params docs fit describe's grammar; help pages for bench and render-transition
file.export's slide range and transition.sound's keys parse as parameters, and the subcommands
main added since #303 have their own help page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 14:40:09 -04:00
Brandon Thomas 38e95d8c15 Merge PR #702 from NikitkaRa: Clipboard: rich text and pictures for Pages and Keynote
# Conflicts:
#	crates/engine/src/cmd/edit.rs
#	crates/ui-egui/src/lib.rs
2026-10-14 14:39:36 -04:00
Brandon Thomas b590cb0b0b Merge PR #303 from hoblin: deckcraft-cli help explains the CLI to an agent
# Conflicts:
#	apps/deckcraft-cli/src/main.rs
#	crates/engine/src/cmd/design.rs
#	crates/engine/src/cmd/file.rs
#	crates/engine/src/cmd/format.rs
#	crates/engine/src/tests.rs
2026-10-14 14:36:13 -04:00
Brandon Thomas 89da88e374 Merge PR #258 from RCShoemaker: fix(cli): render refuses an unknown option instead of writing it as a file (#235)
# Conflicts:
#	apps/deckcraft-cli/src/main.rs
#	contributors/people.toml
2026-10-14 14:34:57 -04:00
Brandon Thomas e406e11db2 Merge PR #444 from MarekSpodBiedry: CLI: render-transition refuses --t values that would share one file name (#423)
# Conflicts:
#	apps/deckcraft-cli/src/main.rs
2026-10-14 14:33:40 -04:00
Brandon ThomasandClaude Opus 5.5 8ee597216d Fix up landed PRs from review
- #178: ToUnicode ranges looked up without indexing
- #465: frame_num gaps are concealed (bounded) even when the SPS forbids them; cut streams keep playing
- #471: control request lines up to 256 MB so picture/media inserts still fit
- #473: a merge that loses its only row or column is removed, with regression tests
- #521: AutoCorrect no longer rewrites real words (cant, wont, im)
- #654: inherit_placeholder_geometry's doc comment back on its function

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 14:31:01 -04:00
Brandon Thomas a0d97fa931 Merge PR #644 from NikitkaRa: Startup: survive damaged settings, font folders, recovery folders and small texture limits
# Conflicts:
#	crates/engine/src/recovery.rs
#	crates/fonts/src/fontdb.rs
#	crates/fonts/src/lib.rs
#	crates/ui-egui/src/lib.rs
2026-10-14 14:24:45 -04:00
Brandon Thomas fca521ac8c Merge PR #471 from NikitkaRa: Control server: bound connections, line length, queue and socket timeouts (#418) 2026-10-14 14:24:15 -04:00
Brandon Thomas 8ea2cb0871 Merge PR #361 from NikitkaRa: CLI: say that render --slide counts from 0 (#359)
# Conflicts:
#	apps/deckcraft-cli/src/main.rs
2026-10-14 14:12:10 -04:00
Brandon Thomas 2009242055 Merge PR #684 from NikitkaRa: Export: a PNG or JPEG slide records 144 dpi at the default 2× size
# Conflicts:
#	crates/engine/src/cmd/file.rs
#	crates/engine/src/tests.rs
2026-10-14 14:02:59 -04:00
Brandon Thomas f52bcfa1c8 Merge PR #530 from NikitkaRa: Design: Browse for Themes from a .thmx, .pptx or .potx file
# Conflicts:
#	crates/ui-egui/src/lib.rs
2026-10-14 13:36:45 -04:00
Brandon Thomas 6a8922ac49 Merge PR #661 from NikitkaRa: Startup: fall back to Wayland when DISPLAY names no X server 2026-10-14 13:09:05 -04:00
Brandon Thomas 3a5153a1d0 Merge PR #564 from NikitkaRa: Performance baseline: deckcraft-cli bench and cargo xtask bench 2026-10-14 13:08:54 -04:00
Brandon Thomas f8d52f6fbe Merge PR #308 from marcoarnulfo: macOS: end the process in on_exit so closing the window doesn't crash 2026-10-14 12:57:23 -04:00
Brandon Thomas 8d8cbeb123 Merge PR #179 from MarekSpodBiedry: CLI: --help prints usage and unknown render flags are rejected (#163) 2026-10-14 12:57:20 -04:00
Brandon Thomas 40231d8114 Merge PR #176 from itrycodinganditsbad: Windows: compile DX12 shaders with FXC 2026-10-14 12:57:20 -04:00
Gert Pellin cf640c4b08 CLI: convert and run refuse output formats DeckCraft can't write (#715)
convert, run --save and run --export picked the format from the output
extension and fell back to native .deckcraft bytes for any extension
they didn't know, so out.odp, out.gif, out.svg and out.outline were
zips with exit status 0. They now fail before writing anything, with
the extension and the supported ones in the error.
2026-10-14 13:07:49 +02:00
Nikita RakitinandCursor 5d9f47c81a Clipboard: rich text and pictures for other apps
Copy puts HTML on the pasteboard with the same plain words, so Pages keeps
bold, italic and underline, and a paste of that HTML keeps them here. A
shape with no text copies out as a picture.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 06:37:49 +03:00
Nikita RakitinandCursor d04df05249 Export: record slide resolution in PNG and JPEG pictures
A default export is 2 pixels per point. Without a resolution, Preview
treats those pixels as 72 dpi and the picture opens at twice the slide's
size. PNG pHYs and JPEG JFIF density now say scale times 72, so the
default is 144 dpi. Screenshots stay untagged.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 05:35:37 +03:00
Nikita Rakitin 0c84b0434d Merge remote-tracking branch 'origin/main' into m-359-cli-slide-index
# Conflicts:
#	apps/deckcraft-cli/src/main.rs
2026-10-14 05:16:53 +03:00
Nikita RakitinandCursor fcb5eae1a5 Startup: fall back to Wayland when DISPLAY names no X server
DeckCraft forces X11 whenever DISPLAY is set. A stale DISPLAY (an ended ssh -X session, or
Xwayland turned off) made start-up fail with "failed to open display" while a Wayland
compositor was running. A local DISPLAY whose /tmp/.X11-unix socket is missing now starts on
Wayland when WAYLAND_DISPLAY is set; remote displays and live servers keep X11. Forcing Wayland
without a compositor keeps X11, and with no display at all the error says so plainly.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 04:21:30 +03:00
Nikita RakitinandCursor c583480010 Startup: survive damaged settings, font folders, recovery folders and small texture limits
- ui.json / prefs.json are read through a new settings module: regular files only, 4 MiB
  cap, parse errors logged, values sanitized (a saved zoom of 1e30 aborted start-up,
  1e4 panicked in egui); writes are atomic.
- The canvas and the control protocol clamp stray zooms; the status bar shows the zoom in use.
- The canvas texture is cut to the GPU's max texture side (zoom 400% on a 2048 limit panicked).
- The system font scan opens only regular files of sane size (a FIFO named *.ttf in ~/.fonts
  hung start-up), with depth and entry caps.
- AutoRecover skips non-regular entries and reopens at most 32 per start, newest first.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 03:27:57 +03:00
Nikita Rakitin 5bdfc3228d Add a performance baseline: deckcraft-cli bench and cargo xtask bench
Times open, per-slide render, save, the PPTX round trip and PDF export, and
reports peak memory; xtask builds the CLI in release, runs it on the sample
and any given decks, and compares with docs/benchmarks/baseline.json.
2026-10-14 00:05:47 +03:00
Nikita RakitinandCursor 30c2fe4b6d Design: Browse for Themes from a .thmx, .pptx or .potx file
deckcraft_pptx::import_theme reads the theme of a .thmx (its main document is
a theme part) or of a presentation's first master, with the media its format
scheme uses. design.browseTheme {path | name, data} applies it to the current
master as one undo step, giving the theme's pictures ids of this deck.

Design tab: Browse for Themes… next to the theme gallery and in the Slide
Master Themes menu; the desktop picker offers Office Theme (.thmx) and
presentations. Ribbon small buttons expose their label to accessibility (same
change as #512). Parity row Browse themes M → D.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-13 23:04:41 +03:00
Nikita RakitinandCursor 8bab5c2053 Web: keep a picked file on the document and slide that asked for it
The browser file picker only queued a name and bytes. When the read
finished, DeckCraft guessed the command and ran it on whichever
document and slide were active, so a picture, sound or outline could
land in the wrong place, and a later pick could finish first.

The request now keeps the document, the slide or master, the operation
and a cancellation id. A completion applies there, or is dropped when
that target is gone or the picker was dismissed.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-13 20:53:10 +03:00
Nikita RakitinandCursor 8dc068e0ba Control server: bound connections, line length, queue and socket timeouts (#418)
The loopback control server spawned a thread per connection, read
unbounded lines, queued requests without limit and set no socket
deadlines. It now caps simultaneous clients (16) and request lines
(16 MiB), uses a bounded request queue (64) that answers busy when full,
closes sockets idle for 10 minutes or blocked on a write for 30 seconds,
and frees a connection slot whenever a client thread ends.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-13 20:39:36 +03:00
Nikita RakitinandCursor 952ebad3cf Media: a failed or stalled audio output hands the clock back to wall time (#417)
A cpal stream error was only kept and logged on stop, and the player kept
`streaming` true, so a device that died mid-play froze the voice and video.

AudioOut gains `failure()` (CpalOut reports DeviceNotAvailable), and
Player::tick also treats a stream with no callbacks for a second while a
voice plays as stalled. Either way the stream is stopped, voices continue on
the wall clock, and the next play retries the device; after three failures
the player gives up on the device and plays silently.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-13 20:27:21 +03:00
MarekSpodBiedry eff88eaf59 CLI: render-transition refuses --t values that would share one file name (#423) 2026-10-13 17:34:17 +02:00
NikitaandCursor 503ee5d67e A tabbed slide body is an outline, and --help exits (#360)
slide.new kept a leading tab as text, while text.set already turned it into a bullet level. The desktop --help flag was opened as a missing file.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-13 12:38:57 +03:00
Brandon ThomasandClaude Opus 5.5 d5e30557eb Transitions like PowerPoint: measured frame by frame and retuned (#366)
Every transition and Effect Option was built in PowerPoint (COM), exported as
video and compared frame by frame with DeckCraft at the same progress
(mean abs diff over 150 variants 35.7 -> 15.0, 0-255).

- anim: transition_frame(kind, option, t, aspect) with measured curves
  (smoothstep fades, ease-in-out moves, Cover/Uncover/Pan curves), directions
  and option meanings, soft edges as per-corner opacity, 3-D effects as
  perspective-projected cards, Dynamic Content moving slide contents over
  cross-fading backgrounds (Source::OldBack/NewBack/OldContent/NewContent);
  layer_mesh subdivides perspective quads so textures stay straight.
- New options: Page Curl Single, Glitter Hexagons, Shred In/Out, Zoom and
  Rotate; PowerPoint-style Effect Options labels.
- render: composite_transition (CPU twin of the show), render_slide_part,
  render_transition; deckcraft-cli render-transition FILE --slide N --t T.
- show: per-vertex opacity meshes, slide parts rendered once per transition.
- pptx: PowerPoint's elements and defaults (p:strips diagonal wipes, p14:warp
  and p:newsflash for Zoom, p:zoom for Shape In/Out, glitter pattern, shred
  rectangle/dir, prstTrans invX per preset, pageCurlSingle, defaults for
  randomBar/doors/window/pan/zoom); PowerPoint reopens DeckCraft's files with
  the same effects.
- Tests: measured curves, probes of which slide shows where at t, option
  coverage, per-frame triangle budget, PowerPoint XML and defaults round trip.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 05:31:13 -04:00
NikitaandCursor 18e47d1af7 CLI: say that render --slide counts from 0 (#359)
--all names files slide-01.png onward, so --slide 8 on an 8-slide deck looked like an off-by-one. The index stays 0-based, matching slide.go, and the error now gives the range and the file names.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-13 11:55:00 +03:00
Yevhenii Hurin 922445300b describe keeps a remark with its option and allows a bare call
animation.remove's remark belongs to its `ids` option, so describe shows
it there instead of as a note on the whole command. A command with an
all-optional set of parameters is suggested as a bare id.

[claude-opus-5-5] on behalf of hoblin
2026-10-13 09:55:19 +03:00
Yevhenii Hurin 66f7e6e1ed Self-review: no ID[=JSON] left, params grammar documented
A --cmd without a value now asks for COMMAND[=PARAMS]. The params field
says how describe reads it, table.split's row and col are optional as
the command reads them, and the MCP instructions name only shape
commands for `ids`.

[claude-opus-5-5] on behalf of hoblin
2026-10-13 00:15:53 +03:00
Marco Arnulfo e3d9803069 macOS: end the process in on_exit so closing the window doesn't crash (fixes #279)
Same fix as storytold/gridcraft#117 (storytold/gridcraft#316): eframe drops
the window while AppKit's run loop still runs, AccessKit restores the
content view's class and AppKit's Touch Bar KVO observer throws on the
next display cycle. on_exit now ends the process on macOS once the
preferences are saved.
2026-10-12 23:12:03 +02:00
Yevhenii Hurin 717e855cec deckcraft-cli help explains the CLI to an agent
`deckcraft-cli help` and each subcommand's `--help` say what it does,
with a working example; `--help` never runs the subcommand. `describe`
spells out a command's parameters and what it acts on, `commands` lists
one command per line, and the MCP instructions say what format.* acts on.

[claude-opus-5-5] on behalf of hoblin
2026-10-12 23:41:42 +03:00
Ryan C. ShoemakerandClaude Opus 5.5 30a5ee202d fix(cli): render refuses an unknown option instead of writing it as a file (#235)
`deckcraft-cli render` took any argument it didn't recognise as the output
path, so `render deck.pptx --help` rendered the slide into a file named
`--help`, and a mistyped option was silently ignored. An argument starting
with `-` that render doesn't know is now an error naming it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:42:53 -06:00
Isaac Levine f3ae32d920 CLI: add --automation-read-root and --automation-write-root to mcp 2026-10-12 09:58:07 -04:00
MarekSpodBiedry c1ab5d3c43 CLI: --help prints usage and unknown render flags are rejected (#163) 2026-10-11 23:37:38 +02:00