Skip to content

20.4: Mask stack UI — the CS6 mask panel #76

Open

Description

@aliasfoxkde

Objective. Expose the mask stack in the FireCraft shell as a CS6-shaped panel: one row per mask level, in stack order, with per-level enable, delete, combine mode, and selection coupling to the canvas.

Why. FireCraft's engine already carries mask commands (crates/engine/src/catalog/mask.rs) and mask plumbing in the document model (crates/doc/src/fwmap/reader.rs), but a user cannot see or manipulate a mask at all. A mask that exists only in the file format is not a feature: it is data the user cannot inspect, disable, reorder, or reason about. The shell is where FireCraft stops being a file-format library and becomes a daily-driver tool.

Current state. The stack model, its FWMap persistence, the compositor fold and the level panel are implemented on branch feat/mask-stack-ui-v2 and in flight as PR #113 (head 44b383a, merged with main and conflict-free). The merge is gated on the two CI receipts; it is not on main yet. The engine catalog exports element_mask_stack(document, id) -> Vec<MaskLevel>, and the shell panel is wired to the registry command surface.

Authority. docs/tasks/T9-mask-stack.md; decisions 0092 (wire contract) and 0093 (level model); the CS6 reference install's Properties panel mask section as the behavioural authority; docs/planning/generated/dom-parity.md for the command-bound count.

Work.

  1. The mask panel lists the document's masks in stack order, matching the CS6 mask panel's section.
  2. Per-mask controls: enable/disable, delete, and the combine mode (add / subtract / intersect / invert) with a preview of the mask shape.
  3. Selecting a mask in the panel selects the corresponding object on the canvas.
  4. Everything is exposed as registry commands, reachable from the menu tree and the command palette — no panel-local behaviour.

Acceptance.

  • A document with two masks shows two rows; toggling a mask's enable flag changes the rendered output.
  • The combine mode of a selected mask is editable and takes effect.
  • No inert menu rows are added (the inert_count_never_rises test caps them at 8).
  • The reachability floor does not regress (docs/planning/generated/dom-parity.md regenerated with no new unreachable share).

Verification. cargo run -p xtask -- ci green on the exact PR head; the mask stack's unit tests cover fold/unfold and FWMap round-trip; the workspace clippy and test suite pass.

Boundaries. The mask stack is a FireCraft extension — CS6 has one element mask per object and no stack at all. The stack's shape follows the modern raster editors (Photoshop layer masks, Affinity mask stacks): per-level operators over the coverage below. Do not present it as a CS6 parity feature.

Tracking. Task #143; PR #113.

Next action (owner: shell). Land PR #113 on the receipt of both CI gates, then take the follow-ups in #114 — the panel's screenshot acceptance against the CS6 Properties panel, and the compositor's mask sampling resolution.

Activity

  1. aliasfoxkde commented on Nov 10, 2026

    @aliasfoxkde
    OwnerAuthor

    Status: IN PROGRESS

    Landed: not on main. WIP branch feat/mask-stack-ui (b9ec164) only; the engine-side mask commands already exist (crates/engine/src/mask.rs and the catalog mask commands).
    Still outstanding: no merged mask stack panel, so adding / removing / reordering / toggling / inverting a mask on an object is not reachable from the shell.
    Next: land the panel with every action dispatching a registry command, and the two-masks stack/unstack acceptance test. Owner: app/shell owner.

  2. aliasfoxkde commented on Nov 11, 2026

    @aliasfoxkde
    OwnerAuthor

    Campaign fields (appended 2026-11-11)

    Outcome — The CS6 mask stack is exposed in the FireCraft shell: the document's masks list in stack order, each mask's enable flag and combine mode are editable with a preview, and selecting a mask selects its object on canvas.

    Objective — Build the mask panel over the engine's existing mask commands and the document's mask plumbing, with every action dispatched as a registry command so it is reachable from the menu tree and the command palette.

    Stopping condition — A document with two masks shows two rows, toggling a mask's enable flag changes the rendered output, the combine mode of a selected mask is editable and takes effect, and no inert menu rows are added.

    Verification — A two-masks stack/unstack test asserting the panel's rows and the enable/combine effects on the rendered output; cargo test -p app inert_worklist -- --nocapture shows the inert count still at or below 8.

    Status — IN PROGRESS

    Tracking: task #143; the work is preserved on branch feat/mask-stack-ui (mask combine-mode plumbing in crates/doc/src/fwmap/reader.rs), with no panel and no pull request yet.

    Defects: none recorded.

  3. aliasfoxkde commented on Nov 11, 2026

    @aliasfoxkde
    OwnerAuthor

    PR #113 (feat(app,engine): the mask stack — model, persistence, …) is open and carries this work (currently conflict-dirty against main after train #107). Leaving open until it lands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestparityCS6 parity work

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions