Conversation
Add a Preferences → General → Appearance section with a Theme dropdown (System / Light / Dark) and an accent color picker, applied live with no restart. - Tokenize src/style.css to @define-color refs (~180 hex literals → ~14 families); media-viewport surfaces and semantic status colors stay literal. - New src/ui/theme.rs builds the stylesheet at runtime (light/dark header + accent with derived hover/active shades) into one re-loadable CssProvider. System mode resolves and watches the XDG org.freedesktop.appearance color-scheme portal (live SettingChanged, dark fallback). - Accent drives CSS chrome plus the Cairo timeline selection highlight via runtime accent in colors.rs (set_selection_accent + selection_fill/border, replacing the COLOR_SELECTION_* consts). - ThemeMode (default Dark) + accent_color persist in PreferencesState with backward-compatible serde defaults. - Timeline / program-monitor / scopes canvases stay on the dark editing palette in all modes (standard NLE behavior). 9 new unit tests; 1466 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a fourth "High Contrast" option to Preferences → General → Appearance (ThemeMode::HighContrast), built on the runtime theme system: - Pure-black palette (HC_HEADER): black surfaces, white text, bright #ffffff borders. - HC_EXTRA rules, appended only in this mode: prominent :focus-visible accent outlines, stronger control borders/separators, and small-text floors that raise the 10/11px utility classes to a readable 13px without shrinking display text (preserves the type hierarchy). Applies live with no restart; timeline/monitor/scopes stay dark; accent drives the focus/selection colors. +1 unit test; 1467 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Groundwork for native-Rust AAF (Pro Tools / Avid) export. AAF is a binary
Compound-File container wrapping the AAF object model; every file must embed
the full AAF MetaDictionary, which readers (pyaaf2, the Avid SDK) require.
Rather than reimplement the fixed metadictionary, embed a pyaaf2-generated
skeleton (header + full metadict + empty ContentStorage.Mobs) and append the
dynamic Mob graph into it with the `cfb` crate.
- Add `cfb = "0.14"`; register `mod aaf;`.
- src/aaf/{mod,ids,encode,writer}.rs scaffold + embedded template.aaf.
- encode.rs: AAF properties-stream encoder + UTF-16 string encoder.
- ids.rs: stored-form codes + property-stream version constants (from pyaaf2).
- writer.rs: write_aaf / build_aaf_bytes entry points (skeleton passthrough).
Risk retired: the Rust cfb crate opens pyaaf2's 450KB container, reads its
storages, and round-trips it with added storages/streams. 4 new tests; 1471
tests pass. Object-graph encoders (slots, sequences, source clips, descriptors,
index streams, weak refs) follow.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Decode the AAF structured-storage binary format from a pyaaf2 reference file and implement the encoders, each asserted byte-for-byte against the captured reference bytes: - encode.rs: scalar encoders (u32, i64, Rational, 32-byte MobID w/ fixed prefix), UTF-16 strings, weak object references (refIndex/keyPid/key), and both strong-ref index-stream formats — vector (count/nextfree/keys) and set (+ keyPid/keySize + per-entry localKey/refCount/key). - ids.rs: class CLSIDs, property IDs, stored-form codes, and DataDefinition AUIDs (Sound/Picture/Timecode), ported from pyaaf2 (MIT) and cross-checked against the reference. Key finding baked in: the embedded skeleton already carries the full metadictionary, the Dictionary DataDefinitions, and the /referenced properties path for DataDefinition (index 2) — so the writer only appends Mobs and never touches those shared structures (ContainerFormat omitted as optional). +8 tests (all assert vs pyaaf2 reference bytes); 1479 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Build the dynamic AAF object graph into the embedded skeleton with the cfb
crate: a CompositionMob (one TimelineMobSlot per audio track — a Sequence of
Filler gaps + SourceClips — plus a flattened video-reference slot and a
Timecode slot) and one SourceMob per unique source file (PCMDescriptor for
audio, ImportDescriptor for the video reference) each with a NetworkLocator to
the external file:// URL. Linked media; no embedded essence.
Strong-ref sets/vectors are appended by writing <base>{N} storages + rewriting
the <base> index stream; the parent property streams are untouched. CLSIDs set
via uuid (cfb's GUID-LE field order round-trips pyaaf2's class ids). Edit-unit
lengths: samples for audio, frames for video (reusing edl timecode helpers).
Validated end-to-end: pyaaf2 reads the output with full fidelity — tracks,
edits, sample-accurate clip lengths, gap fillers, MobID references, linked
media URLs, and timecode. New tools/validate_aaf.py (pyaaf2 round-trip) is the
dev/CI gate. +2 Rust tests; 1481 tests pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- toolbar.rs: "Export AAF…" entry in the Export ▼ popover (FileDialog, *.aaf filter) calling crate::aaf::writer::write_aaf, mirroring Export EDL. - MCP save_aaf tool: schema + dispatch (server.rs), SaveAaf command (mod.rs), handler (mcp_handler.rs). - cargo-sources.json: vendor cfb + web-time (archive + checksum) for Flatpak offline builds. - CHANGELOG + ROADMAP (line 703 checked off). App launches cleanly with the new menu; pyaaf2 validates exported files. 1481 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.