Commit Graph
135 Commits
Author SHA1 Message Date
Brandon ThomasandClaude Opus 5.5 eb59ec09da Release 0.17.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 19:25:46 -05:00
Brandon ThomasandClaude Opus 5.5 77adc30a75 Release 0.16.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 13:57:45 -05:00
5ed4952d43 Add shared custom colors and complete marker editing (#1435)
* M3: Add shared custom colors and complete marker editing

* #1435: refine native colors and range endpoint flags

Use the macOS Colors panel for custom label colors and reuse the established egui picker on other hosts. Preserve draft confirmation, exact sRGB values, native text shortcuts and project ownership. Compact the swatches and center the add control, split range glyphs across their endpoints, localize the new controls, protect newer marker edits from stale dialogs, and cover the behavior with rendered UI and hit-test regressions.

Co-authored-by: Codex <noreply@openai.com>

* #1435: preserve imported palettes and marker double-click ownership

Union saved OTIO palettes across timelines with deduplication, bounded capacity,
first-name preservation and explicit overflow warnings. Keep null authors
consistent with omitted fields, and consume marker double-clicks before the
work-area gesture so opening the editor does not alter project history.

Correct the CSV URL column and schema documentation. Add six regressions for
palette retention/capacity, author handling, and physical overlapping gestures.

Validation: full cargo xtask ci (3666 passed, 45 skipped), 42 rendered UI tests,
and strict workspace/all-target Clippy on Rust 1.99.1.

Co-authored-by: Codex <noreply@openai.com>

* #1435: retain OTIO swatch names and generator labels

Ignore orphan name entries when retaining saved palette names so input ordering
does not hide valid names after the first 64 entries. Keep names bounded by the
retained palette and preserve existing valid names.

Include generator preset labels alongside custom label colors in OTIO metadata.
Add regressions for orphan-prefixed name maps and three generator kinds with
preset/custom colors through actual export/import round trips.

Validation: both regressions failed before fixes; all 72 interchange tests and
full cargo xtask ci pass (3668 tests, 45 skipped), plus strict workspace/all-target
Clippy on Rust 1.99.1.

Co-authored-by: Codex <noreply@openai.com>

* #1435: preserve distinct OTIO generator item identity

Use exported FilmCraft item IDs for generator media identity so identical
content can retain distinct source names, labels and custom colors. Repeated
references to one source item still share a single imported media entry.

Preserve content-based fallback for missing or invalid item IDs. Cover black
video, bars and tone, and color mattes with distinct items/shared references,
plus legacy and malformed identity metadata.

Validation: distinct-generator regression failed before fix; legacy compatibility
passed. All 74 interchange tests and final full cargo xtask ci pass (3670 tests,
45 skipped); strict workspace/all-target Clippy also passes on Rust 1.99.1.

Co-authored-by: Codex <noreply@openai.com>

* #1435: align Edit Marker layout and add safe marker navigation

Give the editor a wide aligned form, larger Notes area, side action column,
and grouped palette with vertical marker types. Expand the Web Link field
with the form and keep actions accessible in small windows.

Previous/Next saves valid edits as one Undo step and stays with the original
sequence/source owner, including coincident markers. Invalid drafts stay open;
unchanged navigation and Done add no history. Keep native/shared color pickers,
Author, Notes, URL validation and immediate marker creation.

Validation: all 45 rendered sequence/marker UI tests pass, including five new
navigation/owner/validation/layout regressions. Native macOS layout, picker
Cancel and exact single-step Undo restoration verified. Full standard cargo
xtask ci passes 3675 tests (45 skipped), doctests and all remaining gates;
strict Rust 1.99.1 workspace/all-target Clippy also passes.

Co-authored-by: Codex <noreply@openai.com>

* #1435: refine Edit Marker proportions and action alignment

Narrow the dialog to 680 logical pixels and keep the core order Name,
Time/Duration, Notes, Color and marker type. Place Author after the type-specific
options as secondary metadata. Preserve our palette, custom picker and range controls.

Use consistently sized, centered rounded action buttons with a primary Done action.
Shorten Delete Marker to Delete and remove the navigation helper and unused translations.
Keep the existing navigation save/validation/Undo semantics and automation IDs.

Validation: all 45 rendered marker/sequence UI tests pass, including small-window
action accessibility. Actual macOS layout and no-op Previous/Next/Cancel verified.
Full standard cargo xtask ci passes 3675 tests (45 skipped), doctests, formatting,
Clippy, translations, layers, assets and 49 WASM crates. Strict Rust 1.99.1
workspace/all-target Clippy passes separately.

Co-authored-by: Codex <noreply@openai.com>

* #1435: tighten marker layout and validate text editing

Use a narrower aligned form with Author below Name, bounded scrolling Notes,
left-aligned colors, centered actions and an inline Web Link URL/open icon.
Remove the legacy Flash Cue choice while preserving imported marker types.

Constrain timecode typing/paste to complete numeric colon-separated fields,
validate drop-frame labels and frame bounds, and disable Done for invalid timing.
Preserve high-frame-rate timecodes and point-marker semantics when Duration is
unchecked. Route native/menu clipboard and text Undo commands to focused fields;
explicit engine commands retain project Undo and selection semantics.

Validation: standard cargo xtask ci passes 3679 tests (45 standard skips),
doctests, fmt, strict workspace/all-target Clippy, i18n, layers, 69 assets and
49 WASM crates. Also passed 48 rendered marker/sequence tests and strict Rust
1.99.1 Clippy. Actual macOS clipboard, bounded Notes, point save and exact Undo
were checked. Windows/Linux desktop interaction remains pending.

Co-authored-by: Codex <noreply@openai.com>

* M0: Wait for frame-worker recovery before asserting

Do not treat a nonempty request queue as proof of worker death in the
panic-recovery regression. Keep waiting for all injected faults and enough
post-fault completions, then drain the queue without adding more seeks.
Retain the exact fault-count, successful-recovery and empty-queue assertions
and bound the wait with a two-minute deadline.

The inherited test failed twice in independent fork CI. It did not reproduce
locally: baseline passed 20 normal and 10 delayed-report runs; the repair
passed 50 normal and 10 delayed-report runs. No product or marker UI changes.

Validation: standard cargo xtask ci passed all 4485 tests (52 standard skips),
doctests, formatting, strict workspace/all-target Clippy, i18n, layers,
69 assets and 49 WASM crates.

Assisted-by: OpenAI Codex

---------

Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <codex@openai.com>
2026-11-01 03:04:14 +01:00
aiongg 477c983694 updates: show check results with craft-update's CheckResultDialog 2026-10-31 04:42:43 +00:00
Brandon ThomasandClaude Opus 5.5 94ceaa91a5 Release 0.15.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 23:22:55 -04:00
Dylan M. Taylor fed0f42fd5 UPD.1: honor app pretend versions in update checks (#3668) 2026-10-30 02:58:39 -04:00
Dylan M. Taylor 45d6a68077 Update prompt shows the app icon and accent color instead of a letter (#3663)
UPDATE_APP (native builds; craft-update is a native-only dependency) carries our 128 px icon and accent (#8b5cf6, its colour in ArtCraft Launcher). The updater, the self-update
helper and craft-update's startup prompt all get them through crate::UPDATE_APP; the
prompt draws the icon, the accent and "by ArtCraft" (craft-update's default developer).

craft-update is pinned to storytold/craft-libs main at 1065653e7 (#434).
Clippy fixes for Rust 1.99 in untouched code (same logic):
- crates/prores/src/decode.rs
- crates/ui-egui/src/panels/file_dialogs.rs
- crates/ui-egui/src/panels/timeline/interact.rs
- crates/ui-egui/src/panels/timeline/layout.rs
2026-10-30 01:27:42 -04:00
Brandon ThomasandClaude Opus 5.5 a2d8e9ce26 Release 0.14.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:09:21 -04:00
Dylan M. Taylor 6a5dacb0e9 Enforce workspace Clippy standards and document lint policy 2026-10-28 04:36:48 +00:00
aiongg 70375a3ee8 refactor(ui): use craft-ui's ComboBox for every dropdown (#3445)
* ui-egui: use craft_ui::ComboBox for dropdowns; repin craft-libs to 62bb0e1

* chore(deps): craft-libs 60d60d48 (dropdown fixes)

* chore(deps): craft-libs 6af63481 (dropdown fixes)

* chore(deps): craft-libs 4d7b82f7 (dropdown fixes)

* chore(deps): craft-libs 92d392cf (#387 merged)
2026-10-27 10:27:01 -04:00
aiongg 3a22804ddd craft-libs: pin every crate to b926b5c0 (craft-libs main with #355) 2026-10-26 03:27:23 +00:00
aiongg a43f19c006 Merge branch 'docking-frame-trial' into docking-ime
# Conflicts:
#	Cargo.lock
#	Cargo.toml
2026-10-26 02:29:30 +00:00
aiongg 5e8c321996 craft-libs: pin every crate to cd25951c (craft-libs#355: native floating windows publish their IME descriptor) 2026-10-26 02:23:53 +00:00
aiongg e58b48aef3 craft-libs: pin every crate to e8b4dde5 (craft-libs#340 stack, for craft_ui::ime::Composer) 2026-10-26 02:17:31 +00:00
aiongg 1f0ecaa138 craft-libs: pin every crate to 1e6f1278 (craft-libs main with #353) 2026-10-26 02:13:59 +00:00
aiongg 41883346d5 Merge remote-tracking branch 'upstream/main' into docking-frame-trial 2026-10-26 02:13:37 +00:00
aiongg 61ab638439 craft-libs: pin every crate to 1a14a680 (craft-libs#340 stack, for craft_ui::ime::Composer) 2026-10-26 02:11:01 +00:00
aiongg 2afdf2e1eb craft-libs: pin every crate to 37c907d2 (craft-libs#353: a drop beside a too-narrow frame at its row's edge) 2026-10-26 02:00:55 +00:00
Dylan M. Taylor fa0502602c build: pin craft-update to craft-libs main (495e597) (#3322)
Picks up the startup prompt without the glyphs a font may lack (storytold/craft-libs#343, #344): the close mark is painted and the version pill is ASCII, so apps that panic on a missing glyph no longer take the prompt down.

Part of tracking issue storytold/craft-libs#319
2026-10-25 17:55:43 -04:00
Dylan M. Taylor df106680d4 feat: startup update prompt modal and direct self-updating (#3298)
* feat: startup update prompt modal and direct self-updating

The update flow (check at start or on request, the startup prompt, the self-update worker) is craft-update's Updater; the app only supplies the suite, its close path and its status window. The check at start is opt-in for the desktop app, an install holds back while documents are unsaved, and the Windows update helper runs before argument parsing.

Ref: storytold/craft-libs#319

* build: refresh the lock

* fix(updates): drop the manual window's custom id; pin craft-update to craft-libs main (db19c37)

* fix(updates): address review feedback

Wake the UI when a manual check is queued from a menu callback; the update prompt owns the keyboard while it is open (LightCraft); Download opens through the desktop URL hook (FilmCraft); the Help menu dispatches through menus::invoke (FigCraft); print jobs and comment drafts hold an install back (WordCraft); Check for Updates is a registered command (GridCraft); an install holds back while documents are unsaved.

* fix(updates): localize the update status messages and format the sources

* fix(updates): give Check for Updates a Help menu hover hint
2026-10-25 16:22:56 -04:00
skylar taylor-barrickandDylan M. Taylor 320cae243d Migrate FilmCraft to egui 0.37 with current editing changes preserved (#3249)
* egui 0.37: migrate FilmCraft input and rendering integration

* egui-037: fix capture failures, UTF-8 input and hidden timing

* Fix screenshot crop scale for fitted native surfaces

* egui037: simplify UI helpers and preserve pointer IME cancellation

* Translate graphics and effect control accessibility labels

* egui037: Document capture and IME lifecycle contracts

* egui-037: document UI and input integration contracts

---------

Co-authored-by: Dylan M. Taylor <dylan@dylanmtaylor.com>
2026-10-25 14:45:04 -04:00
aiongg 75e89dffff Merge #3249 (egui 0.37) into docking-frame-trial 2026-10-25 17:16:31 +00:00
aiongg 217374ba5b docking: craft-libs 5bbe9f6 (main) 2026-10-25 16:58:17 +00:00
aiongg daeda75a11 Merge remote-tracking branch 'upstream/main' into docking-frame-trial
# Conflicts:
#	crates/ui-egui/tests/it/keyboard_ui.rs
2026-10-25 16:25:58 +00:00
aiongg 583fc2ebb9 docking: craft-libs d24e4bc (Mac round 3) 2026-10-25 14:02:11 +00:00
Brandon ThomasandClaude Opus 5.5 30536bc5d0 Release 0.13.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 09:26:28 -04:00
aiongg 364d0ba18f docking: craft-libs 8a503cf 2026-10-25 03:55:40 +00:00
aiongg 190f5def2f docking: craft-libs 865c9af 2026-10-25 02:55:01 +00:00
skylartaylor 4ce159e1cd egui037: migrate FilmCraft UI and reconcile current main 2026-10-25 02:59:42 +01:00
aiongg 2ff95d03d6 docking: craft-libs 6e7f285
Repins craft-docpath, craft-media and craft-ui to storytold/craft-libs 6e7f285. No API changes are needed.
2026-10-24 23:05:59 +00:00
aiongg 7f77bd7377 docking: craft-libs 16fb3d4 with shared docking and native windows
craft-docpath, craft-media and craft-ui pin storytold/craft-libs main at
16fb3d4, which has craft-libs#264 and the undock-hint fix craft-libs#285.
craft-ui builds with `native-windows`.
2026-10-24 18:50:09 +00:00
aiongg 6d3e6daeab Merge remote-tracking branch 'upstream/main' into docking-frame-trial
# Conflicts:
#	crates/ui-egui/src/panels/mod.rs
2026-10-24 18:47:25 +00:00
skylartaylor df5f86ae31 egui 0.37: migrate FilmCraft input and rendering integration 2026-10-24 11:13:28 +02:00
aiongg fa550ce2d0 Build: use craft-media for bitstream, isobmff and matroska (#2435)
* Build: use craft-media for bitstream, isobmff and matroska

filmcraft-bitstream, filmcraft-isobmff and filmcraft-matroska re-export
craft_media::{bitstream, isobmff, matroska} from craft-libs. The packages
and their public paths stay, so dependent crates build unchanged. The
integration tests in crates/isobmff/tests and crates/matroska/tests run
against the re-exports.

* Build: pin craft-media at 9db732e

craft-media spells the Matroska colour types in US English: Colour is
Color and VideoInfo::colour is VideoInfo::color. The spec names
element_ids::COLOUR, COLOUR_SPACE and VpcConfig::colour_primaries stay.

* matroska: the oracle skips the duration of a track's last frame

Ported from craft-media: the last audio or video frame of a track cut by
-t is shorter than a codec frame. ffmpeg 8 writes a shortened
BlockDuration and reports the codec frame duration; a remux by our writer
stores DefaultDuration and ffprobe reports the shortened one. Subtitle
cue durations are still compared. This fixes oracle::mjpeg_ac3 with
ffmpeg 8. The HDR test is named hevc_hdr_color, as in craft-media.

* matroska: laced_remux laces every audio track and checks timestamps

craft-media laces only tracks with a DefaultDuration. The remux gives
each audio track without one its mean packet spacing, so Vorbis, FLAC
and PCM lace too, and compares every packet's timestamp with the
source's. Ported from craft-media's oracle_matroska.rs.

* codecs: the Matroska audio timing test laces its Xiph case

craft-media laces only tracks with a DefaultDuration. The test's
Matroska helper sets the AAC access unit's duration (1024 samples,
rounded to the nanosecond), and the test checks that the Xiph-laced file
has laced blocks and the unlaced one has none.

* Build: repin craft-media to f97c84d27 (NAL length-size checks)

craft-libs#245 is on storytold/craft-libs main, so the dependency points there.

* Build: repin craft-media to f0ad6c1e1 (QuickTime v2 PCM entry limits)
2026-10-23 17:51:38 -04:00
aiongg 0a881266c8 CI: xtask ci in the dev profile, one test binary per crate, nextest (#2860)
* Tests: one integration-test binary per crate

Each crate with several tests/*.rs files keeps them as modules of tests/it/,
so cargo links one test executable per crate instead of one per file. Files
that change process-wide state or time a workload stay binaries of their own.

* Profiles: line tables for workspace crates, no debug info for dependencies

* Windows ARM64: nightly and on release pushes instead of every push to main

* xtask ci: clippy and tests in the dev profile

The release profile's thin LTO and single codegen unit made linking the test
binaries take most of the gate. The codec and audio crates stay at opt-level 3
in the dev profile, so their tests run at release speed.

* xtask ci: nextest, doctests, no examples, one wasm check

Tests run with cargo nextest when it is installed (cargo test otherwise) and
build with --lib --bins --tests, so examples aren't linked; doctests run
separately. The wasm check keeps going past the first failing crate. VP8
fixture generation locks across processes, since nextest runs each test in
its own.

* VP9 synthetic fixtures: write aside and rename

A test in another process could read a fixture ffmpeg was still writing.

* Fuzz tests: a third of each sweep by default, all of it with FILMCRAFT_FUZZ_ITERS

Every seed, mutation kind and thread count still runs. Header bytes each get
one overwrite value and two bit flips in rotation, so every value and bit
index still occurs across the region. FILMCRAFT_FUZZ_ITERS=N runs the whole
sweep plus N random rounds per seed, as before.

* Platform fallback tests: one failure point per hybrid path

The failure-anywhere test injected a failure at four points around every
restart point; the hybrid's paths differ only in the first GOP, around the
second and last restart points, at the end and never. The replay test needs
the first two GOPs.

* Export tests: shorter ranges with the same checks

The bitrate test measures 0.5–1.5 s, where each preset reaches its own
target (on 0–3 s the simple demo left two presets at the same rate). The
every-preset test exports three frames per preset.

* Audio tests: effects in parallel, a table-driven FFT for the Opus quality metric

The extreme-settings test keeps both settings and the 40 s tail for every
effect, one thread each. The Opus quality metric's FFT builds its twiddles
once and allocates nothing per transform (same algorithm and summation order).

* CI: dev-profile gate with nextest

xtask ci no longer builds with --release, so the release-profile overrides
go; nextest is installed for the test step.

* CI: apt packages through the cached install-apt-packages action

* Review fixes: fuzz tests with a panic hook in their own binaries, loud fixture lock

The fuzz tests of av1, h264, hevc, mpeg2v, vp8 and vp9 count panics through
a process-wide hook, so a panic in another test of the same process would
fail them; they are binaries of their own again. The VP8 fixture lock fails
the test instead of skipping it silently, and the full-sweep doc comments say
how many truncation points the full run samples.

* Fuzz tests: rotate the default subset per run (FILMCRAFT_FUZZ_SEED replays one)

* platform tests: decode-switch tests in their own binaries, one NVENC lock
2026-10-23 13:34:16 -04:00
Dylan M. Taylor c5c1693989 Use chrono instead of hand-rolled UTC conversion (#2662)
* Use chrono for UTC/calendar conversion instead of hand-rolled copies

Replaces the hand-rolled civil_from_days / days_from_civil copies (app log
timestamp, Media Browser date column, auto-save file-name stamp, MXF header
timestamp, golden-image attribution date) with chrono as a workspace
dependency. The existing chrono entry on apps/filmcraft (clock feature) was
lifted to the workspace. Output formats are unchanged and pinned by tests.
AGENTS.md now says time goes through chrono.

Follow-up to storytold/cadcraft#1785

* Never panic on a clock outside chrono's range; keep 5-digit years unprefixed

chrono's From<SystemTime> unwraps internally, so a clock past year 262143
panicked. logging::timestamp and golden::today now read the duration since the
epoch and go through the fallible DateTime::from_timestamp, reading an
out-of-range or pre-epoch clock as the epoch as the old saturating code did.
timestamp, today and media_browser::format_date write the year with {:04}
rather than %Y, which prefixes a '+' past year 9999.

Tests cover the far-future and year-10000 cases for timestamp and format_date.

* Don't build an unrepresentable SystemTime in the far-future test

UNIX_EPOCH + Duration::from_secs(u64::MAX / 2) overflows Windows'
SystemTime and panicked before timestamp() ran, failing the Windows
test job. Build it with checked_add and only assert where it exists.

* time: preserve out-of-range years instead of the epoch (FredApps review)

`DateTime::from_timestamp(..).unwrap_or_default()` changed the existing output:
inputs the old hand-rolled civil-from-days converted (e.g. `10_000_000_000_000`
s → 318857-05-20 17:46:40) collapsed to `1970-01-01 00:00:00`. Restore the old
conversion domain with a cycle-based helper: reduce by whole 400-year Gregorian
cycles (146_097 days), convert the in-range remainder with chrono, and carry the
year back as i128 (saturating to the output type). Only the year leaves chrono's
range; month, day and time of day are always exact.

Sites (all UTC):
- apps/filmcraft logging.rs `timestamp` (SystemTime, u64 secs): pre-1970 still
  clamps to the epoch; a far-future clock keeps its year. u64::MAX/2 s →
  "292277026596-12-04T15:30:07.000Z", 10e12 s → "318857-05-20T17:46:40.000Z"
  (was "1970-01-01..."). SystemTime cases built with a checked add (Windows-safe).
- crates/engine media_browser.rs `format_date` (u64): 10e12 s → "318857-05-20
  17:46", u64::MAX → "584554051223-11-09 07:00" (was "1970-01-01 00:00").
- crates/format autosave.rs `civil` (i64 + i32 offset): keeps years, e.g.
  i64::MAX → 292277026596-12-04 15:30:07, i64::MIN → -292277022657-01-27. The
  separate `unix + offset_secs` overflow guard (checked_add) is kept: only an
  overflowing shift (old code wrapped it to garbage) reads as the epoch.
- crates/mxf from_unix (i64): keeps month/day/time, clamps only `year` to the
  u16 field as before. 10e12 s → year 65535, May 20 17:46:40; -10e12 s → year 0,
  Aug 13 06:13:20.
- crates/testkit golden.rs `today` (u64): same helper; pinned via `utc_parts`.

chrono stays the only calendar logic (NaiveDate::from_num_days_from_ce_opt on the
in-cycle remainder). No new chrono features; still default-features = false, std.

* Name the 400-year range extension as the one exception to the time rule

The rule said never to hand-roll calendar math, but the range fix
(shifting by whole 400-year Gregorian cycles so dates past chrono's year
range keep their old output) is cycle arithmetic, so the rule and the code
disagreed. The rule now names that exception: the library still computes
month, day and time, and only whole cycles are carried in the year.

* Say the library computes month and day; time-of-day is plain arithmetic

Narrows the range-extension wording: the date library computes the
calendar fields, and splitting seconds into hours, minutes and seconds
is ordinary arithmetic, which is what the code does.
2026-10-23 11:18:37 -04:00
aiongg 6a017acf41 Merge remote-tracking branch 'upstream/main' into docking-frame-trial 2026-10-23 04:58:02 +00:00
Brandon ThomasandClaude Opus 5.5 274c4cf85b Release 0.12.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 20:06:07 -04:00
Brandon ThomasandClaude Opus 5.5 74242b51d6 Release 0.11.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 15:37:00 -04:00
aiongg 5963690cd3 UI.9: follow craft-ui docking at 958c5ad 2026-10-21 16:51:06 +00:00
aiongg 8525f836ad UI.9: follow craft-ui docking at 2fa4ad7 2026-10-21 16:30:24 +00:00
aiongg 9a590f0fcd UI.9: repin craft-ui to craft-libs 352a830 2026-10-20 15:49:18 +00:00
aiongg 218c03fd75 UI.9: repin craft-ui; a press on a sequence tab focuses the Timeline
Repin to the current storytold/craft-libs#187 head. A press in a group
header now focuses the shown panel, so clicking the Timeline's active
sequence tab focuses the Timeline.
2026-10-20 04:05:11 +00:00
Brandon ThomasandClaude Opus 5.5 cdf43fd366 Release 0.10.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:18:41 -04:00
aiongg 8466f6d8e0 UI.9: use craft-ui's tab wheel, middle click, edge dock and widget ids
Repin craft-ui to the current storytold/craft-libs#187 head. craft-ui now
steps tabs with the wheel, closes a tab on middle click (the Timeline's
tab still closes its active sequence), docks a panel at an edge without
an anchor, gives group_header_width the strip width, and names its
widgets and floating layers, so FilmCraft's own versions go. Panels float
at craft-ui's size. Dock dividers and grips keep keyboard focus after a
pointer drag, and shortcuts stay live while they have it.
2026-10-20 01:05:29 +00:00
aiongg 2a19266ba8 UI.9: draw panels with craft-ui shared docking (Frame profile)
craft-ui's DockArea draws the frames, tab strips, floating windows and
drag previews and owns the gestures. FilmCraft keeps its panels, the ≡
panel menu, the Timeline's sequence tabs (drawn in the Timeline's group
header), maximize keys, the wheel and middle click on tabs, and the
Timeline restored after close.

The layout is a craft-ui Layout; saved workspaces are craft-ui
Workspaces, and entries written before are still read. window.dockPanel,
window.floatPanel and window.closePanel run as craft-ui DockCommands,
and the window.panel.* commands route too. Automation ids for tabs, drag
bars, floating handles and dividers come from DockArea::hit_rects.

craft-ui is pinned to storytold/craft-libs#187.
2026-10-19 21:50:08 +00:00
Brandon ThomasandClaude Opus 5.5 4a69a038d3 Release 0.9.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 21:43:10 -04:00
skylar taylor-barrick 4f8464332f Build: take craft-docpath from the merged craft-libs rev
craft-libs#169 is merged, so the fork pin is no longer needed. Pinned to
storytold/craft-libs 82a24b006eefa036b43c09a67fb9a3fbd17ffe63 (main after the merge) rather than the older 12281d07,
which predates resolve_absolute and the Windows colon refusal.
2026-10-17 12:03:05 -06:00
aiongg ff66e124a4 Build: use craft-docpath from craft-libs 2026-10-17 02:20:44 +00:00
aiongg f565f7b38d fix(engine): follow stored media paths only on this computer or the project's share
Media and proxy paths read from a project file, a project template or an
interchange file are opened only when they name a local file or a file on
the network share the document itself is on (craft-docpath); a relative
path is taken from the document's folder. Other paths count as missing:
the item renders the offline slate with the reason, the open says how many
were not opened, and Link Media lists them. This covers the open-time
scan, rendering and proxies, the growing-files look and interchange
import. Files imported or linked in this session are opened as given.

The Scratch Disks folders use the same check, and Captured Audio and Video
(voice-over takes, pasted images, the default proxy folder) and Audio
Previews follow the rule Auto Save and Video Previews already follow.
2026-10-16 17:27:39 +00:00