Skip to content

"Edit crop" is an unlabelled view switch on the result player #35

Open

Description

@sensitron

Context

Found in the manual field test of PR #27 (issue #25, transform stage) on 2026-09-04, reported at #27 (comment) (item 8). The defects from that test are fixed on the branch; this one is not a defect. Showing the uncropped frame while the crop rectangle is placed is correct, and the code does exactly that. What is missing is a name for the mode, and choosing one is a product decision for the maintainer rather than another commit on the PR.

Current State (verified 2026-09-04 on feat/issue-25-transform-stage at 094c783)

The "Edit crop" checkbox (src/matteloop/ui/transform_group.py:182) does two things:

  1. It enables the crop handles on the result canvas.
  2. It switches the canvas from the transformed frames to the framed, untransformed ones. _current_images (src/matteloop/ui/result_player.py:322-327) returns frames.framed instead of frames.transformed whenever _crop_edit is on. The docstring of set_crop_edit (result_player.py:173) describes it as exactly that: "Toggle between the crop overlay (framed frames) and the result loop."

Only the first is what the label says. Consequences of the second being unnamed:

  • Unticking the box makes the cropped result appear, so the tick reads as "apply". It is not: the transform was in state the whole time, and the loop is a preview either way (see issue A).
  • A resize entered while the box is ticked appears to do nothing. While crop-edit is on, _state_changed (src/matteloop/ui/transform_stage.py:300-325) only refreshes the crop presentation; the frame reload that would show the resize is deferred to the untick (_crop_edit_toggled, transform_stage.py:262-272, _sync_player_frames on the falling edge). The panel's readout updates immediately, the picture does not, and nothing says why.
  • The sibling checkbox in "Crop & Cleanup" is also called "Crop" (src/matteloop/ui/inspector.py:496) and means something else: it enables or disables the source crop. Two checkboxes named Crop, one an on/off switch, the other a view mode.

The tester's own suggestion was an "Apply" button. That would be worse. The shelf already has one control that writes the file, "Render Video" (src/matteloop/ui/action_shelf.py:25), and issue A records that users already cannot tell what it does to a transform. A second button called Apply next to it would leave the user with two candidates for "which one saves", and Apply would in fact save nothing.

Leading candidate, not decided

Replace the checkbox with a named two-state control over the result surface, e.g. Edit | Result, so that the current view is always named and the handles exist only in the Edit state. The semantics stay what they are today; only the labelling changes:

  • "Edit" shows the framed frames with the crop rectangle, as crop-edit does now.
  • "Result" shows the transformed loop, as the unticked state does now.
  • A resize entered in "Edit" is still deferred, but the user is standing in a mode called Edit, and the switch to "Result" is what shows it, which is what the words say.

Alternatives worth weighing before deciding:

  • Keep the checkbox, rename it to say what it shows ("Show uncropped frame and handles"), and add a one-line status on the canvas while it is on. Cheapest, but the resize-does-nothing surprise stays.
  • Reload the transformed frames on every edit even in crop mode and draw the crop rectangle over the resized frame. Removes the deferral, but the crop rectangle is defined in framed-frame pixel space (Transform stage on a finished cut: trim, output crop, resize, and a looping result preview #25, "Crop coordinates are integers in the pixel space of the framed frame"), so the overlay would have to be scaled back and forth; more code for a mode that already works.

Acceptance Criteria (outcome-level)

  1. Whenever the canvas shows the untransformed frames, the UI names that state; whenever it shows the transformed loop, it names that too. A user cannot be in the crop-edit view without a visible word for it.
  2. No control in the Transform section or on the canvas is labelled in a way that suggests it writes the file. "Render Video" remains the single writing control.
  3. The two "Crop" checkboxes no longer share a bare name.
  4. The existing behaviour that the crop rectangle is placed on the unclipped framed frame is retained (tests/ui/test_transform_stage.py:660, :694, tests/ui/test_result_player.py:367 keep passing or are updated to the new control).
  5. uv run ruff check . && uv run mypy src && QT_QPA_PLATFORM=offscreen uv run pytest -q green.

Files Reference

File Role
src/matteloop/ui/transform_group.py:182, :312-318 the checkbox and the Crop rows
src/matteloop/ui/result_player.py:166-190, :322-327 set_crop_edit, _current_images
src/matteloop/ui/transform_stage.py:262-272, :300-325 toggle handling, deferred reload
src/matteloop/ui/inspector.py:496 the source-crop "Crop" checkbox

Related

Activity

  1. smb commented on Sep 5, 2026

    @smb
    Collaborator

    Verified on 2026-09-05, with a concrete proposal.

    The checkbox does two things and announces one. ui/result_player.py:

    if self._crop_edit or frames.transformed is None:
        return frames.framed      # untransformed
    return frames.transformed

    Ticking "Edit crop" enables the drag handles and swaps the displayed image
    from the transformed result to the untransformed framed frames. The docstring is
    explicit that this is intended — "Toggle between the crop overlay (framed frames)
    and the result loop" — but nothing in the interface says so.

    This is the mechanism behind a complaint recorded in #33. While the crop
    overlay is active, a resize change updates the readout but not the visible
    image, because the user is looking at the frames from before the transform.
    That reads as "the resize does nothing".

    Proposal: replace the checkbox with a small mutually exclusive pair beside
    the result surface — Crop editing / Result preview — so the view change
    is named rather than implied. Keep the existing framed-pixel coordinate system;
    neither state applies or saves anything, which is already true today.

    Worth recording what is good here and should not be lost: the numeric X, Y,
    Width and Height fields are not a fallback for missing direct manipulation, they
    are the named, keyboard-reachable path to the same result. Offering both is the
    right decision — only the switch between them currently conceals what it does.

    Context in #66.

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

    accessibilityBarrier affecting people with disabilitiesenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions