Commit Graph
29 Commits
Author SHA1 Message Date
bflatastic dbc9bf7236 Merge main into #1987 2026-11-07 10:34:16 +07:00
Trevor Brown 4b351d9468 Merge remote-tracking branch 'upstream/main' into fix/jam-connector-control-points
# Conflicts:
#	crates/doc/src/lib.rs
#	docs/boards-parity.md
#	docs/file-format-parity.md
2026-11-06 21:55:49 -05:00
bflatastic 95d3978721 Merge main into #1947 2026-11-07 09:38:58 +07:00
Trevor BrownandClaude Fable 5.1 5855c8705c docs: boards-parity's status line and revision history move with its .jam row (#1910)
Review: the row changed without the status line and a history row, which land together.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-04 02:39:24 -05:00
Trevor BrownandClaude Fable 5.1 bda7ca910d M6: a FigJam elbow connector saved with its path keeps it on import (#1910)
The `.jam` importer routed every elbowed connector itself, so one drawn around a layer by hand in
FigJam came in routed through it. FigJam saves the path as `connectorControlPoints`: one per run
between the first and the last, each a point on its run (in the connector's parent's coordinates)
with the run's axis; the first run leaves the start's side and the last arrives at the end's. They
become the `ConnectorPath::Runs` a board connector reshaped by hand has, walked by
`figcraft_doc::route_along`, so the path is kept exactly. Points that don't make such a path (off
both axes, two runs the same way in a row, a first or last run sideways to its side, more runs than
a hand could make) leave the connector to the router as before, and only connectors routed here
count in the "own routing" note. `figcraft_doc::attach_points` and `MAX_RUNS` are exported for it.
Docs: file-format-parity.md, boards-parity.md.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-04 01:52:02 -05:00
Trevor BrownandClaude Fable 5.1 7be7c054eb M12: a connector joined to a layer inside a moving section is no snap target; the docs say which connectors share a run (#1916)
Review: a section moving carries its stickies and their connectors, so those connectors and
their labels are no snap targets for the section either (an end counts as carried when its node
or any ancestor is moving). The parity rows, the END_GAP doc and the test's doc no longer say
connectors from one side run together: elbows share their first run along the normal, curves
leave tangent to it, straight ones fan out from the same point.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-03 21:46:34 -05:00
Trevor BrownandClaude Fable 5.1 2dc7bed2a0 M12: connectors attached to a side start 4 pt outside the border (#1916)
A connector end attached to a side was routed from the middle of that side, so the stroke's
centre line started on the border and half its width plus the round cap lay on the fill, and
several connectors leaving one side piled up into a knot sticking into the card. FigJam starts
the line a few pixels outside the border and connectors leaving one side run together along the
side's normal before they fan out (the issue's screenshots). `board_route::END_GAP` (4 pt): an end
attached to a side (`RouteEnd::Box`) starts that far outside it along the side's normal; an end
placed by hand on the object (`RouteEnd::On`) keeps its exact point; a free end is unchanged.
The pinned route coordinates in the engine, format and UI tests move with it; the overlay's
attach points stay on the border. Docs: the Connectors rows, status line and history of
boards-parity.md.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-03 21:08:19 -05:00
Trevor BrownandClaude Fable 5.1 5eb28b310a M12: the bar above the selection stays away while a quick-create handle is dragged (#1919)
Review: letting a handle go over the selection bar made the next shape behind it. The bar
hides while a "+" is dragged, as it does for any drag (board_connect::dragging), so there
is nothing to drop behind; the drop makes the next one where the bar was, and the bar is
back once typing in it ends. Test the_bar_stays_away_while_a_handle_is_dragged; the docs
rows say the toolbar and the bar.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-03 14:47:46 -05:00
Trevor BrownandClaude Fable 5.1 246a89733c M12: quick-create drag: stickies and shapes in sections, parent coordinates, the handle's side, no drop off the canvas (#1919)
Review: the drop target is the topmost sticky or shape under the pointer, sections and frames
looked into (board::sticky_or_shape_at, instead of the stamp's any-layer hit test on the page's
children); the drop point is placed in the parent's coordinates; the connector leaves by the
handle's side (as the preview draws it) and arrives by the facing side; a handle let go off the
canvas makes nothing; the parity rows on quick-create handles agree.

Tests: dropping_a_handle_on_a_shape_inside_a_frame_joins_it, letting_a_handle_go_over_a_panel_makes_nothing,
the_next_one_goes_where_it_is_dropped (frame case).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-03 12:44:59 -05:00
Trevor BrownandClaude Fable 5.1 d48aa59ec7 M12: drag a "+" handle to drop the next shape anywhere or join another object (#1919)
The quick-create handles only took a click. As the help says ("drag the preview to any location
on your board"), a handle can now be dragged: the preview follows the pointer and, let go on empty
board, the next sticky or shape is made there, centred on the pointer, joined by a connector whose
ends take the sides facing each other (board.addConnected gains at: [x, y]); let go on another
sticky or shape, a connector joins the two instead (board.connector), that object outlined while
over it. figcraft_engine::board::object_at exposes the hit test a stamp uses. The click is as
before.

Tests: board_connect_tests (two), board_connected_tests::the_next_one_goes_where_it_is_dropped.
Docs: boards-parity row, status line and revision history.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-03 11:52:41 -05: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
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
BFlat b462a48346 M12: a connector's path can be reshaped by dragging its path handles (#1710) (#1717) 2026-10-31 04:53:36 +07:00
BFlat 4bcfd5247f M12: boards have 16 more shapes, in grid pickers (#1705)
* M12: boards have 16 more shapes, in grid pickers

* M12: a board shape's id and name sit in one table
2026-10-31 04:27:12 +07:00
BFlat 9f4d1ce75b M12: board votes say who voted for what, and earlier votes' results are kept (#1666)
* M12: an ended vote's results say who voted for each object

* M12: a board keeps earlier votes' results, listed in Results and deleted one at a time

* M12: the vote Results popover is drawn by small helpers, and its stepper, rows and Clear are tested
2026-10-31 01:19:03 +07:00
BFlat e97961ba66 M12: stamps stick to the objects they land on, which are highlighted first (#1671)
* M12: stamps stick to the objects they land on

A stamp sticks to the topmost object under its centre (BoardItem::Stamp gains an optional on, left out when empty so older files open with stamps on nothing) and the board's normalize pass carries it when that object moves or turns, once when both move together. A stamp dragged onto another object sticks to that one, off everything to nothing; one whose object is deleted stays where it is. Gap 24.

* M12: the object a stamp will stick to is highlighted

While the stamp tool is over an object, or a stamp is dragged over one, the object it will stick to is outlined with the canvas's hover outline (Overlay::stamp_target, found by the same stamp_target as board.stamp and settle_stamps). A drag no longer drops what it moves into the auto layout of a sticky, shape with text or table: board objects take no drops; a stamp already inside its sticky moves with it once. Builds on #1671. Gap 24.
2026-10-31 00:25:38 +07:00
BFlat 7e9d6ce8c5 M12: line ends, dashes, weight and any colour on a board connector's bar (#1596) (#1632)
The bar over a selected connector adds start and end point menus with every line end, a line style menu (solid or dashed, weights 1 to 6) and a colour wheel opening the colour picker, beside the board colours and line type; every control names itself on hover. UI only, through board.setStyle and the stroke's dashes and weight.
2026-10-30 22:50:20 +07:00
BFlat 4f5a25cc82 M12: spreadsheet cells paste onto a board as a table (#1663) 2026-10-30 22:32:44 +07:00
BFlat 34fce9bfcf M12: create the next board shape already connected (#1631)
* M12: create the next board shape already connected (#1597)

A selected sticky or shape shows a + beside each side; hovering one previews where the next goes, clicking makes one of the same kind, size and colour there, joined by a connector, and starts typing in it, in one undo step. board.addConnected {id?, side?, edit?} does it from commands.

* M12: the connected-shape handle and command in every full catalog (#1597)

* M12: Shift+Cmd/Ctrl+Enter on a board shape adds the next one already connected (#1597)
2026-10-30 15:59:13 +07:00
BFlat 8ee8ba6ce7 M6: FigJam .jam files open, as boards (#1342) (#1586)
* M6: FigJam .jam files open like .fig files (#1342)

A .jam is the same archive as a .fig (its canvas header reads fig-jam.), which the .fig reader already took; File > Open and its filter, drag and drop, file.import and the command line now take .jam too, and the home screen shows its thumbnail. FigJam layers come in as the .fig reader makes them (stickies and shapes with text as frames with their generated layers, other FigJam layers as frames or vectors with a note, unknown types left out with a note). Tests use a synthetic fig-jam. canvas and a .jam made from our own export.

* M12: a FigJam .jam file opens as a board (#1342)

The .fig reader marks a canvas with FigJam's fig-jam. header as FileKind::Board, so a .jam opens with the board toolbar, the dot grid and the board panels and saves as a board; a .fig stays a design file, and importing a .jam into an open file leaves its kind alone. Its objects stay ordinary layers (frames and vectors with the existing import notes). Builds on the .jam opening branch (#1586).
2026-10-30 08:03:56 +07:00
bflatastic 9d86403f3a #1547: drop the board grid entry from the right-click menu 2026-10-30 00:06:50 +07:00
Claude 2d507d959d M12: board grid settings: dots, lines, graph paper or none
The board canvas's background grid is now a preference (`board.grid`): dots
(the default), lines, graph paper (a strong line every 2-12 cells over fainter
ones, like Japanese section paper) or none, with spacing (4-512), mark size and
contrast. Preferences gets a Board grid section; right-clicking an empty board
offers Board grid settings. Zoomed out the grid still thins out (by halves, or
down to graph paper's strong lines), and dots no longer shrink to a single
pixel, so the grid stays visible at low zoom.

The renderer draws lines as well as dots, with a configurable strong-mark
rhythm; a crossing of two lines is blended once, in the stronger colour. A
hand-edited preferences file falls back to the default grid instead of losing
the other preferences.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FEkCVd8n1eC6xTHebmHMDR
2026-10-29 14:44:18 +00:00
BFlat d4e6ad5d81 M12: the connector tool previews the connector it will make, ends snapping to attach points (#1387) (#1526) 2026-10-29 18:29:48 +07:00
叶林橦 5f7aea91f9 ui: rebuild the toolbar pill on a 32 pt grid, without the Resources button
Brings #1210 onto main as it stands after #1019 and #1209, and keeps both:

- #1019's flyout caret keeps its 16 pt target, 2 pt clear of its tool (#988).
- #1209's narrow-window handling stays as it landed: the pill is never wider
  than the canvas less a margin and its buttons scroll inside it under a drag
  or the wheel, the help button lifts above it when they'd overlap, and the
  pill still clips to itself rather than floating over the panels.

The design itself, as #1210 proposed it:
- One grid for every state of the pill: 32 pt cells, 8 pt padding, 8 pt between
  top-level items (the divider included), a 1 pt divider as tall as the content,
  16 pt carets, 14 pt mode marks, and a 32 pt mode strip whose current mode is a
  plain inset with no outline.
- The Resources button goes; the left rail's Assets tab, Shift+I, Alt+2 and
  View > Panels > Assets remain the ways into the Assets panel (and the locale
  key, its test and the parity notes go with it).
- The vector edit and shape builder pills move onto the same grid, so a pill
  never changes its spacing as the tool changes.

main_width is now the same walk the pill draws, and a test walks it for the
design and board toolbars: the last item ends exactly PAD from the right edge.
That caught the board pill asking for 8 pt more than it drew.
2026-10-27 12:28:49 +08:00
aiongg 60c671da66 docs: update source paths for the layout moves 2026-10-26 20:36:51 +00:00
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 4fad29a66e M12: board timer and voting sessions (#1361)
* M12: board timer and voting

A countdown everyone on a board sees (board.timer, board.timerState), synced as its end time or the
time left while paused, and voting sessions (board.vote, board.voteResults): votes per person, on
everything, stickies or the selection; clicks vote, your badge takes a vote back; your own votes
show while it runs, everyone's with a ranked list once it ends. Timer and vote sync as document
properties and ballots as one entry per voter; neither is an undo step. A pill at the top right
of the board, new Timer, Pause and Vote icons, labels and strings in every catalog, docs.

* M12: board timer and voting on egui 0.37

Id::new is deprecated in egui 0.37: the timer and voting area and its memory ids use Id::unique.

* M12: board.vote's start and ballot changes in functions of their own (Sonar)
2026-10-26 12:28:59 +07:00
BFlat 26291aff2c M12: boards dot grid, re-attaching connector ends, curved connectors (#1249)
* M12: boards dot grid, re-attaching connector ends, curved connectors

Board pages draw a dot grid in the canvas render, after the page colour
and under the layers (figcraft_render::Dots), thinned out when zoomed out
and coloured from the theme's ink against the page. A selected connector
shows its ends as handles; dragging one onto an object re-attaches it,
onto empty canvas leaves it free (board.reattach, one undo step, also
over MCP). Connectors can be curved, and elbows go around the objects
they join when the short way would cross them.

* M12: boards dot grid: blending a dot in a function of its own (Sonar)
2026-10-26 11:52:16 +07:00
BFlat 8167f13a6a M12: Boards: a collaborative whiteboard file kind (#1229)
Board files (File > New board) with sticky notes, shapes with text, connectors that follow what they join (straight or elbow, arrowheads, labels), marker, highlighter and eraser, and stamps; a board toolbar and a contextual bar; the Design panel hidden on boards, Prototype and Dev Mode refused there. Boards are ordinary FigCraft files built from ordinary layers, so saving, undo, export, MCP and live sessions work unchanged. File tabs, recent files and Open files show a pen nib for design files and a note for boards (original icons drawn in code).
2026-10-24 04:18:55 +07:00