Commit Graph
15 Commits
Author SHA1 Message Date
aiongg b95a04dc43 Merge #1304
# Conflicts:
#	docs/prototyping-parity.md
2026-10-25 02:21:29 +00:00
dotCooCoo ae57bf84d0 M5: a notice before a prototype's Open link leaves for a website
The player opened a prototype's Open link at once, also from an After
delay trigger with no click. The help center's Prototype actions page
says that the viewer is told they are leaving before an external
website opens, with a checkbox that skips this page on the current
device.

An Open link to an http or https address now shows a notice with the
link, Open link, Cancel and "Don't show this again". Open link opens
it; Cancel, the close button or Escape drops it. While the notice
shows, the prototype takes no keys, and the presenter's C, Shift+C and
F keys do nothing. When Open link is pressed with the box ticked, the
desktop app saves the choice with its preferences; the web build keeps
it until the page reloads. proto.linkNotice {show} turns the notice on
or off. A mail link opens at once, as before, also while the notice
shows. A second link to a website that fires while the notice shows is
dropped.
2026-10-24 14:10:41 -07:00
dotCooCoo 954f9036da Docs: parity rows for mouse-trigger delays, outline options and missing fonts
Three parity rows still listed work that has landed on main. The
prototyping Triggers row listed delays on mouse enter, leave, down and
up as missing; they landed on 2026-10-13. Canvas & navigation's
remaining work in target-app-parity listed outline mode's Include
hidden layers and Include object bounds, which View > Outlines has.
The file-format Fonts row said missing fonts give warnings only; the
desktop app lists them in the Missing fonts window, and replacing them
is still missing.

Each file gets its status line and a revision-history row. The
percentages and hours are unchanged.
2026-10-24 09:19:45 -07:00
bflatastic 9f60f5470d Batch r2-1 review: status lines and rows in ROADMAP, prototyping and UI parity 2026-10-24 10:31:31 +07:00
bflatastic ba8b608673 Merge #660: M5: one presentation tab per page of a file (@JimKnoxx)
# Conflicts:
#	docs/prototyping-parity.md
2026-10-24 09:23:43 +07:00
bflatastic ac5783d0cd Merge #1135: M5: prototype actions lay out what they change like the canvas does (@MortenHusted)
# Conflicts:
#	docs/prototyping-parity.md
2026-10-24 09:13:08 +07:00
ArminandClaude Opus 5.5 95db91def9 M5: a top-level frame taller than the device scrolls without an overflow setting
On a device, a presented frame bigger than the screen now scrolls through
its whole size whatever its overflow, as Figma documents for top-level
frames. Before, "No scrolling" frames only clipped, so the landing page
template's long Phone frame couldn't be scrolled in Present. Content past
a frame's own edges still scrolls only on the axes its overflow allows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 00:04:28 +02:00
MortenHusted ad9116ff5c M5: the prototyping parity status line and history name the layout fix 2026-10-22 17:01:21 +02:00
MortenHusted 3d5f3e7946 M5: prototype actions lay out what they change like the canvas does
Change to rebuilt the instance from the new variant, and set variable
and set variable mode re-applied bindings, but the player never laid the
result out: no text sizing, no auto layout. A hugging button with a
longer label than its main showed the other variant at the main's width,
its label clipped, and a text bound to a variable kept its old size.

These actions now run the engine's normalize on the player's document
afterwards, the pass that follows every edit on the canvas: text resizes
to what it shows, instances follow and auto layout reflows.
2026-10-22 16:41:30 +02:00
JimKnoxxandClaude Opus 5.5 8d5a29dfda M5: one presentation tab per page of a file
Main plays a presentation in a single "Present" tab. Now each page of a
file gets its own tab, named "file - page", and the name follows
renames. Play on a page that has a tab shows that tab as it was; from
another start frame it starts again. A tab keeps its own copy of the
prototype: it plays on after its file closes, and a saved file opened
again gets its tabs back. A tab whose file is closed or not in front
never reads or changes the file in front (device, responsive,
comments). Escape or the tab's X closes that tab and goes back to its
file, or Home.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:15:13 +02:00
BFlat c6d6433473 Docs: parity rows for the 2026-10-17 landings (#756)
Brings the progress docs up to date with what landed on 2026-10-17: community batches #727, #728, #733, #735, #736 and #753, plus #729, #745, #746 and #751. Docs only.
2026-10-17 21:56:26 +07:00
bflatastic 5548284c65 M5: prototyping: delays on mouse triggers, manual overlay offsets 2026-10-13 13:36:54 +07:00
bflatastic 119b8c7441 M5: prototyping tail: gamepad triggers, widgets in prototypes, mode lookups
The part of gap 15 that doesn't need video, from the public documentation of prototype triggers, plugins/widgets and prototype expressions.

- **Controller buttons on key/gamepad triggers.** A key trigger's key can be a controller button: `Gamepad A` ... `Gamepad Home`, the standard gamepad layout's 17 buttons (face buttons by position, shoulders, triggers, View/Menu, stick presses, d-pad, Home). The engine keeps its input-agnostic model (a key trigger with a key name; `figcraft_doc::proto::GAMEPAD_BUTTONS`, `gamepad_button`, `is_gamepad_button`, `uses_gamepad`). The interaction editor gets a Controller menu beside the key field; the trigger list shows the button's own name.
- **Reading controllers.** A new `Services::gamepad_held()` (bitmask of held buttons; default none). The player polls it only while the presented prototype has a controller trigger and the window has the focus (about 30 times a second), plays each press once (held buttons don't repeat), and fires the first matching key/gamepad trigger on the screen like a key.
  - Desktop, Windows: Windows.Gaming.Input (Xbox-compatible controllers) through the `windows` crate the app already depends on (one more feature flag, `Gaming_Input`; no new crate).
  - Browser: the Gamepad API through `web-sys` (features `Gamepad`, `GamepadButton`, `GamepadMappingType`; standard-mapped controllers only).
  - macOS, Linux, FreeBSD: no controllers yet (documented gap).
  - Control channel: `ui.input {events: [{gamepad: "A" | "Gamepad A" | 0}]}` presses a button in the prototype playing (presenter, else preview pane); an error when nothing plays.
- **REST import** maps controller triggers (`device` other than `KEYBOARD`) to the button at the code's standard-layout index instead of skipping them; two buttons at once or an unknown code is skipped with a warning (`.fig` goes through the same path).
- **Widgets react to clicks in a presented prototype.** A click on a widget's clickable part in the presenter or the preview pane (when no interaction on the layer takes it) calls the plugin back through the canvas's own callback with the same sandbox limits, on the player's copy of the file (`widgets::click_on`, a scratch session holding the copy and the installed plugins): the widget changes in the prototype only, the file and its undo history stay untouched, restarting starts the widget over. Failures (plugin missing or failing) toast; toasts now also show over the full-window presenter.
- **Variable mode lookups.** Lookups (`accent[Dark]`, `mode(Theme)`), set-variable-mode affecting later expressions in the same interaction, and every operator the documentation lists already held; they are now behaviour cases. New `proto.evaluate {expression | expr, id?}` (MCP and agents) computes an expression where a layer's interaction would run, without changing anything. No other cheap expression gap found: every documented operator (numbers, text join, booleans, comparisons, negation, mode lookup) already existed.
- Docs: prototyping-parity (new rule rows, features, revision), target-app-parity area 13 and totals, ROADMAP, gaps.md gap 15, roadmap.md M5, mcp.md, plugins.md, control-protocol.md.

Dependencies: none added. Windows uses the existing `windows` 0.62 dependency with the `Gaming_Input` feature; the browser uses the existing `web-sys` with three more features. The usual Rust controller library (gilrs) was not taken: its Linux backend links the system's libudev (a C library, needing headers on CI and the FreeBSD job), which breaks the pure-Rust rule.
2026-10-12 05:28:53 +07:00
bflatastic b65cc2e4fe M5: prototyping behaviour suite and fixes
**A prototyping behaviour suite written from the public documentation, and fixes for every divergence it found.** Each documented rule on triggers, actions, overlays, animations, easing, scrolling and interactive components is a case with what the rule implies and a one-line derivation; where the documentation is silent the case says so and pins today's behaviour. The model rules are table-driven tests in the engine; the player's are driven through egui headless (real pointer, key and timer input into the presenter) or on the player directly.

**Fixes (the suite failed on these before them)**
- **On drag follows its animation**: with a move, push or slide animation, only a drag that way starts it (a drag another way can scroll instead), and the animation follows the pointer while the button stays down, then plays on from there when it lets go (it played by time, and any drag direction fired it).
- **Key combinations**: a key trigger can be a combination (`Shift+K`, `Ctrl+Alt+Delete`, other spellings of the modifiers accepted); the modifiers held must match, so `K` no longer fires for Shift+K. The interaction editor's recorder records the modifiers held, and REST files' modifier key codes import as the combination (they imported as the key alone, with a warning).
- **Overlay timers**: an overlay's after-delay timer starts when the overlay opens, and again each time it opens (it was timed from when the screen under it arrived, so a toast opened late closed at once, and it fired only the first time).
- **Interactive components**: every instance plays the interactions on the variant it shows; an interaction on the instance with the same trigger wins. Before, instances played only interactions copied onto them when placed: an instance placed before its main got interactions did nothing, and one placed after kept the first variant's interactions after changing (a toggle went on but never off). New instances no longer copy them, and copies in older files give way to the variant shown (`proto_run::play_interactions`, on the player's copy).
- **Change to on nested instances** changes the instance whose variant set holds the destination (`proto_run::change_to_target`), not the innermost instance (an icon inside a button).
- **Springs**: the presets are physical springs (mass 1; stiffness / damping gentle 100/15, quick 300/20, bouncy 600/15, slow 80/20; they were ad-hoc curves), and every spring plays until it settles instead of being squeezed into the duration field's time; the settling time accounts for over-damped springs. The interaction editor shows the spring's duration in place of the duration field, with a tooltip.
- **Smart animate overshoot**: matched layers follow spring and back easings past their end and back (they snapped to the end once the curve passed 1).
- **Fixed layers on top**: fixed layers draw and take clicks above the content scrolling under them, wherever they are in the layer list (the file's order doesn't change).

**Missing documented setting, added**
- **Scroll to offset**: `{type: "scrollTo", dest, offset: [x, y]}` stops the layer that far from the top-left of the innermost frame scrolling it (room for a fixed header); X / Y fields in the interaction editor; files carry it only when set.
- Already there and now covered by the suite: click / mouse down / mouse up / while pressing / while hovering / mouse enter / mouse leave / after delay, nested hotspot priority and click-through, navigate (closing overlays), back with the reversed animation, restart, overlay stacking / swap / close / close on a click outside, change to with smart animate, reversed directional transitions, easing curves.

New strings go through `tr(...)` with `en.toml` / `es.toml` entries. No new command ids. The player still draws nothing while idle: the drag-follow only runs during an animation, and fixed layers and instance interactions are worked out once per layout, not per frame.
2026-10-12 00:57:43 +07:00
Brandon ThomasandClaude Opus 5.5 97159514b4 Progress docs: target-app parity, gaps, alpha gate, readiness by audience (#100)
Progress docs per craftrules standards/progress-docs.md: target-app parity, gaps, roadmap with alpha gate, readiness by audience (full / mainstream / essentials) with Opus 5.5 hours, and auto layout, components, prototyping, dev mode, collaboration, format, hardware, UI and localization parity docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 14:29:24 -04:00