Commit Graph
2691 Commits
Author SHA1 Message Date
bflatastic e469cc8135 Merge main into #840
# Conflicts:
#	apps/figcraft-cli/src/files.rs
#	apps/figcraft-cli/src/main.rs
#	crates/engine/src/cmd/file.rs
#	crates/engine/src/lib.rs
#	crates/ui-egui/locales/en.toml
#	crates/ui-egui/locales/es.toml
#	crates/ui-egui/src/export_panel.rs
#	crates/ui-egui/src/export_preview_tests.rs
#	docs/file-format-parity.md
#	docs/mcp.md
#	docs/roadmap.md
#	docs/ui-parity.md
2026-10-26 23:23:07 +07:00
bflatastic 0e8c1a0437 #1372: restore the blank line after the ROADMAP status line 2026-10-26 23:10:17 +07:00
bflatastic 1f1c8624c9 #824: window.figcraft is opt-in: installed only with a ?control query entry 2026-10-26 23:10:04 +07:00
bflatastic b87cc3ab47 #824: a request carries main's request gate (state), not the old cancelled flag 2026-10-26 23:06:38 +07:00
bflatastic 4c101fa549 #959: the test is named for what it checks: non-finite numbers are saved as zero 2026-10-26 23:05:53 +07:00
bflatastic 8186c4da3f #1369: Go to main component replaces Create component only when every selected layer is an instance 2026-10-26 23:05:40 +07:00
bflatastic 35108cf8dc #1369: the server key field shows a key only for the server it was typed for 2026-10-26 23:05:39 +07:00
bflatastic d3db02de9a #1378: max lines only while truncation is ENDING, with a REST test for auto height with truncation off 2026-10-26 23:04:38 +07:00
bflatastic b8f34b11c1 Merge main into #320 2026-10-26 23:03:01 +07:00
bflatastic daec0e75d6 Merge main into #287 2026-10-26 23:02:48 +07:00
bflatastic 153250fedf Merge main into #1152 2026-10-26 23:00:18 +07:00
bflatastic 5a9b509074 Merge main into #1366 2026-10-26 22:57:27 +07:00
bflatastic e6e4e9ab8a Merge main into #1053 2026-10-26 22:57:25 +07:00
bflatastic b90749b377 Merge main into #1133 2026-10-26 22:57:23 +07:00
bflatastic d5e3e68158 Merge main into #1372 2026-10-26 22:57:22 +07:00
bflatastic b9fc8f5113 Merge main into #824 2026-10-26 22:57:20 +07:00
bflatastic debf300211 Merge main into #959 2026-10-26 22:57:18 +07:00
bflatastic 089b0d8a04 Merge main into #1373 2026-10-26 22:57:17 +07:00
bflatastic 1427221d61 Merge main into #1369 2026-10-26 22:57:15 +07:00
bflatastic 2458de74f2 Merge main into #1371 2026-10-26 22:57:14 +07:00
bflatastic 66e0e0c629 Merge main into #1384 2026-10-26 22:57:13 +07:00
bflatastic 372727c571 Merge main into #1378 2026-10-26 22:57:12 +07:00
bflatastic badf1f5904 Merge main into #1374 2026-10-26 22:57:11 +07:00
BFlat 6ea44e936f Merge pull request #966 from arksky1/codex/korean-support-20261021
Add Korean support
2026-10-26 22:38:50 +07:00
BFlat 90f9697a0e Merge pull request #1309 from denisg0mes/macos-font-manager-fonts
M7: find fonts that macOS font managers activate outside the font folders
2026-10-26 22:33:42 +07:00
bflatastic 420e704eee #966: one Templates entry, and the drop hint names .sketch, as main's catalogs do 2026-10-26 22:25:10 +07:00
bflatastic e4a78279c0 Merge main into #966 2026-10-26 22:20:32 +07:00
bflatastic f89f656d16 #1309: the font-manager path test runs on Unix only (its paths aren't absolute on Windows) 2026-10-26 22:19:46 +07:00
bflatastic 0ef1156f1f Merge main into #1309 2026-10-26 22:17:30 +07:00
Muamer MustaficandCursor 45326b3b1a M1: a layer in the gap between selected layers still takes the press (#1370)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-26 14:13:36 +01:00
Muamer MustaficandCursor 2136ec20b1 M1: a selected unfilled shape drags over a filled layer stacked below it (#1370)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-26 14:02:23 +01:00
Muamer MustaficandCursor 398c5404f5 M4: a truncated last line's char range covers the chars it takes from the next line (#1375)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-26 13:27:25 +01:00
Muamer MustaficandCursor b6d3e002df M4: truncated text fills its last line, keeps truncating when resized, and auto height takes max lines (#1375, #1376, #1377)
- The last line shown runs on into the word wrapped after it, so the ellipsis
  fills the line ("Lorem consec…") instead of following the last whole word.
- An explicit height (node.set, transform.resize, a resize handle, fixed
  sizing) on truncating text keeps it truncating (TextData::fix_size).
- Max lines on auto-height text hugs up to that many lines and ends in an
  ellipsis; text.maxLines keeps auto height, Type settings show it as
  truncating, .fig export writes textTruncation and import keeps auto height.
- node.get reports maxLines; text.fit measures every line.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-26 13:14:51 +01:00
Ridzzz0Alam 0d7d9ebd00 M1: stamp the file before reading it, so a change made during the read isn't missed (#1330)
Open and Revert to saved recorded the file's size and modification time after reading it: a change written in between would be stamped as already loaded and a later save would replace it. Taking the stamp first makes such a change refuse the next save instead (CodeRabbit on #1374).
2026-10-26 11:46:23 +01:00
Ridzzz0Alam a648700fcc M1: Save no longer overwrites changes another app made to the open file (#1330)
With a file open in the desktop app, figcraft-cli could change it on disk;
the next Save (or auto-save) wrote the app's copy over it and said
"Saved", losing the CLI's changes.

Each tab now remembers its file's size and modification time when it
opens, reverts or saves it (the Stamp library files already use), and
Save and auto-save refuse while the file on disk differs, pointing to
Revert to saved or Save as. Scripts pass `file.save {overwrite: true}`.
Save as and saves to an explicit path are unchanged.
2026-10-26 11:04:01 +01:00
lileeei 1138b13f17 Merge remote-tracking branch 'origin/main' into 1235-transliterate-class-names
# Conflicts:
#	ROADMAP.md
#	crates/engine/Cargo.toml
2026-10-26 17:56:57 +08:00
Ridzzz0Alam acdc714537 M3: an instance-swap property's default menu scrolls (#1338)
On a main component's Properties row, the default of an instance-swap
property opened a menu of every component in the file at full height, so
in a file with many components (an icon library) the bottom ones ran off
the screen and couldn't be picked. The menu now scrolls past 320 pt like
the instance's swap menu, is at least 200 pt wide, ticks the current
default and is named for assistive technology.
2026-10-26 10:29:49 +01:00
Mojtaba JafarzadehandClaude c9f834f13c ui: drop an unused variable in the key-binding test (CI gate fix)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-26 11:35:35 +03:30
Mojtaba JafarzadehandClaude c73ff432cb ui: rustfmt the context-menu instance check (CI gate fix)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-26 11:18:48 +03:30
Mojtaba JafarzadehandClaude 65d270dd42 ui: context menu offers "Go to main component" for instances
Right-clicking an instance always showed "Create component" (and never "Go to
main component"), so an imported instance looked disconnected from its main
even though the link was intact. When the selection is an instance, replace
"Create component" with "Go to main component" in the context menu, matching
Figma. A regression test covers the menu contents for an instance.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-26 10:55:38 +03:30
Denis Gomes f0623ff89c M7: show a magnified image's pixels on the canvas
Zoomed in on an image, the canvas smoothed it with bicubic sampling, so
a screenshot under inspection went soft at every edge and its pixels
could not be told apart. Checking a screenshot of a live page against
its design up close needs the pixels as they are.

The canvas now samples an image paint at the nearest pixel once each
image pixel covers two or more device pixels. Below that the image stays
smooth: between 1x and 2x nearest sampling draws pixels one and two
device pixels wide side by side, which looks jagged rather than sharp.

Exports, thumbnails, PDF and SVG are unchanged: the switch is a render
option, magnified_image_pixels, that only the canvas sets, and the
retained renderer reuses a render only when it matches. Pixel preview
was not a fit: it rasterises the whole canvas at 1x or 2x, so vectors
and text go blocky along with the image.
2026-10-26 03:23:56 -04:00
BFlat 63d926876f M10: branches in live sessions (#1367)
Branches of a file in a live session: create, edit, review, update from
main and merge while the file is in a session. The branch stays with its
author and makes ids in their own client space far above the main file's;
merging is one synced edit and one undo step; peers' edits merge against
the branch's own base and conflicts resolve as offline; a view link still
refuses merging; a branch made outside the session that adds layers is
refused with a reason. Branch history entries for creation and updates
from main. Fuzz and junk tests extended to export settings, guides and the
live case. Docs: gap 17, collaboration parity, ROADMAP, mcp, protocol.
2026-10-26 13:57:24 +07:00
BFlat 8d60360173 M11: widgets take text input and a property menu (plugin API 4) (#1365)
* M8: widgets take text input and a property menu

Plugin API 4 (gap 6). A widget's text layer can be an editable field:
a double-click edits it like any text, and when editing ends the value
(cleaned, at most 1,000 characters) goes into the widget's state under
the field's name and its plugin redraws, as one undo step. A widget can
also carry a property menu of up to 8 actions, toggles and colour
choices, shown in a small bar over it while it's selected.

- widget.setText and widget.menu drive the same paths from scripts,
  the CLI and MCP; widget.insert/list also report fields and menu
- descriptions, values and stored menus are validated as untrusted;
  an API 3 plugin drawing a field or menu is refused, older hosts
  refuse API 4 manifests; no new host imports
- SDK reads the new events; the Counter example gains a label field
  and a menu (reset, steps of ten, a colour)
- tests for fields, menus, canvas editing, rollback, forged data and
  live sync; junk sweep extended; labels in every command catalog
- docs: plugins, mcp, gaps, target-app-parity, ROADMAP, roadmap

* M8: widget property menu on egui 0.37

Id::new and Ui::id are deprecated in egui 0.37: the widget bar's area uses Id::unique and its buttons' interaction ids come from ui.scope_id().

* M11: a double-click a board object or a widget field takes, in a function of its own (Sonar)
2026-10-26 13:31:53 +07:00
Mojtaba Jafarzadeh 6442a49d13 Merge latest upstream main 2026-10-26 09:58:01 +03:30
NetterSilverandClaude Haiku 5.5 ca6426b9a1 Keep full precision when converting px to rem in code export
Found while testing crates/engine/src/codegen.rs:122-150 (lengths_to_rem calls num, which rounds to 2 decimals, at :112)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-26 06:24:14 +00:00
Mojtaba JafarzadehandClaude c826c74e6e ui: bind the share server key to its server
The Share popover's server key was stored without its server, so changing the
server in Preferences would send the previous server's key to the new one.
Remember the key with the server it was typed for and only send it when the
addresses match. A regression test covers the mismatch.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-26 09:39:21 +03:30
BFlat 948358eefa Docs: README screenshots of Boards and Dev Mode measurements (#1252) 2026-10-26 13:09:03 +07:00
Mojtaba JafarzadehandClaude 2f5286a387 collab-net: server keeps publish uploads alive with the reply timeout
A publish uploads a whole file; a large project on a slow link takes the
server a while to receive and answer. But the server's one-shot request
connections (manage, hosting, library, plugins) used the short request_idle
as their read timeout, so a slow upload could be cut off mid-processing. The
manage/hosting connections that carry uploads now wait the longer
request_reply_timeout (as the client already did), keeping the short idle
for the other one-shot requests and sessions.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-26 09:31:26 +03:30
BFlat d3782fdc43 M12: board templates and tables (#1363)
* M12: board templates and tables

Five built-in board templates (retrospective, brainstorm, weekly planner,
flow chart, kanban board) placed as ordinary board objects in one undo step
(board.template, board.templates) from a toolbar picker with pictures, and
board tables made of auto layout frames (board.table, board.tableEdit; up to
50 x 20), typed into with a double-click and edited by row and column from
the bar over the selection. Docs: boards-parity, gap 24, ROADMAP, mcp.

* M12: board templates picker on egui 0.37

Id::new and Ui::id are deprecated in egui 0.37: the templates picker's area uses Id::unique, its buttons' interaction ids come from ui.scope_id(), and its test reads the board bar's area by Id::unique.
2026-10-26 12:52:39 +07:00
BFlat bfd6e5f83a Merge pull request #1359 from Silvertree2010/fix/h2744-color-to-css-rounds-alpha-to-2-d
Keep 8-bit alpha when printing colours with Color::to_css
2026-10-26 12:51:22 +07:00