Commit Graph
990 Commits
Author SHA1 Message Date
bflatasticandClaude Opus 5.5 20ed00784f Desktop: report an unusable log folder through the logger, ROADMAP (review of #465)
The "no log file" message went through eprintln!, which panics when
standard error is a broken pipe; log::warn! reaches standard error the
same way (the file sink has already given up) and never panics.
ROADMAP: the log file in "Shipped so far" and "Last updated".

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 17:07:24 +07:00
Gert Pellin ba9edcdc7f Desktop: write log records to standard error and a rotating log file
The desktop app installed no logger, so every log::warn!/log::error! in
the workspace was discarded: the graphics adapter in use, a lost graphics
device, the engine guard's report of a recovered panic. A launch from a
desktop menu has no terminal either, so there was nothing to attach to a
bug report.

apps/vectorcraft/src/logging.rs (no new dependency):
- standard error plus logs/vectorcraft.log next to the preferences
  (~/.config/vectorcraft/logs, or under $XDG_CONFIG_HOME); each launch
  rotates the previous log to vectorcraft.1.log and .2.log, so the log of
  a run that crashed survives the next start; the file is capped at 16 MiB
- records logged before the settings directory is known are buffered
  (bounded) and written once the file is attached
- default levels: info for vectorcraft*, warn for everything else;
  RUST_LOG replaces them with env_logger-style directives
- never panics: an unusable directory or a failed write leaves standard
  error as the only sink
- runs with VECTORCRAFT_NO_PREFS (agents' test runs) log to standard
  error only, so they don't rotate away the user's own logs

The logger is installed first in main and the file is opened after
argument parsing (--version leaves no file). Log messages of this crate
drop their "vectorcraft: " prefix, which the record's target now shows.
vectorcraft-cli keeps its own MCP logger (vectorcraft_mcp::logging).
Documented in docs/development.md (Logs, Environment variables).
2026-10-08 17:07:08 +07:00
bflatasticandClaude Opus 5.5 0bdce8c633 AI import: groups and nested groups survive
Legacy PostScript .ai files (Illustrator 3-8, and their EPS) open through
the EPS interpreter, which only recorded what was drawn: every group came
in flattened. In a file in Illustrator's format (its %AI comments, or
Illustrator named as the creator) the `u` ... `U` it writes at the top
level now open and close groups, whatever its prolog defines them as, so
groups come in nested as they were, between and inside clipping groups.

clipnest's Clip carries an optional region: without one it is a plain
group, nested in the same chain as the clips (ids given in opening order,
so a chain of clips and groups sorts by id).

Clips nested without end used to nest clipping groups past the stack
(a stack overflow in EPS and EMF/WMF import): clips and groups now nest
at most 128 deep with a warning, and each object's chain counts against
the EPS reader's drawing budget.

PDF-compatible .ai (Illustrator 9+) can't get the same: its PDF content
draws each object on its own and doesn't mark plain groups (only layers,
clipping groups and groups with opacity, blending or a mask, which
already come back); the groups live only in the private data, which is
out of scope. Documented in ROADMAP and docs/mcp.md.

Addresses Discord feedback.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 17:06:57 +07:00
BFlat d66a8b6127 Merge pull request #468 from storytold/feat/type-conversion-widget
Type: the point/area type widget converts between them; area type made by dragging resizes
2026-10-08 17:02:58 +07:00
bflatasticandClaude Opus 5.5 940285dd9e Type: the point/area type widget converts between them; area type made by dragging resizes
Discord feedback: type in a frame dragged with the Type tool could not be resized or switched
between area and point type the way the reference app allows.

- The Selection tool shows the type widget beside a single selected point or area type object:
  a small circle outside the middle of its bounding box's right side, hollow on point type and
  filled on area type (vectorcraft_tools::typewidget, drawn by the canvas from the same geometry).
  Hovering it shows the arrow with a type badge; its clicks neither drag nor deselect, and a
  double-click runs type.convertToAreaType / type.convertToPointType (the Type menu's commands),
  keeping the text and its styles in place, one undo step, reachable over MCP.
- Resizing area type made by dragging already works on main (#252): the bounding box resizes the
  type area and the text reflows. A regression test now covers the reported flow.
- docs/mcp.md and ROADMAP.md describe the widget.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 16:54:12 +07:00
BFlat 852848f4ed Merge pull request #467 from storytold/feat/properties-fill-stroke-shortcuts
Properties: Fill and Stroke; Shift+F7 opens Align; Alt+wheel zooms
2026-10-08 16:53:31 +07:00
bflatasticandClaude Opus 5.5 c5b5dbb6ad Properties: Fill and Stroke; Shift+F7 opens Align; Alt+wheel zooms
Discord feedback.

- Properties panel: the Appearance section's Fill and Stroke rows now use the
  Control bar's widgets: the chips with their chevron and swatch/mixer
  popover, the underlined Stroke link that opens the Stroke panel as a
  popover (stroke::link, shared with the Control bar) and the weight spinner
  with its presets (stroke::weight_field, which also follows the Type tool's
  selected characters). With nothing selected the Document view shows them
  too, as the Control bar does: they set up the next object drawn.
- Window menu panel keys as in Illustrator: Brushes F5, Layers F7, Align
  Shift+F7, Transform Shift+F8, Info Cmd+F8, Pathfinder Cmd+Shift+F9,
  Symbols Cmd+Shift+F11, Character Cmd+T, Paragraph Cmd+Alt+T, Tabs
  Cmd+Shift+T, OpenType Cmd+Alt+Shift+T (beside the existing Color, Color
  Guide, Appearance, Graphic Styles, Stroke, Gradient, Transparency and
  Attributes keys). The dock's tabs (Properties, Layers, Libraries) join the
  panel shortcut table and the Keyboard Shortcuts editor through
  state::all_panels, which window.panel's name lookup and the catalog's
  label list use too.
- Alt-wheel (Option on the Mac) zooms about the pointer whatever General >
  Zoom with Mouse Wheel says: egui spreads a notch over a few frames, and the
  rest of an Alt turn scrolled once Alt was up (also over the control
  channel's ui.wheel); the turn's own modifiers now decide. Pinch zoom is
  covered by the test too.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 16:46:34 +07:00
BFlat a9b28cc22a Merge pull request #464 from storytold/revert/gentoo-readme
README and contributors: drop the Gentoo overlay section
2026-10-08 16:41:43 +07:00
bflatasticandClaude Opus 5.5 bde3a222bb README and contributors: drop the Gentoo overlay section and its credit entry
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 16:41:00 +07:00
BFlat 752a67e16c Merge pull request #462 from switch87/readme-gentoo
README: install on Gentoo from the ::snakebyte overlay
2026-10-08 16:31:40 +07:00
Gert Pellin 746d2a6b07 Contributors: credit switch87 as Gert Pellin 2026-10-08 16:30:04 +07:00
Gert Pellin 39a2338b2f README: install on Gentoo from the ::snakebyte overlay 2026-10-08 16:30:04 +07:00
BFlat 2a03e9b87f Merge pull request #460 from storytold/fix/issue-457
Fix #457: paste screenshots from the clipboard on macOS, Windows and the web
2026-10-08 16:19:37 +07:00
bflatasticandClaude Opus 5.5 8f771faa9e Fix #457: paste screenshots from the clipboard on macOS, Windows and the web
A screenshot on the clipboard didn't paste everywhere:
- macOS: the Paste menu item (which takes Cmd+V there) was enabled for text
  only, so with nothing copied in the app Cmd+V did nothing; and arboard
  reads the pasteboard's TIFF only. The pasteboard's types now enable Paste,
  and its PNG, else TIFF, pastes as it is.
- Windows: bitmaps came through CF_BITMAP and GetDIBits, which drops alpha.
  Paste now reads PNG, else CF_DIBV5, else CF_DIB, decoded with their colour
  masks and tables (a BMP file header in front, which image's headerless
  decoder gets wrong for masks after a BITMAPINFOHEADER), opaque when the
  alpha is zero throughout as screenshots leave it, capped at 32768 px a side.
- Web: only SVG text pasted. The page's paste event now hands the first
  picture or file that is art to the app (VectorcraftApp::paste_from_host),
  pasted with the chord held, like the desktop's paste keys.
- Linux reads image/png already; its Paste menu item still waits for text
  (no cheap way to ask arboard for a bitmap), the paste keys take one.

Bitmaps paste as embedded images at the view centre, as before.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 16:15:20 +07:00
BFlat f22c100cc5 Merge pull request #459 from storytold/fix/issue-458
Fix #458: Font Size and Leading combo boxes in the Character and Properties panels and the Control bar
2026-10-08 16:13:01 +07:00
bflatasticandClaude Opus 5.5 0c4df274aa Fix #458: Font Size and Leading combo boxes in the Character and Properties panels and the Control bar
The Properties panel's Font Size and Leading were plain typed fields and the
Control bar had no type controls. All three places now use the shared
editable combo (`widgets::spin_field`: typing, arrow and spinner stepping,
label scrubbing, a preset dropdown in the type unit):

- Character panel: the size and leading grid is shared with the Properties
  panel (`character::metrics_grid`), which now shows the font style, Font
  Size, Leading, Kerning and Tracking as combos and applies them to the
  Type tool's selected characters as the Character panel does.
- Control bar: with type selected or edited, a Character link (the Character
  panel in a popover), the font family and style menus and the Font Size combo.
- Presets as Illustrator lists them: sizes 6-72 pt; Leading has Auto first
  (`widgets::spin_field_auto`, `text.setStyle {leading: "auto"}`) and then
  the size ladder instead of 120% values; Kerning and Tracking -100...200.
- Font Size, Leading, Kerning and Tracking show blank where the selected
  text's values differ (`character::shared`); the spinner does nothing on a
  blank field instead of jumping to the step size.

Each pick is one `text.setStyle` / `text.setRangeStyle` step, so MCP and the
control channel are unchanged. Translations for the two new strings.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 16:10:14 +07:00
BFlat fa405da794 Merge pull request #453 from wstock/fix/issue-394-smart-guides
Part of #394: Smart Guides display options and Snapping Tolerance
2026-10-08 15:51:01 +07:00
bflatasticandClaude Opus 5.5 42fced4725 Smart Guides: "align" also on a handle already in line, Free Transform's move offset and slice readouts follow Measurement Labels (review of #453)
- `Targets::align_rects` tells `snap_point_with` an axis lined up even when
  nothing moved or Alignment Guides hide the line, so the "align" label stays.
- Free Transform's move offset is a measurement label (as the Selection
  tool's), its scale/rotate readouts Transform Tools; slice move/resize
  readouts follow Measurement Labels.
- Snap to Point (Smart Guides off) keeps the default look for moves too, as
  for drawn points and guides.
- Test: guides dragged out of a ruler (#451) follow Snapping Tolerance,
  Anchor/Path Labels and Measurement Labels; docs/mcp.md.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 15:46:15 +07:00
wstockandClaude Fable 5.1 14d7b3ddce Part of #394: Smart Guides display options and Snapping Tolerance
Color, Alignment Guides, Anchor/Path Labels, Measurement Labels,
Transform Tools, Object Highlighting and Snapping Tolerance are read:

- tools: `guides::GuideStyle` on `Targets` (`styled(cx)`) colours the
  lines and labels and leaves them out when their option is off, the
  snap itself unchanged; `ToolContext` gains the six fields and
  `snap_tol()`, replacing the 5 px literal for every smart guide snap
  (drawn points, moves, bounding-box handles, ruler guides, artboards,
  reference points). The tools gate their `Overlay::Measure` readouts on
  Measurement Labels (drawing, moving, ruler guides, artboards) or
  Transform Tools (scaling, rotating, Free Transform, transform tools).
- engine: `with_tool_cx` fills them from `Prefs` (the colour parsed, magenta
  as fallback); the colour's default is `#ff3dfc`, what the tools drew.
- ui-egui: the hover outline needs Object Highlighting and Smart Guides.
- Tests in tools (guides, select), engine (tests_prefs) and the canvas;
  docs/mcp.md and ROADMAP.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-08 15:46:15 +07:00
BFlat d92ade9117 Merge pull request #456 from storytold/fix/issue-455
Fix #455: the toolbar's double arrow and Window › Toolbars switch one/two columns
2026-10-08 15:41:41 +07:00
bflatasticandClaude Opus 5.5 297f6e93d3 Fix #455: the toolbar's double arrow and Window › Toolbars switch one/two columns
The toolbar went to two columns whenever the window was shorter than the
single column (about 990 pt for Basic, more for Advanced), so on most
screens it was always double and the double arrow and the Window menu item
flipped a flag nothing read. The column count is now the user's choice
alone; a window too short for the tools scrolls them (#84).

- window.toolbarColumns takes {double?: bool} (set or toggle, returns the
  new state) and reports `checked`; the double arrow runs it.
- The Window › Toolbars item reads "Double Column" with a check mark;
  catalogs updated (cs, es, ja, pt-br, zh-hans, zh-hant) and an es @msg row
  for the new error.
- Headless tests: the arrow and the command toggle the column count in a
  700 pt window (both fail on main).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 15:38:54 +07:00
BFlat d8e79078e5 Merge pull request #454 from storytold/fix/issue-451
Part of #451: guides dragged out of the rulers snap, artboard guides
2026-10-08 15:28:04 +07:00
bflatasticandClaude Opus 5.5 5d65699043 Part of #451: guides dragged out of the rulers snap, artboard guides
Guides dragged out of a ruler did not snap at all (only Shift to the ruler's
ticks): they now go through the engine (`Session::ruler_guide`, a
`NewGuide` previewing `guide.add`, one undo step) and snap as a moved guide
does: with Smart Guides to the edges, centres (so the sides' midpoints) and
anchors of the art and of the artboards, labelled; with Smart Guides off,
View > Snap to Point pulls new and moved guides onto anchors. Moving art
with the Selection tool already snapped flush to artboard edges and centres
with Smart Guides on; a test now covers it.

Artboard guides: `Guide.artboard` holds an artboard id (written only when
set, so canvas guides save as before and older files open unchanged).
`guide.add {artboard}` makes one, `guide.list` reports it; a guide dragged
out of a ruler with the Artboard tool belongs to the active artboard. It is
drawn, picked and snapped to across its artboard only, moves with it
(`artboard.move`, a pure move in `artboard.setProps`, `artboard.rearrange`),
is copied with it (`artboard.duplicate`, Alt-drag copy) and deleted with it
(`artboard.delete`, the guide selection kept in step).

Guides as Layers rows with their own lock and hide (part d) stay open: ruler
guides are not layer nodes; Lock Guides locks them all, and Make Guides
paths are Layers rows already. Listed in the ROADMAP parity row.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 15:23:18 +07:00
BFlat 5f9d280892 Merge pull request #452 from storytold/fix/issue-446
Fix #446: copy and paste artboards with their art
2026-10-08 15:06:53 +07:00
bflatasticandClaude Opus 5.5 a0819151a0 Fix #446: copy and paste artboards with their art
With the Artboard tool chosen, Copy and Cut take its artboard together with
the art fully inside it (when Move/Copy Artwork with Artboard is on), and
Paste brings both back in one undo step: Paste right of the last artboard,
Paste in Place / in Front / in Back where it was, into this or another
document, the art going back into the layers it came from (Paste on All
Artboards pastes the art alone). The clipboard carries the artboard
(Clipboard::artboard); a pasted artboard keeps its name when it is free.

Duplicate Artboards (the Artboards panel menu, and now a row dragged onto
New Artboard) copies the art too: artboard.duplicate {index?, art?} defaults
to the Artboard tool's artboard and moveArt option and reports the copies.
It shares copy_artboard with the Alt-drag copy (artboard.move {copy}).

New commands reachable over MCP: artboard.copy and artboard.cut
{index?, art?}; edit.copy / edit.cut run them while the Artboard tool is
chosen (and are enabled then with nothing selected). Docs (mcp.md), the
tool and panel docs, translations of the new labels and the ROADMAP follow.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 15:02:33 +07:00
BFlat e17699b7ea Merge pull request #450 from storytold/fix/issue-444
Fix #444: tool cursors are OS cursors, so the pointer no longer trails over the canvas
2026-10-08 14:44:05 +07:00
bflatasticandClaude Opus 5.5 f46527e0bd Fix #444: tool cursors are OS cursors, so the pointer no longer trails over the canvas
Over the canvas the window hid the system cursor and painted the tool's
cursor glyph into its own frame. That glyph reached the screen only after
the frame was rendered, queued (two frames by default) and composited, so
on Windows it visibly trailed the real pointer, on any GPU: the "sluggish
mouse" of the report. Frame times were not the cause (0.4 ms empty,
1.5 ms median on a 20 000-path document, and no repaints while idle).

- cursors: the glyphs are collected as shapes, tessellated by egui and
  rasterized into straight-alpha RGBA bitmaps (anti-aliased, hotspot on a
  pixel corner), cached per cursor and display scale so the same Arc is
  handed over every frame and egui-winit keeps its OS cursor.
- canvas: on Windows and Linux the tool cursor goes to the OS through
  ctx.set_cursor_image; the system moves it itself. macOS (bitmaps sized
  in points) and the web (no bitmap cursors in eframe) keep painting it.
- app: the wgpu surface queues one frame instead of two (LOW_LATENCY):
  the GPU only composites the CPU-rendered canvas, so everything drawn in
  the window follows the pointer a frame sooner.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 14:41:22 +07:00
BFlat 1ce3a5c908 Merge pull request #448 from storytold/fix/issue-442
Fix #442: alike circular corners on rectangles that aren't square
2026-10-08 14:40:03 +07:00
BFlat 4254bf915e Merge pull request #441 from DvloperKing/es-errores
i18n: Spanish translations for error and status-bar messages
2026-10-08 14:39:46 +07:00
bflatasticandClaude Opus 5.5 44c7e64e1b Fix #442: alike circular corners on rectangles that aren't square
Live rectangles drew elliptical corners after an uneven scale in v0.4.0;
inconsistent on a rectangle that isn't square:

- doc: LiveShape::fold_scale moves an uneven scale left in `xf` (files
  saved before #291) into the size and radii; `transform` uses it, and
  `folded()`/`corner_style` give Live Corners document units.
- engine: object.setLiveShape folds that scale first, so setting a radius
  or kind (fields, dialog, widgets, MCP) gives circular corners on such
  shapes instead of keeping the ellipses.
- geom: max_corner_radius/fitted_corner_radius are the one limit every
  corner shares (half the shorter side).
- tools: corner widgets sit at the centres of the corners as drawn (a
  radius past the limit put them off the arc, further in along the long
  side), drag in document units on stretched shapes, and outline the
  edited corners in red at the limit, as the reference app does.
- svg: CSS export writes the drawn radii (CSS would draw a radius past the
  limit when its neighbours leave room).
- docs: mcp.md Live Corners, ROADMAP.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 14:34:37 +07:00
bflatasticandClaude Opus 5.5 7c7ce7f4fb i18n: Spanish messages say aplicación and match the UI's wording (review of #441)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 14:34:20 +07:00
Eliezer Hernandez f44155e098 i18n: Spanish translations for error and status-bar messages 2026-10-08 14:34:20 +07:00
BFlat 9533707893 Merge pull request #445 from storytold/fix/issue-443
Fix #443: installed fonts outside the font folders and fonts installed while the app runs reach the font menus
2026-10-08 14:34:12 +07:00
bflatasticandClaude Opus 5.5 64cbee2a96 Fix #443: installed fonts outside the font folders and fonts installed while the app runs reach the font menus
The scan read only the platform's font folders, once per session (or on
Character panel menu > Refresh Font List). Fonts Windows registers outside
its font folders (installed as shortcuts, or by programs into their own
folders) never listed, nor did fonts installed while the app was open.

- Windows: the font files registered under the local machine's and the
  user's Fonts registry keys outside the scanned folders are scanned too
  (windows-registry, the windows-rs project's safe registry API).
- Linux/BSD: the XDG data folders' fonts (XDG_DATA_HOME, XDG_DATA_DIRS:
  Flatpak, Snap, NixOS, Guix) and a Flatpak sandbox's host fonts
  (/run/host/fonts, local-fonts, user-fonts); macOS: /Network/Library/Fonts.
- The global database looks the platform's paths up again at each scan,
  and a scan's roots may be font files as well as folders.
- FontDb::installed_fonts_changed compares the folders the last scan read
  (their modification times, and the paths it started from); the app
  checks it when its window comes back to the front and rescans
  (text.rescanFonts) only when fonts were installed or removed meanwhile.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 14:03:53 +07:00
BFlat e2a4173337 Merge pull request #440 from storytold/fix/issue-439
Fix #439: Shape Builder erase mode deletes edges, shows what will go and follows Alt live
2026-10-08 13:42:06 +07:00
bflatasticandClaude Opus 5.5 17f66003cf Fix #439: Shape Builder erase mode deletes edges, shows what will go and follows Alt live
Alt already deleted regions and pieces of open lines, but erase mode had
no edges of closed shapes, no distinct pointer, highlighted regions in the
merge-mode grey, only noticed Alt on a mouse move, and an erase drag could
flip mode at release. Like the reference app's erase mode:

- pathops::shape_builder(shapes, edges) returns a BuilderArrangement; with
  `edges` it also cuts the outlines of closed (and filled open) paths
  wherever other paths meet them. pathops::cut_out removes such a piece
  from a path: a closed subpath opens there, an open one splits or
  shortens, a piece all the way round takes its subpath, and a filled open
  path's invisible closing edge never comes back as a visible segment.
  Specks where paths only touch cut nothing; a zero-length input is no
  longer the source of edges running through it. encloses_area is shared
  with the tool's closing of filled open paths.
- BuilderMap (with_edges) hit-tests edges like line pieces (nearest wins);
  an erase gesture that crosses an edge into a region deletes the region,
  not the edge (erased_edges).
- shapeBuilder.merge {erase}: deletes the edges touched within tolerance
  (from every shape along them), after the regions; returns `edges`.
  shapeBuilder.regions lists `edges` (bounds, source). One undo step.
- Shape Builder tool: Alt held switches to erase mode and back on release:
  red mesh/edge highlights of what will be deleted, a minus pointer
  (Cursor::ShapeBuilder / ShapeBuilderErase, a plus in merge mode); a drag
  keeps the mode it started in. The canvas re-hovers the tool when a
  modifier changes, so the highlight follows Alt without a mouse move.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 13:37:35 +07:00
BFlat 1b93336bdf Merge pull request #437 from bobtherobot/feat/floating-flyouts
Toolbar: tool flyouts tear off into floating toolbars
2026-10-08 13:04:27 +07:00
BFlat 9a4a632ea7 Merge pull request #436 from bobtherobot/fix/toolbar-flyouts
Toolbar: a right press or a corner press opens a tool group's flyout at once
2026-10-08 13:04:11 +07:00
bflatasticandClaude Opus 5.5 97906f2104 Toolbar: a click on the tear-off bar floats the group, window.floatTools, strips in workspaces (review of #437)
- A click on a flyout's tear-off bar, or the release of the long press
  that opened it over the bar, tears the flyout off too, as in
  Illustrator; dragging it still does.
- window.floatTools {tool, floating?} floats or puts back the group
  holding a tool, for the control channel and MCP's invoke_menu.
- Floating strips are part of user workspaces; the built-in ones float
  none, so Reset puts them back.
- Loaded preferences keep one strip per group, of known tools.
- No per-frame clone of the strips or copy of the active tool's id.
- docs/control-protocol.md, ROADMAP, Float Tool Group translations.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 13:01:40 +07:00
bflatasticandClaude Opus 5.5 b08188e5a5 Toolbar: only tool groups' buttons check for a flyout press, ROADMAP (review of #436)
A press on a single tool's button no longer schedules the repaint that
would open a flyout it doesn't have. The ROADMAP's UI list and Last
updated line name the right and corner press.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 13:01:25 +07:00
Michael GiesonandClaude Opus 5.5 dcc8a24f66 Toolbar: tool flyouts tear off into floating toolbars
A grab bar runs down the right side of a tool group's flyout. Dragging it
tears the flyout off: the group floats as a strip of its tools' buttons
(the active one lit, each tool's name and shortcut in its tool tip), with
the bar on its right. The same bar moves the strip, and the × at the top
of the bar puts the group back in the toolbar. While a group floats, the
presses that would open its flyout (right, long or corner press) raise
the strip and flash its border instead, so a group is never both a
flyout and a floating strip. Floating strips are kept with the UI
preferences and kept on screen.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-08 13:01:25 +07:00
Michael GiesonandClaude Opus 5.5 e80b3543d3 Toolbar: a right press or a corner press opens a tool group's flyout at once
A right press opens the flyout on the press instead of on the release,
including on the active tool's button, and the release leaves it open. A
primary press on the button's corner triangle opens it at once without
picking the tool; a plain click in the middle still picks it. The long
press keeps scheduling the frame where it becomes long.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-08 13:01:13 +07:00
BFlat a6fceb295e Merge pull request #435 from bobtherobot/feat/layers-panel
Layers: drag ghost, drops on the bottom-bar buttons, trash deletes again
2026-10-08 13:01:07 +07:00
bflatasticandClaude Opus 5.5 a32aed7e81 Layers: only the trash and New Layer take dropped rows (review of #435)
Illustrator documents two drop targets in the Layers panel's bottom bar:
dragging items to Create New Layer duplicates them, to the Delete icon
deletes them. Dropping rows on New Sublayer or Make/Release Clipping
Mask no longer creates a sublayer or clips the row's layer; those
buttons only act on a click, and the new test checks a drop on New
Sublayer changes nothing. The trash and New Layer share one drop loop,
and the drag ghost paints its colour bar and thumbnail with the row's
own helpers.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 12:58:21 +07:00
Michael GiesonandClaude Opus 5.5 a216c36779 Layers: drag ghost, drops on the bottom-bar buttons, trash deletes again
Dragging a row shows a dimmed copy of it (colour bar, thumbnail, name)
under the pointer. A row dropped on Delete, New Layer, New Sublayer or
Make/Release Clipping Mask runs that button on the row's layer, as a
click would: Delete removes the row itself and New Layer duplicates it,
as in Illustrator.

Rows dragged onto the trash weren't deleted. The trash took the drop as
a target-circle payload first, and egui's take discards a payload of
another type, so the rows reached the second check as nothing. It now
peeks at the type before taking. The trash is also outlined while rows
or a target circle are over it, like the other drop buttons.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-08 12:58:04 +07:00
Michael GiesonandClaude Opus 5.5 80f4de1a5e Layers: Layer Options' Color list shows a chip of each colour
Each preset in the Color dropdown has a chip of its colour before its
name; Custom has none, its name aligned with the others.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-08 12:58:04 +07:00
BFlat cae68a57a1 Merge pull request #438 from storytold/fix/issue-429
Fix #429: Type on a path brackets, flip and Type on a Path Options that keep the type in place
2026-10-08 12:57:55 +07:00
bflatasticandClaude Opus 5.5 1706e84829 Fix #429: Type on a path brackets, flip and Type on a Path Options that keep the type in place
Type on a path could only be repositioned by Type on a Path Options, whose menu item sent
`{start: 0}`, so OK threw the text to the start of its path; nothing showed or dragged its
brackets. Now, as in Illustrator:

- Type on a path flows between a start and an end bracket (`TextKind::OnPath { end }`, None:
  the end of the path or once round a closed one; `TextKind::path_span`). Flipping
  (`TextObject::flip_on_path`) reverses the path keeping a closed path's first anchor and swaps
  the brackets, so the type keeps its stretch of the path.
- Type on a Path Options gains Align to Path (ascender, descender, center, baseline) and
  Spacing (glyphs spaced as if set that far above the path: closed up round the outside of
  curves, opened up round the inside), laid out by the text engine.
- `type.pathOptions {start?, end?, flip?, effect?, alignToPath?, spacing?, ids?}` sets them in
  one undo step; with none of them it queries. The menu item opens the dialog with the selected
  type's Effect, Flip, Align to Path and Spacing (dropdowns for the choices) and leaves the
  brackets alone, so OK as opened changes nothing.
- The Selection and Direct Selection tools show selected type on a path's path and its start,
  centre and end brackets (`tools::pathtype`, with a bracket cursor): dragging the start or end
  bracket sets where the type runs, dragging the centre bracket slides it along the path and,
  across the path, flips it (Cmd/Ctrl held: it only slides). Each drag is one undo step.
- Arc-length measuring moved to `vectorcraft_geom::ArcPath` (layout, the tools and
  `text.createInPath` share it). SVG export outlines path type whose end bracket, alignment or
  spacing `<textPath>` can't express.
- docs/mcp.md documents the command and the drags; ROADMAP updated; dialog strings translated.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 12:50:25 +07:00
BFlat 696d9f619b Merge pull request #430 from bobtherobot/fix/appearance-opacity-popup
Appearance: the Opacity popup's blend list and slider work
2026-10-08 12:49:58 +07:00
BFlat 3966b0cce5 Merge pull request #426 from raytheengineer/stroke-weight-presets-per-unit
Stroke: per-unit weight presets so mm/cm/in dropdowns show clean numbers
2026-10-08 12:49:39 +07:00