Commit Graph
220 Commits
Author SHA1 Message Date
BFlat 9a71884244 Merge pull request #1894 from storytold/community/1745-eyedropper
Eyedropper: Sample Size, Sample layers and Show Sampling Ring (#1745 carry)
2026-10-09 22:08:46 +07:00
2b139ebd5c inspect: report each smart object's source (#1785)
document.inspect (and photocraft-cli info) now gives every smart object a
smartSource: embedded with its file name, or linked with a file path or,
for a PSD placed layer, the Idnt uuid its duplicates share. A script can
then tell duplicates of one placed file from independent contents, e.g.
to check that every location in a mockup template has its own art.

Co-authored-by: Juan Manuel Verges Solanas <jmverges@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:08:07 +07:00
BFlatandClaude e39cacd895 Packaging: Windows MSI setup wizard (folder choice, progress, version, launch on finish) (#1864)
Double-clicking the MSI now opens WixUI_InstallDir without the licence page:
Welcome, install folder (remembered for upgrades in
HKLM\Software\PhotoCraft\InstallDir), Ready, progress, and a Finish page with
a ticked "Launch PhotoCraft" box (WixShellExec, unelevated). The pages name
the full version, pre-release tag included (photocraft.en-us.wxl).
package.ps1 draws the banner and side bitmaps from the app icon, so no WiX
stock art ships. msiexec /qn still installs silently. The release and ARM64
workflows install the WiX UI and Util extensions; packaging-lint checks the
.wxl. Ported from VectorCraft (storytold/vectorcraft@aa548d2).


Claude-Session: https://claude.ai/code/session_01AP7ThRN3kpNmjsuJUerJui

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-09 21:33:38 +07:00
Elvis33LEandClaude Opus 5.5 adc1f76df4 Indexed Color: integer counts, palette stops and asynchronous previews (#1741)
Indexed Color accepted fractional colour counts and computed its live preview on the UI thread.
Counts are now whole numbers in 2-256 with a linear slider snapping at 8/16/32/64/128/256, and on
native builds the preview runs on one background worker that coalesces slider drags and rejects
stale results. Nearest-colour lookup uses an exact kd-tree above 64 entries (identical indices,
256 colours at 4.2 MP: 3018 -> 1061 ms). Web and inline sessions stay synchronous.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:33:13 -04:00
Gert Pellin - GPEandClaude Opus 5.5 15737e122b Filter > Other > Color to Alpha (#1683)
A new filter that removes a chosen colour by unmixing it into transparency, as GIMP's and
Krita's Color to Alpha do: per pixel the most transparent opacity that keeps the unmixed colour
in range, shaped by transparency and opacity thresholds. It runs through run_filter (selection,
smart filters, Last Filter, one history step), floats the Background first and refuses a
transparency-locked layer; the filter dialog gains a colour parameter. Fixes #1576.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:13:42 -04:00
Claude ac9c7b057b Merge main into #1745 (catalogs: keep both blocks)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UHgFEHEsefoQoBParH47JA
2026-10-09 14:08:06 +00:00
storybored379andClaude Opus 5.5 15e35cf605 MCP: shared conventions and cancellable Render Video (#1668)
The MCP server follows the crafts' shared conventions (FilmCraft #28): core tools
incl. render_preview, titles and annotation hints, strict argument keys (-32602),
live photocraft://document and photocraft://commands resources, and -32700
recovery from malformed JSON lines. Headless Render Video writes through the
granted write root, reports progress, stays ping-responsive and can be cancelled,
removing only the files it created. docs/mcp.md describes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:54:14 -04:00
Nigel Ihza FirdausyandClaude Opus 5.5 75e6bad453 Control: ui.inspect reports the open Brush Preset picker (#1672)
ui.inspect now has brushPicker: null while closed, {pos, list} while the Brush
Preset picker is open (list is its collapsed/filter/view/renaming state), so
agents can see what a right-click with a painting tool opened. Fixes #1558.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:50:01 -04:00
Claude a94dd19d79 Merge main into #1745 (German catalog)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UHgFEHEsefoQoBParH47JA
2026-10-09 13:29:18 +00:00
midasdfandClaude Opus 5.5 b5320e590e Preferences: System Title Bar says it applies at next launch (#1677)
On Windows and Linux the System title bar checkbox now carries the existing "Applies at next
launch." note, since saving it does not change the current window. Fixes #1661.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:17:05 -04:00
midasdfandClaude Opus 5.5 40f14d25e8 Plug-ins: keep the originating error across parallel bands (#1654)
When one band failed, its siblings stopped with a generic "another band failed"
error, which could win the collection order and hide the real cause. The abort
flag now carries the first error, so every band reports it; tests cover traps,
error codes and the instruction budget across parallel bands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:11:00 -04:00
初心YearthandClaude Opus 5.5 c63d04a09c docs: explain Windows source build prerequisites and app-control failures (#1692)
Document the MSVC toolchain and C++ build tools workload, and how to diagnose
Smart App Control blocking Cargo or build outputs (os error 4551), with a
pointer to the packaged release. Fixes #1585.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:04:05 -04:00
Nigel Ihza FirdausyandClaude Opus 5.5 351736ef6b docs(mcp): grant scoped file roots in headless registration examples (#1673)
The PHOTOCRAFT_AUTOMATION_*_ROOT variables are read only by the desktop app, so
headless photocraft-cli mcp/serve need the --automation-*-root flags. Say so,
and pass explicit roots in the .mcp.json and claude mcp add examples.
Fixes #1551.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:03:58 -04:00
Nigel Ihza FirdausyandClaude Opus 5.5 6b1075e240 docs(control): align method signatures with accepted parameters (#1674)
ui.set gains rotation, gradientBlendMode and gradientClassic in its signature
and the stale duplicate ui.set line goes; ui.menu.invoke documents params,
ui.pointer tool, app.save an optional path, and serve's doc.save tiffLayers.
Fixes #1550.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:03:30 -04:00
buivanvu94andClaude Opus 5.5 f7d8a328e4 docs(control): Preferences Apply and OK are refused over control (#1678)
The Preferences entry said ui.dialog.apply/confirm save the dialog, but the
automation policy refuses whole-preferences updates (SECURITY.md). Document the
refusal, what happens to the dialog, and prefs.set for single safe preferences.
Fixes #1555.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:03:06 -04:00
BFlat 8e8e9f2c68 Merge pull request #1778 from storytold/community/1607-affinity
AF.3: native Affinity import (layers, artboards, vectors, text, images), carrying #1607 by @callmeBalloch
2026-10-09 18:00:53 +07:00
MarekSpodBiedry 2feaf055cc fix(xtask): the scorecard's performance summary no longer counts not-run scenarios as tracked (#947) (#1705) 2026-10-09 18:00:19 +07:00
MarekSpodBiedry 1fd600d3ad fix(automation): bridge doc_save without path writes back like headless (#946) (#1704) 2026-10-09 18:00:16 +07:00
MarekSpodBiedry 864021994c fix(scorecard): mark the #204 preference rows done; their readers, allowlist and test exist (#1002) (#1694) 2026-10-09 17:59:41 +07:00
Gert Pellin 65f30dd9e3 feat(eyedropper): Sample Size, Sample layers and Show Sampling Ring (#1649)
The Eyedropper options bar now has Photoshop's Sample Size (Point Sample,
3 by 3 ... 101 by 101 Average), Sample (Current Layer, Current & Below,
All Layers, All Layers No Adjustments, Current & Below No Adjustments)
and Show Sampling Ring.

- engine: new `document.sampleColor {x, y, size, sampleLayer}`
  (sample_cmds.rs). Averages the square centred on the pixel, clipped to
  the canvas, alpha-weighted, in the document's colour model (Gray, Lab;
  CMYK documents use their composite RGB, since the profile round trip
  is not exact) and rounded to the document's bit depth.
- ui: eyedropper_ui.rs options bar; state.rs ToolOptions
  eyedropper_size / eyedropper_sample / eyedropper_ring (serde). The
  size is shared with the painting tools' Alt-click eyedropper, the
  Curves / Color Picker eyedroppers and the Info panel readout.
- control: ui.set eyedropperSampleSize / eyedropperSample /
  eyedropperRing; documented in control-protocol.md and the MCP schema.
- i18n: new strings in all 14 catalogs (plus the missing Russian hint
  the tl! scan had not reached).
- scorecard: TOOL-1649-1.
2026-10-09 12:28:14 +02:00
Claude 770f6d49b8 scorecard: regenerate for the display-server preference (141 settings)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UHgFEHEsefoQoBParH47JA
2026-10-09 16:06:12 +07:00
Adam Gincel 35c323c9de feat(ui): keep a brush per painting tool, as in Photoshop (#218)
The brush was one global session setting (only its smoothing was per tool), so
switching tools carried the size, hardness, mode, opacity, flow and dynamics
over. sync_tool_smoothing becomes sync_tool_brush: it saves the session brush
for the outgoing tool and loads the new tool's on every switch. UiState's
smoothing_tool/tool_smoothing become brush_tool/tool_brushes (serde default, so
saved UI state still loads), and the session's own fields (colours, erase flag,
stroke seed) are never carried across a swap.

Called from the frame start, the options bar before the brush chip, both canvas
stroke paths, ui.set {tool} (so tool + brushSize in one call sets the new tool's
size) and select_tool_preset. A tool seen for the first time inherits the brush
in hand at Photoshop's 10 % smoothing.

Tests: each_tool_keeps_its_own_brush, the renamed per-tool smoothing test,
per-tool coverage in the ui.set brushSize test, and pencil_tests switching tools
before setting the smoothing as the options bar does.
2026-10-09 16:06:07 +07:00
callmeBallochandClaude Opus 5.5 6deb1e0934 AF.3: attribute the Affinity corpus, one sample count, run it on --changed
From the review on storytold/photocraft#1607:
- ATTRIBUTION.md gets a row for corpus/affinity: the four upstreams at
  their pinned commits, with authors and licences (CC0-1.0, and MIT by
  Nick Beeuwsaert, Jeremy Cantu and DAIKI).
- The README said 176 sample documents in the provenance and 189 in the
  limits. It now says 189 distinct public documents in both places; the
  reader opens all of them (298 files with duplicates, no failures).
- crates/affinity/ joins CRITICAL, so test-corpus --changed runs the
  corpus when the reader changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQPh8UDgMyARR5Hat9UchC
2026-10-09 07:41:49 +00:00
callmeBallochandClaude Opus 5.5 2b279ba61b Merge storytold/main into AF.3 native Affinity import
No conflicts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQPh8UDgMyARR5Hat9UchC
2026-10-09 06:38:46 +00:00
callmeBallochandClaude Opus 5.5 a8d7c6ef3f AF.3: put the Affinity fuzz targets and corpus back in CI
The maintainers approved the new crate, its fuzz targets and the corpus
upstreams in principle (storytold/photocraft#1607), so this undoes the
interim opt-in: ci.yml fuzzes preview and import_preview again, corpus
--all fetches the Affinity set, and its test runs under the normal
corpus feature. The provenance section stays.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQPh8UDgMyARR5Hat9UchC
2026-10-09 06:38:40 +00:00
kubuntugamer 950eb1dd28 fix(automation): a pathless PSD or PSB save leaves the document dirty (#1547)
Headless::save recorded the saved revision only for .pcraft, so saving a
document back to its own PSD or PSB wrote the file correctly and still
left session.list reporting dirty: true. Automation clients that use the
flag could not tell a saved document from unsaved work.

The test is now "was this a layered document save" (PSD, PSB or .pcraft)
rather than "was this .pcraft". A flat export (PNG, JPEG, ...) stays a
copy: it leaves dirty and the document's path alone. The desktop app.save
path already recorded the revision for every format, so this only affects
the headless JSON-lines server and the MCP stdio server, which both route
through Headless::save.

Tests cover the reported sequence for both .psd and .psb -- create, reopen
the saved file, edit, then doc.save with no path -- plus a control that a
flat export is a copy. docs/control-protocol.md now states the outcome of
doc.save for the dirty flag and the document path.

Co-authored-by: Space Bunny Free <chasbigham@gmail.com>
2026-10-09 13:24:07 +07:00
callmeBallochandClaude Opus 5.5 edb42922c1 AF.3: keep Affinity out of CI's corpus and fuzz jobs; state the clean-room provenance
Review on storytold/photocraft#1607 asked maintainers to decide on new
fuzz targets in ci.yml and four third-party corpus upstreams in
corpus --all. Until they do, neither touches CI: ci.yml is main's again
(the targets stay in crates/affinity/fuzz, run locally), and the
Affinity corpus is fetched only by corpus --affinity and tested with
--features corpus-affinity, so --all and test-corpus are unchanged.
The plan is to move those files into photocraft-corpus.

The crate README now spells out the provenance: no Affinity software,
afread's MIT description re-described without translating code, every
structure confirmed on public files (CRC-32 per entry, self-typed
fields), semantics fitted to Affinity's own thumbnails, and how the
sample documents were licensed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQPh8UDgMyARR5Hat9UchC
2026-10-09 05:19:56 +00:00
Claude 52552d7127 Rotate View with ui_set: describe rotation, drop the duplicate Greek row, regenerate the scorecard
- #1599 tests that ui_set's description names every field ui.set accepts; #1611 adds
  `rotation` to ui.set, so the description now names it.
- #1611's el.tsv row for "Pick screen color" duplicates the one #1618 added on main.
- docs/scorecard.md regenerated with cargo xtask scorecard after merging both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UHgFEHEsefoQoBParH47JA
2026-10-09 05:07:07 +00:00
Claude 31cf872333 Merge #1611 (mvanhorn): Rotate View tool
# Conflicts:
#	docs/scorecard.md
2026-10-09 05:06:50 +00:00
WilandClaude Opus 5.5 3091a2843c Actions: edit steps, nested action calls, F-key shortcuts and recorded Fit on Screen (#1093)
Steps can be deleted and dragged into a new order, live while recording. Playing an action
while recording stores one named actions.play call, and nested playback stops on a child
failure, rejects cycles and goes at most 16 levels deep. Right-click an action to give it
F1-F12 (saved in preferences). View > Fit on Screen (Cmd+0), Zoom In/Out and 100% record and
replay. New actions.move command; actions.delete takes a step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 01:03:35 -04:00
Jason XiangandClaude Opus 5.5 1bc25d363f New Document: save named presets (Saved category) (#1516)
Save Preset... in File > New stores width, height, resolution, mode, depth, background (with
its colour) and display units in preferences. They are listed under a Saved category, where a
preset can be selected or deleted. Adds document.presets.save/list/get/delete; get returns
params for file.new, which gains an optional backgroundColor. Bad saved entries are skipped one
at a time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 00:54:37 -04:00
Matt Van Horn 4f7bd1f28f Regenerate the scorecard after the Rotate View tool
Marks TOOL-214-17 done and drops the now-read trackpad rotate preference
from the unread list. The Paint Bucket test mapping carries the view's
camera angle.
2026-10-09 04:40:22 +00:00
Matt Van Horn 690dafd61b Add the Rotate View tool in the Hand flyout
Turns the canvas camera around its centre without rewriting pixels.
Reset View zeros the angle; Match Rotation copies it across documents.
Trackpad rotate follows Preferences › Enhanced Controls › Rotate View with Trackpad.
2026-10-09 04:40:22 +00:00
Γιῶργος (George)andClaude Opus 5.5 1910b9f87c Add Greek (Ελληνικά) UI localization (#1562)
A complete Greek catalog (el.tsv) registered with the other complete-menu languages: menus,
dialogs, preferences, filters, tool names (Greek with the English name in parentheses) and
font weights, plus Greek Services / Hide Others / Show All in the macOS app menu.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 00:31:00 -04:00
abc2cbandClaude Opus 5.5 0256eaa4e0 Type Color Picker opens the full Color Picker; screen eyedropper with a pixel loupe (#1232)
The Type options bar and Character panel swatches open the full Color Picker (Text Color),
applying to the selected characters or the whole layer via type.setStyle; Cancel is inert. A
shared "Pick screen color" action in the full dialog and compact popups samples the desktop:
X11/Windows/macOS snapshots with an 11x11 magnifying loupe (4x-24x), the XDG PickColor portal on
Wayland, the EyeDropper API on the web. Captures stay in memory, are bounded at 64 MP, and are
ICC-converted to sRGB where the display publishes a profile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 00:30:50 -04:00
callmeBallochandClaude Opus 5.5 57ae2fb1a3 Merge storytold/main into AF.3 native Affinity import
Conflicts: File › Open and batch extension lists (SVG, swatches and
Affinity together); the import dispatcher (upstream's type-layer
preparation with the new result fields); the pinned EXR and Affinity
corpora side by side; README, book and development docs.

Affinity type layers now draw through text_import::prepare, so they get
the same raster bound as other imported type, and SVG import fills the
two new ImportResult fields.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQPh8UDgMyARR5Hat9UchC
2026-10-09 04:26:18 +00:00
harrisonoconnorhover 0e0311d245 Reject unsupported document indices in MCP screenshots 2026-10-09 11:12:46 +07:00
MarekSpodBiedry fb71daf2c6 Control channel: ui.click rejects a count above 256 instead of queueing unbounded input (#982) (#1446) 2026-10-09 11:12:34 +07:00
MarekSpodBiedry 746f2530e6 Plug-in names reject bidi controls, zero-width spaces and other invisible format characters, and need a visible character (#1011) (#1444) 2026-10-09 11:12:27 +07:00
Harrison O'Connor-Hoover 672c0775de Reject control requests that expire before dispatch (#1525) 2026-10-09 11:11:47 +07:00
Harrison O'Connor-Hoover de9cc5f12c Do not replay bridge requests after an uncertain result (#1527) 2026-10-09 11:11:44 +07:00
BFlatandClaude b693d690e1 docs: MCP tool names and job tools, codec README JPEG metadata and deep EXR (#1552, #1553, #1559) (#1573)
- architecture.md listed dotted MCP tool names (doc.open, command.run...) that the server
  rejects; it now uses the advertised underscore names, adds the missing tools, and points
  out that dotted names belong to the JSON control protocol.
- development.md's MCP tool inventory gains jobs_list and jobs_cancel.
- crates/codecs/README.md: oversized JPEG EXIF/XMP is dropped with a warning (XMP first sheds
  its layered-document properties), not an error; supported deep EXR opens flattened with a
  DeepFlattened warning, and only deep ZIP and mip/rip-map tiles are unsupported.


Claude-Session: https://claude.ai/code/session_01UHgFEHEsefoQoBParH47JA

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-09 10:23:19 +07:00
Xus BadiaandClaude Opus 5.5 bfc59c784f macOS DMG: branded window background and icon layout (#1201)
The DMG opens on a 660x400 Finder window with the PhotoCraft artwork, 128 pt icons and the
Applications link beside the app. packaging/macos/dmg/ holds the SVG source, a reproducible
generator, an 87 KB HiDPI palette TIFF (was 1.0 MB) and the .DS_Store layout. The volume is
named "PhotoCraft" (the background alias resolves by volume name); the DMG file name keeps
the version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 23:11:00 -04:00
Filip PłachecińskiandClaude Opus 5.5 f0ae12dd22 Self-host the web app with Docker (nginx, community-maintained) (#1334)
A multi-stage Dockerfile builds photocraft-web with Trunk and serves dist/web from an
unprivileged nginx on :8080, with /healthz, precompressed gzip, the wasm MIME type and
immutable hashed assets. Rust and Trunk follow the release workflow, and the
PHOTOCRAFT_BUILD_SHA/DATE build args stamp About. Documented in packaging/web/README.md;
not built in CI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 23:10:55 -04:00
optimalbyteeandoptimalbytee c7dbb37b3c Speed up wide Motion Blur with adaptive FFT convolution (#1471)
Keep the merged upstream row kernel for shorter streaks and unsupported inputs.
Use bounded overlap-save convolution of its merged bilinear coefficients when
channel pairs, parallelism and memory estimates favor FFT. Preserve alpha cutoff
behavior, cancellation, selections and depth/model-neutral filtering.

Validate 303 algorithm tests in debug and release, plus native checks and full
image comparisons. Repeated current-upstream comparisons show 2.31x at 24 MP
and 4.15x at 1.5 MP for angle 30 / distance 1000 on the measured host.

Co-authored-by: optimalbytee <optimalbytee@users.noreply.github.com>
2026-10-09 09:02:00 +07:00
Brandon ThomasandClaude Opus 5.5 0b5803500c Regenerate docs/scorecard.md and docs/parity.md after the latest community merges (#1530)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 21:24:37 -04:00
619095bfd0 Pattern Stamp tool in the S-group flyout (#922)
* Add Pattern Stamp as a Clone Stamp flyout sibling

Introduce paint.patternStamp to paint the current pattern through a
brush stroke. Aligned strokes keep a document-space tile origin;
unaligned strokes restart at the first point; Impressionist jitters
each dab with a seeded RNG. Empty patterns and strokes larger than
4096² pixels return an error instead of allocating.

* Record Pattern Stamp on the tools scorecard

Allow the aligned stamp helper's argument count under clippy.

* Pattern Stamp: raise the stroke cap to 8192² so a 24 MP diagonal fits

The 4096² bounding-box cap refused a corner-to-corner stroke on a 6016x4000 canvas (~24M px).
Unit test covers that diagonal and a still-rejected 9000² box; the hostile-input test uses a
footprint above the new cap. Scorecard note labels Impressionist as an approximation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* i18n(pl): translate the Pattern Stamp strings

The Polish catalog landed on main after this PR was written; the
translation-coverage tests need every language to carry new UI strings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Tool::ALL holds 51 tools now that Red Eye and Pattern Stamp both landed

The rebase onto main (with #1084's Red Eye tool) leaves Tool::ALL one entry
longer; bump the array length and the count test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Flyout test: qualify egui::Vec2 (panels.rs no longer imports Vec2)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 21:07:06 -04:00
Brandon ThomasandClaude Opus 5.5 ed6f989bc6 Regenerate docs/scorecard.md and docs/parity.md after the latest community merges (#1518)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 20:47:09 -04:00
5bef14dbdc Swatches: user swatch model with .aco/.ase import and export (FILE-215-14, part of #215) (#886)
- photocraft-psd: clean-room .aco (v1/v2, UTF-16 names, RGB/HSB/CMYK/Lab/Gray at 16 bits,
  other spaces kept verbatim) and .ase (groups, global/spot/process, RGB/CMYK/LAB/Gray floats,
  unknown models kept) readers and writers; byte-stable round trips, hostile input -> Err.
- engine: presets::swatches (colours in their own model, display/foreground conversion through
  photocraft-cms working spaces, persisted with the prefs, default 40 colours in 4 groups) and
  swatch_cmds (swatches.list/add/delete/rename/move/newGroup/renameGroup/deleteGroup/use/reset/
  import/export) with graceful-failure tests.
- ui: swatches_ui.rs replaces the const grid (groups, tooltips, click = foreground and selected
  type, Alt/Ctrl-click = background, rename/delete/move, panel menu Import/Replace/Export/Reset),
  Color Picker "Add to Swatches", .aco/.ase via File > Open and drag-and-drop; strings translated
  in every complete catalog.
- Scorecard FILE-215-14 -> done.

Co-authored-by: leon <claude.udder842@passmail.net>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-08 20:43:01 -04:00
2f42b1cc80 Camera Raw opens in a window of its own (#1361)
* Camera Raw opens in a window of its own

The Camera Raw dialog (Filter › Camera Raw Filter and the open-time
dialog) was a full-window overlay drawn over the PhotoCraft window,
covering its title bar: it looked like a fullscreen app without window
controls. Adobe Camera Raw is a separate window.

Show it in an egui immediate viewport: an OS window titled "Camera Raw
(name)" / "Camera Raw Filter (layer)", 1360 x 900 by default, resizable
(minimum 900 x 600). The dialog stays modal: the main window is dimmed
and takes no input while it is open. Closing the window is Cancel (for
the open-time dialog that closes the raw being opened). Where the
platform has no extra windows (ctx.embed_viewports(), the web build) it
is drawn over the main window as before, with its painted title strip.

The drawing code is unchanged apart from the title strip, which is not
painted in a window of its own.

* Camera Raw window: scrim theme token, close-is-Cancel test, document the screenshot gap

- theme::Tokens gains `scrim` (the dim over the main window behind a modal
  that takes all input); Camera Raw uses it instead of a hard-coded colour.
- closing_the_camera_raw_window_cancels: the overlay fallback keeps the
  dialog open, a close request on its window cancels without history.
- control-protocol.md: eframe 0.36 cannot screenshot an immediate viewport,
  so ui.screenshot shows the dimmed main window while Camera Raw has its own
  window; agents read it via ui.inspect.cameraRaw and see it offscreen with
  the snapshot example or kittest (which embed viewports).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 20:39:15 -04:00