44 Commits

Author SHA1 Message Date
Whatever Industries 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 5c18340e3f docs: tidy agent, contributor and asset docs 2026-10-31 04:17:32 +00:00
Dylan M. Taylor fed0f42fd5 UPD.1: honor app pretend versions in update checks (#3668) 2026-10-30 02:58:39 -04:00
Arshiya Rahgozar 4eed81bbc2 contributors: add names for marshiyar (#3596)
Adds my own entry to contributors/people.toml so the About window can show
"Arshiya" when the viewer picks Display name and "Arshiya Rahgozar" when
they pick Real name.

Tested: cargo build -p filmcraft-ui-egui (build.rs reads people.toml) and the
About/credits tests in filmcraft-ui-egui.

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-30 01:46:51 -04:00
Aryan 3590cd1bcf control: say why the control server is not serving (#3436) (#3535)
* control: say why the control server is not serving (#3436)

With --control but a missing or malformed FILMCRAFT_CONTROL_TOKEN the
server declined to start and said so only on stderr, which a desktop
launch has no reader for: the window opened, nothing listened, and the
bridge blamed the launch command.

- control server: log the disable reason and the listening state through
  log::warn!/log::info! so they land in filmcraft.log; start returns a
  typed Option<DisabledWhy> instead of hiding the reason
- desktop app: show the token reason in the status bar whenever it is
  idle (persistent but replaceable by any real status)
- --control-input-only: exit with an error when the server cannot start
  instead of parking a window that ignores all native input
- bridge: the connection-refused error names the token requirement
- i18n: status-bar string translated in the 8 active locales

Co-Authored-By: Claude <noreply@anthropic.com>

* control: drop the unused ControlNotice::Bind and its catalog rows

A bind failure is only logged until #3318; nothing constructed the variant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-30 01:46:18 -04:00
alexanderalber f6e329bb6c feat(text): strikethrough for graphic text (#3433)
* feat(text): strikethrough for graphic text

Text layers get a Strikethrough toggle next to Underline: per layer
(`strikethrough` parameter, Properties ▸ Text ▸ Style "S") and per
character (`graphics.setCharStyle` style `strikethrough`, stored in the
layer's style runs).

The stroke uses the font's OS/2 strikeout position and size; a font that
leaves them out gets a stroke centred on half the x-height. Strokes are
added to the layout's decoration rectangles next to underlines, so every
renderer and the path export draw them without further changes. Vertical
text gets a stroke down the middle of each cell.

generated with Claude Code

* contributors: add alexanderalber

generated with Claude Code

* graphics properties: draw the letter-button marks in a helper

Keeps the Properties scroll closure under the cognitive-complexity limit with the new
Strikethrough button.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 01:45:25 -04:00
Michael Butler d74379858d Export: preserve optional binary transparency in animated GIFs (#3396) (#3423)
* #3396: preserve binary transparency in animated GIF exports

Enable Include Alpha Channel for GIF with an explicit 128/255 threshold. Cover transparent, opaque and partial-alpha pixels, frame disposal and the Export UI. Document the behavior and add the requested username-only contributor credit.

Co-Authored-By: Codex <noreply@openai.com>

* #3396: clarify when the GIF alpha threshold applies

Begin the export hint with "When enabled," and wrap the longer label so its explanation remains visible. Alpha behavior and threshold wording remain unchanged.

Co-Authored-By: Codex <noreply@openai.com>

* #3396: cover GIF transparency during palette quantization

Round-trip two frames with more than 256 post-conversion RGBA colors, a moving isolated transparent pixel, and opaque black and near-black neighbors. Require exact alpha and bounded RGB error. Document commands for the GIF and export test suites; leave the encoder unchanged.

Co-Authored-By: Codex <noreply@openai.com>

---------

Co-authored-by: Codex <noreply@openai.com>
2026-10-30 01:22:02 -04:00
Brandon Thomas a469a4aeb7 Merge origin/main into #1271
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 01:10:44 -04:00
Brandon Thomas 138e972010 Merge origin/main into #1287 (frame_rate on the adjustment layer's FxCtx after #1327)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 00:10:18 -04:00
NetterSilver 4a75bc05fa Add my contributor entry 2026-10-12 12:11:07 +02:00
NDelic d74ed39c24 Contributors: add n-delic
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 11:18:07 +02:00
webdevtodayjason aff5e7f194 Contributors: add webdevtodayjason (Jason Brashear) 2026-10-11 22:13:01 -05:00
opentechnepal 3f9c1421d9 contributors: credit opentechnepal
Takes the display name from the GitHub profile (sync_github_name), so it
tracks the profile rather than a copy here.
2026-10-11 03:46:18 +02:00
Brandon Thomas 2ff3f5e266 Release prep: 0.6.0 and a Linux riscv64 release build (#830)
- release.yml: new `linux-riscv64` job, cross-compiled on ubuntu-24.04 against
  ports.ubuntu.com riscv64 libs (ported from GridCraft), tar.gz only, CLI
  smoke-tested under QEMU. Installs libasound2-dev:riscv64 for cpal/ALSA; the
  VA-API and NVDEC/NVENC paths are loaded with libloading at run time, so they
  need no riscv64 libraries. The draft-release job now needs it, so its tarball
  is uploaded and covered by SHA256SUMS.txt.
- packaging/linux/package.sh: CROSS_ARCH / CROSS_TARGET / CROSS_COMPILE /
  EMULATOR support, as in GridCraft.
- README and docs/releasing.md list the riscv64 tarball.
- cargo xtask version set 0.6.0 (Cargo.toml, Cargo.lock); refresh contributors.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 19:28:41 -04:00
Brandon Thomas 398befbeec Merge origin/main into #630: ROADMAP from main (restructured), contributors, German row for the new Project Notes menu
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 16:34:01 -04:00
Brandon Thomas e4f3cab5a0 Merge origin/main into #704 (gap and marker context menus side by side; contributors)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 16:27:48 -04:00
Oskar 24d555eb7c Merge upstream/main into fix/ripple-delete
Conflicts:
- contributors/people.toml: keep both new entries (maxm11, ossini)
- timeline.rs: take upstream's Alt-click through timeline.select (it
  clears the gap selection), and its empty-space arm (#683); only an
  empty stretch of a track selects a gap
2026-10-10 21:48:36 +02:00
vangel76 6067462b88 Merge upstream/main into fix-591-explicit-clip-errors 2026-10-10 21:13:24 +02:00
Oskar ac8b777447 contributors: add myself (ossini), shown with my GitHub profile name 2026-10-10 19:17:47 +02:00
Max Murphy cfebe8df14 Contributors: credit maxm11 (Max Murphy) 2026-10-10 10:20:45 -04:00
vangel76 1169ef2a93 contributors: credit vangel76
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 15:49:08 +02:00
Lukas Keller 63c9b17454 contributors: credit @keller-lukas as Lukas Keller
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 14:35:14 +02:00
Brandon Thomas be498865c3 Merge origin/main into fix/linux-dev-desktop-icon
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:12:41 -04:00
Brandon Thomas dc325d34c1 clip.link: clips without an overlapping partner stay unlinked; track kind worked out once
Merge origin/main (keep both contributor entries).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:38:35 -04:00
Brandon Thomas e2ebbe715e Merge remote-tracking branch 'origin/main' into fix-246 2026-10-10 06:18:20 -04:00
Brandon Thomas 63c10831ff Merge origin/main into fix/appearance-theme-name-471
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 05:12:48 -04:00
Brandon Thomas 4d3fe1bdb0 Merge pull request #506 from liangforstudy/fix/save-playhead
Project files: each sequence reopens with its playhead where it was left
2026-10-10 05:02:24 -04:00
Krzysztof Cieślik b6c604c104 clip.link: pair video clips with overlapping audio clips (#507)
When linking a selection containing multiple video clips, create one link
per video clip with its overlapping audio clips rather than a single link
for all clips, matching Premiere Pro behavior.
2026-10-10 04:21:06 +02:00
Brandon Thomas 7bd7621262 Bump version to 0.5.0 (from 0.4.0) for release; refresh contributors
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:02:11 -04:00
ReReddo 83da21acd1 contributors: credit ReReddo
Add ReReddo's own entry to contributors/people.toml, display name only, as
AGENTS.md asks of contributors. The name is shown once the maintainers'
contributors.py run verifies it.
2026-10-10 00:34:26 +03:00
liangforstudy 72e3eeb5de Project files: each sequence reopens with its playhead where it was left
The engine already keeps one playhead per sequence while a project is open, and the
project file's view already stores each sequence's zoom, scroll and track heights, but
not its playhead: after saving and reopening, every sequence started at zero.

ProjectView gains `playheads` (sequence id -> Tick), written beside the tabs and views
and restored with them when "Restore open sequences when opening projects" is on. Files
written before it have none and open as they did. Values from a file are not trusted:
ids that are not sequences are dropped, playheads are clamped to 0..ProjectView::MAX_PLAYHEAD
and snapped to a frame of their sequence.

Tests: each_sequence_reopens_with_its_playhead_where_it_was_left (fails without the
fix), hostile playheads in a_damaged_view_in_a_project_file_is_cleaned_up_or_ignored,
a deleted sequence's playhead is not written, and the format round trip carries it.

Also adds my contributor credit entry (people.toml).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qq8BK1LmohzE1ga4NgAdWM
2026-10-10 05:22:05 +08:00
user.email d8ef953f16 Merge branch 'main' into fix/linux-dev-desktop-icon 2026-10-09 23:08:04 +03:00
Brandon Thomas 6893b19314 Merge remote-tracking branch 'origin/main' into fix-368
# Conflicts:
#	contributors/people.toml
2026-10-09 09:57:52 -04:00
Brandon Thomas c21c86089f Merge remote-tracking branch 'origin/main' into fix-247
# Conflicts:
#	contributors/people.toml
2026-10-09 09:52:32 -04:00
Brandon Thomas 1b4b6fbffa Merge remote-tracking branch 'origin/main' into fix-368
# Conflicts:
#	contributors/people.toml
2026-10-09 09:40:15 -04:00
Brandon Thomas 96f76bac2a Merge remote-tracking branch 'origin/main' into fix-355
# Conflicts:
#	contributors/people.toml
2026-10-09 09:27:39 -04:00
Brandon Thomas 6e80bab6b8 Merge remote-tracking branch 'origin/main' into fix-359
# Conflicts:
#	contributors/people.toml
2026-10-09 09:26:08 -04:00
Bloxy 7401f5038b contributors: credit @ItzBloxy
My own entry for the About window: display name "Bloxy".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 12:17:08 +02:00
sanyamsingh001 0e0f0485da LINUX.VALIDATION: honor preset shortcuts and retain MPEG oracle frames
Resolve inherited physical key collisions when loading built-in presets,
while preserving established explicit winners and deliberate custom conflicts.
Read every ffprobe display-frame timestamp and register the requested credit.
Verify exact frame-plane reuse without depending on concurrent global metrics.

Co-authored-by: Codex <codex@openai.com>
2026-10-09 14:06:37 +10:00
ippsec c43d1090c1 contributors: credit IppSec by GitHub profile name
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 22:30:49 -04:00
swillunderscore 57d8990765 contributors: display name for @swillunderscore
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 21:19:21 -05:00
Gert Pellin d018fb9abb Contributors: credit switch87 as Gert Pellin 2026-10-08 11:27:34 +02:00
Ahmed Hosny 58ce158ed0 contributors: credit ahhosnyas (people.ahmedhosnypro) as Ahmed Hosny
Own entry in contributors/people.toml for the About window, per AGENTS.md.

🤖 Generated with [Kimi Code](https://github.com/storyteller/kimi-code)
Co-Authored-By: Kimi <noreply@storyteller.dev>
2026-10-08 11:39:09 +03:00
Brandon Thomas 87c4d1516e About: contributor and model credits compiled in (grab bag + table, self-submitted names) (#215)
* About: contributors compiled in from contributors.json (grab bag + table, sortable, name toggle)

Help ▸ About FilmCraft gets tabs About · Contributors · Models, following the craftrules standard
(standards/contributors.md): contributors/contributors.json is generated by
craftrules/scripts/contributors.py and baked into the binary by crates/ui-egui/build.rs as static
tables (nothing read at run time; the web build has them too). Each contributor line: @username,
opt-in display/real name, PRs, commits, lines +/−/Δ, binary assets +/−, first/last commit.
Sortable by every column; alphabetical ignores case and the leading @. Tabs and credits controls
register automation ids (about.tab.*, about.credits.*).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Contributors docs: craftrules is two levels up (../../craftrules)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Contributors: self-submitted names in contributors/people.toml; AGENTS.md credit-yourself section

build.rs reads contributors/people.toml next to the generated contributors.json and shows a name only
for entries the generator verified as written by that person (craftrules standards/contributors.md).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Contributors: regenerate (verified people.toml entries)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:16:52 -04:00