2.8 KiB
2.8 KiB
Contributing
- Language: Rust only. No JavaScript or TypeScript. On the web,
wasm-bindgengenerates a small loader; never hand-write JS. - Licence: contributions are MIT OR Apache-2.0 (
LICENSE-MIT,LICENSE-APACHE,NOTICE). The ArtCraft logos indocs/brand/are not open source (docs/brand/LICENSE-brand.txt). - Clean-room: do not copy code, shaders, icons, ICC profiles or other assets from proprietary software (such as Photoshop). Match behaviour and look by observation and public specs. Only use assets with permissive licences, keep their license next to the asset (e.g.
assets/fonts/OFL-*.txt,assets/icons/LICENSE-lucide.txt), and list every asset inATTRIBUTION.md. - Commands, not handlers: new features are engine commands with tests, and the UI calls them (checklist below).
- Layering:
cargo xtask layersmust pass. Register new crates inxtask/src/layers.rs. - Tests: required for every change. Format code needs round-trip and malformed-input tests. Pixel code is tested at 8, 16 and 32-bit.
- Style:
cargo fmt, andcargo clippy -- -D warnings. Match surrounding code. Comments explain why. - UI: use
theme::Tokensandwidgets::*. Verify visually (offscreensnapshotexample or the control channel) before submitting, and attach before/after screenshots to PRs. - Commits: small, focused, with a clear subject line.
Adding a command
- Find the id. Search
crates/ui-egui/src/menu_catalog.rsfor the Photoshop menu item. Using its id makes the menu item live with no UI work. Commands without a Photoshop menu entry use a descriptive id in the same style (layer.smartFilter.delete) and an empty menu path. - Algorithm goes in the lowest crate that fits (
algofor imaging,paint,vector,text,cms), with unit tests. It takes depth-agnostic surfaces (photocraft-raster), works per tile, and is deterministic (seeded randomness). - Command goes in an engine module (
crates/engine/src/<area>_cmds.rs) exposingspecs(), registered withv.extend(...)incommands.rs. Fill in:id,label,menupath and Photoshop's defaultshortcut,- a params doc string such as
{"radius":px=4,"mode":"a|b"="a"}(this is what agents read throughcommands/command_list), - an
enabledpredicate (greys the menu item out), run, which returns a JSON result and records exactly one history step (usecoalescefor drags and typing sessions).
- Respect the context: active selection (feathered), layer vs mask target, locks, the colour model and depth.
- Tests in the module: behaviour, undo/redo, disabled states, bad params, several depths.
- Dialog (if it has parameters): filters and adjustments get schema-driven dialogs with live preview (
ui-egui/src/filter_dialog.rs,dialogs.rs). - Run
cargo xtask parityand commit the updateddocs/parity.md.