Commit Graph
2965 Commits
Author SHA1 Message Date
f9b5693621 M2: a text keeps a max height or a number of max lines, not both (#1832)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-02 00:02:56 -05:00
8174dd5b74 M4: bulleted lists keep the same bullet at every level of indentation (#1843)
* M4: bulleted lists keep the same bullet at every level of indentation

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* list_markers: the comment says bullets are the same at every level

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-02 00:01:29 -05:00
9c3ec8c1d1 M4: typing 1) and a space starts a numbered list, as 1. does (#1842)
* M4: typing 1) and a space starts a numbered list, as 1. does

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Parity: the Text area row names the list creation characters

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Parity: the list creation characters without spaces inside the code spans

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-02 00:00:19 -05:00
a953a04e33 Shortcuts: Cmd/Ctrl+Shift+Alt+= / - / 0 make the interface larger, smaller and default-sized (#1846)
* Shortcuts: Cmd/Ctrl+Shift+Alt+= / - / 0 make the interface larger, smaller and default-sized

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Interface size keys: live while editing text too, and the new size draws on the next frame

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* A preference set during a frame repaints this window too, so the interface size applies on the next frame

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Control channel: a preference changed by a hidden window's command repaints every window

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-01 23:59:08 -05:00
f58e022ed7 Shortcuts: Cmd/Ctrl+Alt+arrows rotate a degree at a time, 15 with Shift (#1845)
* Shortcuts: Cmd/Ctrl+Alt+arrows rotate a degree at a time, 15 with Shift

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* The rotate gesture's label in the English catalog

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Rotate keys: about the selection's rotation origin, not while editing points, Dev Mode refusal on the control path too

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-01 23:56:06 -05:00
Trevor BrownandClaude Fable 5.1 5050631bcf M5: Hide UI in the presenter: the bars go away and Cmd/Ctrl+\ brings them back (#1820) (#1826)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-01 23:50:03 -05:00
Trevor BrownandClaude Fable 5.1 65bd00f739 M3: Delete on a layer inside an instance hides it instead of being refused (#1834)
* M3: Delete on a layer inside an instance hides it instead of being refused

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* The components structure test: Delete inside an instance hides

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-01 23:49:58 -05:00
Trevor BrownandClaude Fable 5.1 2abd8c5f52 M2: Remove all auto layout takes it off a frame and every frame nested in it (#1833)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-01 23:49:53 -05:00
Trevor BrownandClaude Fable 5.1 3b8ded69c0 M4: a link on text is underlined by default, and Underline takes it off (#1841)
* M4: a link on text is underlined by default, and Underline takes it off

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* text.link: only a new link takes the default underline; Underline reads the texts inside a target

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-01 23:49:48 -05:00
Trevor BrownandClaude Fable 5.1 fdd27a0b88 Shortcuts: the Layers panel opens with Ctrl+1 as well as Alt+1 on Windows and Linux (#1844)
* Shortcuts: the Layers panel opens with Ctrl+1 as well as Alt+1 on Windows and Linux

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Parity note: in the browser Ctrl+1 is the browser's tab key

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-01 23:49:43 -05:00
김삼현andClaude Opus 5.5 702b0d7894 M8: a whole ellipse drawn backwards keeps its simple stroke in SVG (#1848)
* M8: a whole ellipse drawn backwards keeps its simple stroke in SVG

An ellipse with a sweep of -2π goes all the way round, as the renderer
and the .fig export already read it. The SVG export's simple stroke
checked `sweep >= 2π` only, so such an ellipse's inside or outside
stroke was written as a filled even-odd ring instead of a stroke.

All three places now ask `figcraft_geom::full_sweep`, as the geometry
and the bounds do.

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

* M8: a backwards whole ellipse's stroke ring in the renderer and .fig export, tested

Review follow-up (#1848): the renderer's stroke ring and the .fig
export's stroke geometry read a sweep of -2π as whole too, now through
`full_sweep`. A test for each checks a backwards ellipse strokes the
same ring as a forward one, and fails if either goes back to checking
positive sweeps only.

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

* M8: the .fig backwards-ellipse test compares the stroke ring itself

Review follow-up (#1848): the test checked only that one stroke path was
written. It now compares the path's commands and winding rule for the
forward and backwards ellipse, and that the ring is even-odd.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:49:38 -05:00
김삼현andClaude Opus 5.5 fa8faf216d M8: a whole ellipse starting anywhere stays whole through a .fig file (#1851)
A .fig file (and the REST JSON) holds an ellipse's start and end angles
as 32-bit floats, and FigCraft writes them that way too. For a whole
turn that starts anywhere but zero, end - start comes out a hair short
of 2π as often as not (start 0.3: 6.283185184), which reads as an arc:
the ellipse came back as a pie slice whose centred stroke draws a line
from the centre to the edge.

On import, a sweep within the angles' precision of a turn is now a turn.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 23:49:34 -05:00
AxylumandCédric Legrand dea8d8eb3a fix(cli): M2.1: scope dead-code expectation (#1816)
Co-authored-by: Cédric Legrand <cedric@legrand-tech.fr>
2026-11-01 23:49:30 -05:00
NetterSilverandClaude Haiku 5.5 9a1b33bbfd Reject signed major in plugin manifest api version string (#1853)
Found while testing crates/plugin/src/manifest.rs:70 (api_from_number_or_string, the Api::Text arm)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-11-01 23:49:26 -05:00
bd920fc7de M8: .fig import: a routed connector takes its line style from the generated record (#1807) (#1813)
* M8: .fig import: a routed connector takes its line style from the generated record (#1807)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* M8: .fig import: a routed connector keeps its own empty paints and dash pattern

CodeRabbit review on #1813: an explicit empty strokePaints (no stroke) or
dashPattern (solid) on the connector no longer takes the generated record's.

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

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-01 14:12:31 -05:00
김삼현andClaude Opus 5.5 264bcb1c03 M8: an arc's spread shadow and mitred stroke get room for their corners (#1802)
* M8: an arc's spread shadow gets room for its mitred corners

Rectangles, frames and ellipses grow by exactly their spread, so their
layers only make room for the spread itself; other shapes make room for
the mitre at sharp corners (up to four times the spread). An ellipse
with arc data (a pie slice, or a ring cut short) counted as an ellipse,
but its ends meet its sides in sharp corners: a spread of 25 on a slice
of 0.3 rad cut its shadow off at the layer's edge (up to 255 levels).

Only an ellipse that goes all the way round now grows by exactly its
spread. `figcraft_geom::full_sweep` is what `ellipse` already used to
tell a whole ellipse or ring from an arc, so the two agree.

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

* M8: an arc's mitred stroke gets room for its corners too

Review: `outline_reach` counted every ellipse as an outline whose stroke
mitres end on the grown box, the same mistake as the spread. A thin
slice with a 20-unit mitred stroke and a spread of 10 still had its
shadow cut off (255 levels). It now asks `grows_by_exactly_its_spread`,
which picks the same shapes and leaves arcs out.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 14:12:27 -05:00
김삼현andClaude Opus 5.5 6b2e464361 M8: a scaled node's spread shadow keeps its room in SVG (#1803)
The SVG export blurs a spread drop shadow in a filter whose region is
the silhouette's page bounds grown by the spread's mitre and the blur.
The spread grows the outline in the node's own units, though, and the
transform then scales it: on a star scaled three times, a spread of 10
mitred out to some 97 units while the region only made room for 48, so
SVG viewers cut the shadow's points off. The spread now grows the region
as far across and down as the transform takes a local step of that
length, as the paint bounds already do.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 14:12:23 -05:00
Trevor BrownandClaude Fable 5.1 83c28cf3ae M6: SVG import: a stretched image stays stretched (#1811)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-01 14:12:18 -05:00
Brandon ThomasandClaude Opus 5.5 5fc2840d90 Release 0.14.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.14.0
2026-11-01 13:58:36 -05:00
Dylan M. Taylor 7b5f8c3699 docs: sync Craft App Suite list with ArtCraft Launcher 2026-11-01 12:30:08 -05:00
Dylan M. Taylor 53259cf50e ci: grant packages write permission to release workflow 2026-10-31 23:43:14 -04:00
Dylan M. Taylor b0673ffc8b packaging(flatpak): add OCI image build and GHCR publishing helper (#1784) 2026-10-31 18:52:48 -04:00
e04c5d2274 text: use craft-font-catalog on Unix (#1765)
* text: use craft-font-catalog on Unix

On Linux and BSD distributions that do not follow traditional FHS layout
(such as NixOS and Guix), or systems using custom font configurations,
fonts are not located under `/usr/share/fonts` or `/usr/local/share/fonts`.
Instead, font directories are declared in `/etc/fonts/fonts.conf` and its
included configuration files (such as `/etc/fonts/conf.d`), or under
`$XDG_DATA_DIRS/fonts`.

`figcraft-text` already depends on `craft-font-catalog`, which provides
`craft_font_catalog::font_dirs`:
- Preserves all existing directory sources (`/usr/share/fonts`,
  `/usr/local/share/fonts`, and user font directories).
- Adds Flatpak host directories (`/run/host/fonts`), `$XDG_DATA_DIRS`,
  and fontconfig directory trees (`/etc/fonts/fonts.conf`).
- Deduplicates the combined list via `craft_font_catalog::dedup_dirs`
  using canonical paths, ensuring equivalent directories and symlinks
  are not redundantly scanned.

Use `craft_font_catalog::font_dirs` in `system_font_dirs()` on Unix, and
retain `unix_user_font_dirs` under `#[cfg(test)]` for its unit tests.

* text: walk each system font folder once

Fontconfig usually lists folders the scan already has (/usr/share/fonts); the list is deduplicated
so their faces aren't indexed twice (CodeRabbit on #1765).

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

* text: scan the catalog's full Unix font folder list

fontconfig_dirs alone dropped /usr/share/fonts, ~/.fonts and the XDG folders when no fontconfig
configuration exists; font_dirs keeps them, adds what fontconfig names, and deduplicates, as the
PR description intended. The local user-folder helper it replaces is removed with its tests (the
catalog applies the same XDG rules).

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-31 10:38:47 -04:00
NetterSilverandClaude Opus 5.5 96dcb3eda9 Give each variable a unique custom property in CSS export (#1738)
Found while testing crates/engine/src/cmd/variables_io.rs:~80-105 (css, non-tailwind `name` closure using css_var_of) with crates/engine/src/dev/codegen/css.rs:41 (css_var_name)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 10:37:26 -04:00
NetterSilverandClaude Haiku 5.5 556d44d47a Reject '+' sign in comment parse_link thread ids (#1740)
Found while testing crates/engine/src/cmd/comment.rs:55 (parse_link)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-31 10:37:22 -04:00
NetterSilverandClaude Haiku 5.5 9a7e5d1a16 Apply paint opacity to CSS gradient stops in code export (#1750)
Found while testing crates/engine/src/dev/codegen/css.rs:121 (css_decls, the PaintKind::Gradient arm calling css_gradient at :255)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-31 10:37:18 -04:00
45e5a25370 Escape backslashes and line breaks in CSS font-family export (#1752)
* Escape backslashes and line breaks in CSS font-family export

Found while testing crates/engine/src/dev/codegen/css.rs:223 (text_decls, the font-family put)

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

* Escape quotes and < in CSS font-family export

A double quote in a family name is escaped instead of turned into a single quote (CodeRabbit on
#1752), and < is written as \3C so a name can't end the generated page's <style> block.

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

---------

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-31 10:37:13 -04:00
NetterSilverandClaude Haiku 5.5 fad47ac8bc Relative line height and letter spacing edits with a unit suffix add to the current value (#1755)
Found while testing crates/ui-egui/src/panels/typography/spacing.rs:166 (parse_line_height, px branch; also :183 and :180 in parse_letter_spacing, px and % branches)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-31 10:37:09 -04:00
NetterSilverandClaude Haiku 5.5 3b5de55587 Keep huge finite values finite when stepping number fields (#1753)
Found while testing crates/ui-egui/src/widgets/field_math.rs:168 (stepped, used by widgets.rs:131 scrubbed)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-31 10:37:05 -04:00
b957160379 Fix code export printing inf for very large finite numbers (#1757)
* Fix code export printing inf for very large finite numbers

Found while testing crates/engine/src/dev/codegen.rs:185 (num)

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

* Keep rem values finite past num6's scaling overflow

num6 had the same x1e6 overflow as num: a huge finite length printed 0rem (CodeRabbit on #1757).

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

---------

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-31 10:37:01 -04:00
aiongg 0abbe44cd4 updates: gate the wasm-only import (#1746) 2026-10-31 01:43:37 -04:00
Dylan M. Taylor 7253909c09 Merge pull request #1739 from aiongg/docs-tidy
docs: tidy agent, contributor and asset docs
2026-10-31 01:06:42 -04:00
Dylan Taylor 29e333b5b1 fix: remove unused tr import in updates_ui 2026-10-31 01:05:13 -04:00
Dylan M. Taylor 2983ea54bc Merge pull request #1743 from aiongg/update-result-dialog
Updates: shared check-result dialog from craft-update
2026-10-31 01:05:04 -04:00
aiongg 57d92d291a updates: show check results with craft-update's CheckResultDialog 2026-10-31 04:42:35 +00:00
aiongg 97dbfe37f6 docs: tidy wording 2026-10-31 04:25:44 +00:00
aiongg 69f7e91db3 docs: tidy agent, contributor and asset docs 2026-10-31 04:17:30 +00:00
Brandon ThomasandClaude Opus 5.5 76f520ffaa Release 0.13.1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.13.1
2026-10-30 23:34:12 -04:00
Brandon ThomasandClaude Opus 5.5 96552d6d09 craft-libs: move to e11f9d9 so craft-menu parses on FreeBSD's Cargo 1.98 (craft-libs#366)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 23:34:10 -04:00
BFlat 12e9b409ed M12: a connector end on any part of an object with Cmd/Ctrl (#1733) 2026-10-31 10:27:56 +07:00
Brandon ThomasandClaude Opus 5.5 6bf38fa963 Release 0.13.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 23:22:51 -04:00
BFlat e2f04b33e0 M11: a tap on a plugin panel's button keeps what was typed in its fields (#1732) 2026-10-31 10:13:01 +07:00
BFlat 6b28ef57dc M4: Dash cap setting for Dash and Custom strokes (#1728) 2026-10-31 09:41:39 +07:00
BFlat b62ec4ef25 Merge pull request #1734 from Silvertree2010/fix/h4145-parse-css-accepts-empty-argument
Reject empty arguments in parse_css color functions
2026-10-31 09:28:57 +07:00
BFlat 3b77c236af Merge pull request #1731 from zral/docs/vector-path-xy-offset
M0.9: document that x/y offset a vector path by its own box
2026-10-31 09:14:25 +07:00
BFlat 87254913af M3: library analytics list how each style and variable is used (#1730)
* M3: library analytics list how each style and variable is used

A file reports how many of its layers use each of a team library's styles and
variables, and Show usage lists them by a Type choice with their layers and
files. Layers in instances count for their component. Also ignores plugins/target.

* M3: the style analytics test waits for the instance report too
2026-10-31 09:13:08 +07:00
NetterSilverandClaude Haiku 5.5 9ae43a4c4e Reject empty arguments in parse_css color functions
Found while testing crates/color/src/lib.rs:247 (css_args, used by the rgb/rgba and hsl/hsla arms of parse_css at :159 and :178)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-31 03:02:39 +01:00
BFlat 57a51af8bb M5: the Controller menu names each button as PlayStation and Switch controllers do (#1726) 2026-10-31 08:41:40 +07:00
BFlat 1c5c9e04c3 M11: widgets draw lines and SVG pictures (plugin API 6) (#1727)
A widget description can have a line, 100 long and black and 1 thick unless told
otherwise, and an SVG that comes in as locked layers, scaled to fit a size and
within the widget's 256 layers. The Counter example uses both.
2026-10-31 08:13:08 +07:00
BFlat 59c7624569 M12: a connector end dropped along a side of a shape attaches to that side (#1708) (#1714) 2026-10-31 07:57:03 +07:00