Commit Graph

1708 Commits

Author SHA1 Message Date
Keavon Chambers
6e32e97ba1 Add a gradient interpolation attribute with Stepped, Linear (existing), and Smooth modes (#4418)
* Delete dead code function

* Add a Gradient Interpolation axis with Stepped, Linear, and Smooth paths through the stops

* Keep the gradient interpolation attached when dragging stops in the picker

* Give the gradient popover's dropdowns the same tooltips as their row labels

* Order the gradient popover with Intrp. above Space

* Hold gradient stops in place when the cyclic flag is toggled

* Fix wrong Smooth gradient colors around stops sitting on the ramp boundaries

* Consolidate gradient settings plumbing and fix bugs

* Bundle whole-ramp gradient settings into GradientSettings across the editor plumbing

* Name the Smooth gradient interpolation's spline type in its tooltip

* Linearize the gamma hex stop colors recovered from imported Graphite SVGs

* Code review

* Aim the Smooth bake's seam subdivision at the copied boundary color

* Add GradientEvaluator to build gradient sampling state once per loop instead of per sample

* Correct the gradient evaluator's documented setup cost to O(n log n)
2026-09-14 12:58:43 +02:00
Keavon Chambers
244a7e0f78 Add a "Cyclic" gradient option that closes the ramp into a seamless loop (#4416)
* Add a Cyclic gradient attribute that wraps the stop list through the 1|0 boundary back to the first stop

* Show the wrap segment's midpoint diamond in the color picker spectrum strip when cyclic

* Keep the wrap midpoint diamond tracking the pointer by a wrapped strip width when dragged past the ends

* Give the Gradient tool's viewport overlay the same cyclic wrap midpoint diamond and drag behavior

* Correct the docs claiming the final stop's midpoint is always ignored now that cyclic uses it

* Move the gradient cyclic toggle onto the Ends row as a Link icon checkbox

* Update labels

* Register GradientHueDirection with the Data panel so its attribute column renders

* Reword wrap segment to wrapped interval and stray segment usages to interval

* Clean up comments

* Fix the color picker write-back losing default position elision and the blend path guessing the cyclic flag
2026-09-14 12:58:41 +02:00
Keavon Chambers
a35143586a Add the "Perceptual" and "Classic" families of gradient spaces with OkLab as the new default (#4415)
* Add an OkLab gradient interpolation space and make it the new default

* Fix the Properties panel fill row resetting the gradient interpolation space to the default

* Add OkLch, Lab, LCh, and HSL gradient interpolation spaces

* Add a hue direction attribute and picker choice for polar gradient interpolation spaces

* Add an HSV gradient interpolation space

* Rename the sRGB Linear and sRGB Gamma gradient spaces to RGB Linear and RGB Gamma

* Divide the gradient interpolation dropdown between absolute and relative color spaces

* Rename the OkLch gradient interpolation space to OkLCh for channel-notation capitalization

* Shorten the color picker popover's hue direction row label to Arc

* Call the Gradient Interpolation node's parameter Space and extend the picker tooltip title to match

* Rename the gradient interpolation attribute and type family to gradient space

* Rename the gradient tool's gradient space transform to gradient to viewport transform

* Add serde aliases and a node replacement covering the gradient space renames

* Give the gradient space choices artist-facing labels and reorder the dropdown sections

* Add a Gradient Hue Direction node and its attribute read node

* Say interpolate instead of blend for gradient stop color traversal in docs and tooltips

* Label the polar perceptual gradient spaces as Perceptual Hue and group the dropdown sections by geometry

* Add a migration alias covering the gradient space attribute reader rename

* Carry the gradient hue direction attribute through boolean operations

* Register GradientHueDirection wire types in the node registry
2026-09-14 12:58:40 +02:00
Keavon Chambers
11dfc27645 Make gradient evaluation follow the ramp's interpolation space attribute (#4414) 2026-09-14 12:58:39 +02:00
Keavon Chambers
3678826a48 Give whole-expanse gradient layers a transform cage based on the gradient line (#4413) 2026-09-14 12:58:37 +02:00
Keavon Chambers
f8975b7d94 Add a gradient interpolation space attribute with sRGB Gamma (existing) and sRGB Linear (new) (#4412)
* Build dropdown menu entries from choice type metadata

* Add a gradient interpolation color space attribute, blending stops in linear light by default

* Add a Space interpolation dropdown to the color picker popover

* Stamp legacy gradient ramps with their implicit gamma interpolation during deserialization

* Resolve color-interpolation from SVG style blocks and fix cascade order among repeated declarations
2026-09-14 12:58:36 +02:00
Keavon Chambers
ea6f45ddc0 Fix node shaking causing an offset from the pointer for the rest of the drag (#4411) 2026-09-14 12:58:34 +02:00
Keavon Chambers
c71f78edb5 Add a Clear gradient spread that cuts off to transparency beyond the ends (#4410) 2026-09-14 12:58:32 +02:00
Keavon Chambers
344e24f0c2 Bind the Gradient tool's spread to the gradient value's ramp instead of a Gradient Spread node (#4409) 2026-09-14 12:58:30 +02:00
Keavon Chambers
ba5b25112b Build radio widget entries from choice type metadata so variants display their icons (#4408)
* Build radio widget entries from choice type metadata so variants display their icons

* Route the node properties enum radio through the shared choice type entry builder
2026-09-14 12:58:29 +02:00
Keavon Chambers
b635e6fa02 Let the Fill and Gradient tools paint blank layers with whole-expanse colors and gradients (#4407)
* Let the Gradient and Fill tools paint blank layers with whole-expanse gradients and colors

* Make it work on layers with un-fed Transform nodes

* Show the Fill tool's hover pattern over the whole expanse of layers painted by a color chain

* Let the Fill and Gradient tools replace one another's whole-expanse paint on a selected layer

* Keep a shared paint node alive when a tool takes over a layer, and share the paint value lookup

* Stop a chain node from being shifted twice when a node is inserted in front of it
2026-09-14 12:58:27 +02:00
Keavon Chambers
4da366acf1 Rename gradient type to gradient form (#4405)
* Rename gradient type to gradient form

* Update the demo art for the gradient form rename

* Say form not type in the Gradient Form node's doc comment
2026-09-14 12:58:26 +02:00
Keavon Chambers
167da6a210 Rename spread method to gradient spread so it matches the other gradient attribute names (#4404)
* Rename spread method to gradient spread so it matches the other gradient attribute names

* Keep the legacy gradient struct's spread method field name matching its on-disk key
2026-09-14 12:58:24 +02:00
Keavon Chambers
c5cb466e28 Move the gradient spread method into GradientRamp and the color picker popover (#4402)
* Add a spread method field to GradientRamp, carried at runtime as the gradient item's attribute

* Retire the Fill node's spread method input, folding its value into the gradient ramps on document upgrade

* Add an Ends spread method radio to the color picker popover, replacing the Gradient tool's control bar radio

* Update the demo art
2026-09-14 12:58:22 +02:00
Keavon Chambers
360321e0ce Wrap serialized gradient stops in a new GradientRamp struct and unify FillChoice (#4400)
* Introduce the GradientRamp exchange struct as the serialized TaggedValue::Gradient payload

* Unify FillChoice and FillChoiceUI into one enum generic over color format, carrying GradientRamp stops

* Rename the TaggedValue::Gradient variant to GradientRamp to match its payload

* Move the Color variant into the tagged_value macro list since its stored and wire forms match
2026-09-14 12:58:19 +02:00
Keavon Chambers
4d8729d87c Add a drill-in button beside Data panel gradient preview widgets (#4398) 2026-09-14 12:58:18 +02:00
Keavon Chambers
86d4106592 Rework Gradient into a newtype of List<Color> with optional position and midpoint attributes (#4397)
* Rework Gradient into a newtype of List<Color> with optional position and midpoint attributes

* Fix Vello stopless-gradient fallback coverage, empty legacy gradient tables, the node docs gradient swatch, NaN position elision, and wired setter input overwrites
2026-09-14 12:58:16 +02:00
Keavon Chambers
b78e4b107e Remove custom (de)serializers from the DashPattern and BoxCorners TaggedValue variants (#4394)
Replace the DashPattern and BoxCorners custom serde impls with storage-shaped Vec<f64> TaggedValue payloads
2026-09-14 12:58:15 +02:00
Keavon Chambers
69148d1b36 Replace raw node input indices with compile-time parameter symbols (#4387)
* Remove the dead InputAccessor traits and the uncallable test helper built on them

* Replace raw node input indices with macro-generated parameter symbols across the editor

* Audit dynamic input index usage, converting to parameter symbols and named input position constants

* Abstract the remaining input index plumbing behind ParameterRef APIs and accessors

* Build SetInputValue messages as struct literals to keep message enums impl-free

* Delete the typed parameter markers in favor of explicit-output test introspection

* Wire the interpolation control path input per chain node type

* Return no input when a parameter symbol is read against the wrong node's parameter view
2026-09-14 12:58:14 +02:00
urisinger
b42b00febe Move the math expression parser from Pest to Chumsky and add more features (#2685)
Rewrite the math-parser library using a chumsky-based lexer and parser, adding functions, comparisons, logic, and conditionals
2026-09-14 12:57:20 +02:00
Keavon Chambers
c77359bedf Add a Connect Cells option to the 'Grid' node (#4374)
Add a Connect Cells option to the Grid node
2026-09-14 12:57:19 +02:00
Keavon Chambers
cd03202060 Deduplicate the network interface query helpers and collapse TransientMetadata into TransientCache (#4382)
* Route the remaining view queries through the logging query helper

* Name the cache readers by their loading contract and stop cloning the owned nodes per collision check

* Deduplicate the port center, output count, and upstream connector helpers and drop dead accessors

* Collapse the TransientMetadata enum into the Option inside TransientCache

* Extract the shared history snapshot install from undo and redo
2026-09-14 12:57:18 +02:00
Keavon Chambers
b6accaf4bd Fix wrong-input disconnects, ghost wire caches, and partial import removal in the network interface (#4381)
* Remove commented-out code and fix stale names and doc comments

* Validate that the pinned node order only references existing nodes

* Abort remove_import before any mutation when the import's wires cannot be resolved

* Purge the deleted nodes' cached wire paths in delete_nodes

* Disconnect a deleted node's inputs by position so hidden inputs cannot mask a later exposed wire

* Gather the delete_nodes layer sweep only when deleting children needs it
2026-09-14 12:57:17 +02:00
Keavon Chambers
e666838580 Move session state out of the network interface caches and replace the selection hijacks with explicit parameters (#4379)
* Move drag offsets out of the stack dependents cache into dedicated drag session state

* Replace the move_layer_to_stack selection hijack with a seeded stack dependents load

* Move text measurement into a neutral utility module out of the overlays layer

* Deduplicate the document bounds queries and name the artboard clip input index

* Replace the remove_references_from_network selection hijack with an explicit shift set

* Extract shared import and export wire disconnection used by the expose handlers

* Extract the shared epilogue of the import and export removal operations

* Move the post node lookup into the network interface to fix the layering inversion

* Clear drag offsets when the stack dependents cache unloads so programmatic shifts cannot replay them

* Use the thread-local text context for text measurement instead of a process-global mutex

* Resolve the post node lookup within the network being edited instead of the document root
2026-09-14 12:57:16 +02:00
Keavon Chambers
09f8864450 Make the network interface's queries take &self instead of &mut self (#4378)
* Back the outward wires cache with an interior-mutability cell readable through &self

* Convert the remaining network-level caches to interior-mutability TransientCache cells

* Move the owned nodes cache out of persistent layer metadata into a transient cell

* Flatten the transient node type enum into a layer width cell with &self loading

* Back the per-node click targets cache with a TransientCache cell

* Unify the per-input and per-export wire caches into one connector-keyed map

* Flip the click target, position, and stack dependent load chains to &self

* Flip the bounding box, import export position, and port load chains to &self

* Flip the wire geometry and resolved type query families to &self

* Flip the hit testing and frontend click target surface to &self

* Flip the frontend assembly, clipboard copy, and chain validation queries to &self

* Load stack dependents before filtering layer-owned nodes out of a selected-nodes shift
2026-09-14 12:57:16 +02:00
Keavon Chambers
d03adcae83 Replace NodeTemplate's parallel node and metadata trees with a single flat recursive shape (#4377)
* Unify NodeTemplate into a single flat recursive shape with from_parts/into_parts as the storage split points

* Unify the three sole-dependent traversals onto one is_sole_dependent kernel

* Scan network exports for resource values when collecting used resources
2026-09-14 12:57:15 +02:00
Keavon Chambers
72b3a883a7 Introduce the NetworkView read cursor with typed errors and convert the network queries onto it (#4376)
* Introduce a NetworkView cursor with typed errors and convert the primitive queries to it

* Convert the composite name, selection, and eligibility queries onto NetworkView
2026-09-14 12:57:14 +02:00
Keavon Chambers
81398ca0cb Make double-clicking a text layer begin editing in shallow select mode, not just deep select mode (#4373) 2026-09-14 12:57:14 +02:00
Keavon Chambers
fded44c293 Break apart the enormous network_interface.rs into submodules (#4371)
Split the network interface monolith into submodules with no behavior change
2026-09-14 12:57:13 +02:00
Keavon Chambers
79944bd6d0 Add additional tests to the network interface (#4370)
* Add a network interface invariant validator and characterization tests as a refactor safety net

* Characterize stack, chain, layer move, signature edit, and preview behaviors in tests

* Sweep network interface invariants after every message in editor tests
2026-09-14 12:57:12 +02:00
Keavon Chambers
ff18b33362 Fix assorted node graph correctness bugs and replace network interface panics with logged errors (#4364)
* Deselect deleted layer children by pruning the expanded deletion set from the selection

* Rebuild the document structure on redo to match undo

* Check for cycles in set_input before applying layout side effects rather than reverting after

* Correct the swapped old/new exposure binding names in set_input

* Reload the document structure when an import or export is appended into the first two slots

* Treat toggling preview on a disconnected export as a preview with nothing to restore

* Replace panics on malformed networks with logged errors in the network interface

* Make is_artboard an identity check independent of scene connectivity

* Stop serializing the selection undo and redo history into saved documents

* Run the set_input cycle check before the node-to-node disconnect so a rejected wire swap leaves the graph unchanged
2026-09-14 12:57:12 +02:00
Keavon Chambers
f4609e0e3b Improve number fields/labels in the UI to filter out floating point noise and truncate at correct precision (#4363)
* Improve the displayed precision of float number labels

* Show actual tiny values in high-precision number fields
2026-09-14 12:57:11 +02:00
Keavon Chambers
85dd39c35b New nodes: 'Sign', 'Distance', 'Cross Product', and 'Lerp' (#4361) 2026-09-14 12:57:09 +02:00
Keavon Chambers
83d24251d7 Rename the nodes 'Length' -> 'Magnitude', 'Flatten Path' -> 'Combine Paths', 'Vec2 Value' -> 'Combine Vec2', and add a new 'Vec2 Value' node (#4349)
* Rename the node 'Length' -> 'Magnitude'

* Rename the node 'Flatten Path' -> 'Combine Paths'

* Replace the node 'Vec2 Value' with 'Combine Vec2' and add a new 'Vec2 Value' that's actually a vec2

* Update demo artwork
2026-09-14 12:57:07 +02:00
Keavon Chambers
cba642a7a1 New nodes: Sum, Average, Minimum, Maximum, Any, All (#4344)
Co-authored-by: Dennis Kobert <dennis@kobert.dev>
2026-09-14 12:57:05 +02:00
Keavon Chambers
67690d22d4 Convert the node catalog to rank-polymorphic kernels, materialize stored values as ranked wires, and display wire rank in the graph
Co-authored-by:    Dennis Kobert <dennis@kobert.dev>
2026-09-14 12:57:05 +02:00
Keavon Chambers
5bc41c4c58 Reshape the node catalog: rename the list access nodes, split Text to Vector, reinstate Upload Texture as a proto node, and delete the vestigial debug nodes 2026-09-14 12:57:04 +02:00
Keavon Chambers
7ddab438d1 Split Fill's optional transform into a has-transform toggle and add the DashPattern and BoxCorners value types 2026-09-14 12:57:03 +02:00
Keavon Chambers
6acc0638e4 Add Graphic::None and store paint choices as plain color, gradient, and no-paint values 2026-09-14 12:57:02 +02:00
Keavon Chambers
fd7f67b3e9 Rename GradientStops to Gradient and the legacy Gradient/Fill structs to LegacyGradient/LegacyFill 2026-09-14 12:57:01 +02:00
Dennis Kobert
1a20718a3b Box the largest message and update payloads 2026-09-14 12:53:17 +02:00
Dennis Kobert
c0a793784b Sort key mappings and node positions by key 2026-09-14 12:53:16 +02:00
Dennis Kobert
8281d082f4 Drop redundant conversions, assertions and struct updates 2026-09-14 12:53:15 +02:00
Dennis Kobert
52301d68aa Collapse nested conditionals into let-chains and match guards 2026-09-14 12:53:12 +02:00
Dennis Kobert
f27d90d152 Fold attribute names through monitors and skip coercing name inputs 2026-09-14 12:53:11 +02:00
Dennis Kobert
9b92edc0e9 Write an attribute under a name the graph supplies
`Named<X>` in parameter position declares where a placeholder's name is
wired, and the macro gives that input constant text; `Attr<Named<X, V>>`
in the return writes under it. The kernel is handed the bare placeholder,
since the name is spent resolving the layout and a folded offset is all
the write needs, so the hot path matches a marker node's exactly.

A name-generic write names its value type through the wired generic,
which only an implementations row resolves, so those nodes emit their
layout meta per row rather than sharing one across rows.

`write_attribute` is the catalog's set half, restoring the identifier
master's documents carry with its input positions. Its name input is a
constant, so those documents resolve without migration, and the reset
marker that stood in for the missing node retires with it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-09 09:26:17 +00:00
Dennis Kobert
98cabee4c6 Rebuild stale rasterize subgraphs at document migration 2026-09-08 12:53:02 +00:00
Dennis Kobert
313c591f70 State from_resident's borrow-window contract at its call sites 2026-09-07 16:11:32 +00:00
Dennis Kobert
9f0e0ebc96 Clear the remaining clippy warnings on the diff surface 2026-09-06 16:25:17 +00:00
Dennis Kobert
a911bcc165 Justify the three clippy lints that must stand 2026-09-06 16:24:53 +00:00