Commit Graph
12 Commits
Author SHA1 Message Date
dtourolle be37218696 Picture film inside a mask layer
The manual described film in a mask layer (6b99f67) with no picture of
it, and the paragraph named the control `Print exposure` where the
panel says `Print Exposure`.

A new scene, film_local, sets Kodak Ektar 100 on an upright alpine
frame — a negative, so it is printed and has a print exposure — then
adds a linear gradient, turns it by its rotate handle to fall from the
top, moves it onto the sky, shows the mask as its edge so the print
stays visible, and raises the layer's Print Exposure to burn the sky
in. Done Masking, then Before held. It puts the masks back to Tint
before undoing, as the other scenes expect.

The picture follows the film list's, under the paragraph it
illustrates. The bundled manual is regenerated to match.
2026-09-27 08:18:15 -04:00
dtourolle 7428f6f845 Re-record the manual for 0.17.0, with albums and the new preset sheet
Every scene is recorded again on the 0.17.0 build, because the header
(Export to Exports), the sidebar (Albums) and the develop column had
all moved. The launch pictures showed the typed folder field, and the
export settings "Export to"; the presets picture predated the sections.

New scenes: presets_film scrolls the sheet down through the shipped
sections and applies Ilford HP5 Plus, a look that changes the film and
nothing else; albums exports four New York frames to an album, selects
it to show the originals behind its files, and opens a new album's
sheet before deleting what it made. record.sh now points the profile's
old export folder at DR_HOME/Exports, which the app turns into the
album "Exports" on first open - the one way to have an album without
the portal's dialogue, which Xvfb cannot show. The launch scene signs
out of a remembered folder instead of typing one, so it shows
"Open folder" beside the folder used last.

Not recorded: the server browser's New folder, which needs a Nextcloud
server, and the download screen, which a folder library never reaches
(the original is a local read, over before the first poll). The manual
says so where it describes each. film_reach and duplicates passed;
inference was pinned to the CPU.
2026-09-26 15:15:51 -04:00
dtourolle b1d36b9143 Picture the duplicate originals review in the manual
The manual described the review (7c9a4ee) without a picture, because the
demo library holds no duplicates. The new duplicates scene makes two:
it copies two New York frames into a bck folder beside their own,
restarts the app so the scan finds them, waits for the sidebar row the
sweep's dating brings (54aee50), opens the review from it, presses
Check and takes the page. It deletes the copies and restarts on the
library as it was; record.sh's snapshot restore would remove them too.
It is registered last, so no other scene sees the copies.

The picture shows both groups proved the same file, the camera-named
copy outside bck marked Stays, and "Move 2 copies to trash" ready.
2026-09-26 08:02:51 -04:00
dtourolle 048d48f532 Re-record the manual on the 0.16.0 interface
Every scene was recorded again on a release build of this commit with
the automation feature. Master changed what nearly every picture shows
after they were taken: scrollbars on the develop column, the grid, the
sidebar and Settings; a "?" beside Settings in develop's top bar, with
its controls regrouped; the Film row opening its list as a popup.

The film scene pressed the list's rows through the develop column, which
no longer holds them: the list is a popup, and the automation hook
reports its contents relative to it. The scene now opens it with
film_list_open, turns the wheel down it and back so the popup and its
scrollbar are seen scrolling, and clicks Velvia at its popup position
plus the popup's origin. The caption says so. film_reach passed in the
same run: the last stock was reached by the wheel, a drag, the scrollbar
and the keys.

Looked at as contact sheets of each GIF's middle and last frames and
each PNG. launch, launch-folder, library-nesting.png and
library-collection-menu came out byte-identical after optipng and are
unchanged. develop-zoom's deepest frames are smooth on Xvfb as before;
its caption does not claim blocks. Settings shows version 0.15.0,
the build's own, until the release commit bumps it.
2026-09-26 08:02:39 -04:00
dtourolle f0e7b8e11c Re-record the manual on the keyboard layout, and stop the zoom caption promising blocks
Every scene was recorded again on a build of this branch rebased onto the
keyboard work and TD-1, since nearly every scene depends on files those
changed: the develop top bar now carries a star strip and Pick/Reject, the
roll shows flags and stars, and the grid's selection bar gains Label and
Flag. `--changed` could not be trusted to find them, because the rebase
made each picture's commit newer than the sources it was recorded from.

The develop-zoom caption said the wheel goes on "until the pixels are
blocks". On Xvfb the deepest frames come out smooth even though the app
draws past 1:1 nearest-neighbour on a real display (confirmed by eye on
the desktop), and a GIF shrunk to 960 wide could not show 3-pixel blocks
anyway. The caption now says what the clip shows; the prose above it,
which describes what the app does, stays.
2026-09-25 07:26:37 -04:00
dtourolle f426bb903a Picture this round's features in the manual
Four scenes, recorded and looked at frame by frame:
- library-labels: 6, 7, 8 and 9 over four New York frames, 7 again to
  take one off, then the Green chip narrowing the grid and back.
- compose-perspective: two towers shot from below, stood upright with
  Vertical at about +58, then held against Before.
- crop-orphan: a stroke in the top-left corner, a crop that leaves it
  outside, the notice with Undo crop and Keep crop, and Undo crop.
- local-intersect: a linear gradient over the lower half, then
  Intersect and two strokes that survive only where it is.

develop-zoom already ends on hard-edged pixels (previous commit). The
text added is a sentence or two under the existing headings, so the
other branch's structure and anchors are left alone.
2026-09-25 07:26:36 -04:00
dtourolle c41f99ea52 Record the manual's scenes by name, and each against what it depends on
scenes.py aimed every press at window pixels, and the develop column had
already moved under it: Compose now sits above Adjust, so the old
exposure coordinate lands on a straighten slider. Every scene now names
what it presses by its accessible label through the automation hook,
places points on the photograph relative to the canvas, and opens its
photographs by file name. Each starts from a known place and undoes what
it did, so one can be recorded alone; the few that continue another's
state name it, and running one runs that first into a scratch folder.

Each scene also declares the pictures it makes and the sources they
depend on. `record.sh --check` fails when the manual shows a picture no
scene makes, or a scene makes one it does not show; it reads two files.
`record.sh --changed` re-records the scenes whose sources, or own code,
changed since the commit that last touched their pictures. record.sh
builds with the automation feature, restores the library from
DR_LIBRARY_SNAPSHOT, starts from a fresh profile and pins inference to
the CPU; the launch screen is recorded from an empty profile of its own.

Re-recorded with the ported scenes, and looked at frame by frame. What
differs from the pictures they replace:
- develop, presets, settings, local, compose, film, wb, light: the
  current develop column (Compose with Vertical and Horizontal above
  Adjust, the Label button), otherwise the same moments.
- library pictures: the filter bar's colour-label chips; no collection
  left over from an earlier run in the sidebar; library-selection is the
  twelve alpine frames rather than eight of them and four New York ones.
- library-rating rates two frames nobody had rated, so the stars are set
  and not cleared.
- develop-zoom goes on past 1:1 with the wheel and ends on the file's
  pixels as hard-edged blocks.
- repair covers a real mark on the road, with a size that fits it; film
  is shown on the Chinatown frame instead of the road.
- panorama tries Perspective, Spherical and Cylindrical before filling.
- launch, launch-folder and panorama-aligned came out byte-identical.
2026-09-25 07:26:36 -04:00
dtourolle c96e670356 Re-record the panorama for the trained filler; the scene waits for the preview and for the DNG instead of guessing 2026-09-20 20:19:01 +02:00
dtourolle 5b4ad11853 Manual: nested collections, and the ghost drawn as it should be
Benchmarks / CPU and I/O (per commit) (push) Failing after 6m16s
Benchmarks / Frame budget (on demand) (push) Skipped
Build and test / Desktop (Linux) (push) Failing after 42s
🐳 Android image / Build and push (push) Successful in 1s
Build and test / android-image (push) Successful in 1s
🐳 Windows image / Build and push (push) Successful in 1s
Build and test / windows-image (push) Successful in 2s
Build and test / Layer separation (push) Successful in 26s
Traceability / Requirement traces (push) Failing after 38s
Build and test / Android (aarch64) (push) Failing after 2m20s
Build and test / Windows (x86_64, cross) (push) Failing after 3m3s
A scene that makes a parent, nests two collections in it by drag and by
the menu, files frames into a child and opens the parent to see it count
both; stills of the tree and of the menu. The collections recording is
re-made now that the bitmap under the cursor is the photograph.

drive.py grows a multi-leg drag: a diagonal with much vertical in it is
taken by the grid's Flickable as a scroll before the DragArea can claim
it, so a drag to the sidebar goes sideways first.
2026-09-20 16:27:18 +02:00
dtourolle f4c3f425dd Show the picker correcting something in the manual
The recording sampled a red brick wall and moved the sliders by three
units, which at GIF size is a click that does nothing. The scene now
drags the frame cold first and picks a white air conditioner, so the
correction is visible and the picker's being absolute - set from the
photograph, not from where the sliders were - is what the picture
shows. The text says so, and says a blown highlight is refused.
2026-09-20 15:24:27 +02:00
dtourolle a03e082fe2 Point the manual's white balance scene at "pick", and record it again
The scene clicked 40px to the right of "pick", on "reset", so the
recording showed a neutral group being reset and a click on the wall
that panned. Re-recorded with the picker fixed: the word lights, the
sample moves temperature and tint, and Before shows what it corrected.
2026-09-20 13:41:17 +02:00
dtourolle d790961b28 Add the manual: every feature pictured from the application itself
Benchmarks / CPU and I/O (per commit) (push) Failing after 30s
Benchmarks / Frame budget (on demand) (push) Skipped
Build and test / Desktop (Linux) (push) Failing after 47s
Build and test / Layer separation (push) Successful in 27s
🐳 Android image / Build and push (push) Successful in 3s
Build and test / android-image (push) Successful in 4s
🐳 Windows image / Build and push (push) Successful in 1s
Build and test / windows-image (push) Successful in 1s
Traceability / Requirement traces (push) Failing after 38s
Build and test / Android (aarch64) (push) Failing after 2m24s
Build and test / Windows (x86_64, cross) (push) Failing after 3m21s
docs/manual/README.md is a tour for a photographer opening DarkRoom for
the first time — one picture per thing, moving where movement is the
point. tools/manual/ is how the pictures are made: drive.py puppeteers the
desktop build on a private Xvfb (launch, click, drag, type, screenshot,
record), scenes.py is each picture as a script, and record.sh runs them
all over a folder and writes the results into docs/manual/media/.

The media is in LFS, with the CI pulls excluding it as they exclude the
fixtures; a screenshot changes wholesale when the interface does.

Nothing in the pictures shows a person, by design: the demo library is
seventy urban and alpine frames, chosen from the catalog's rows that face
detection found nobody in.

The traceability matrix is regenerated here after the rebase that
brought this branch up to master.
2026-09-20 00:26:00 +02:00