Skip to content

Fix gradient chain metadata sync for exposed Fill nodes#4315

Draft
YohYamasaki wants to merge 5 commits into
GraphiteEditor:masterfrom
YohYamasaki:sync-gradient-chain-metadata-for-exposed-fill
Draft

Fix gradient chain metadata sync for exposed Fill nodes#4315
YohYamasaki wants to merge 5 commits into
GraphiteEditor:masterfrom
YohYamasaki:sync-gradient-chain-metadata-for-exposed-fill

Conversation

@YohYamasaki

Copy link
Copy Markdown
Contributor

Closes #4314

This fix inserts a Transform node only when the Gradient tool is selected. The first try was inserting a Transform node when wiring Gradient Value -> Fill if no transform attribute exists. This kept the tool and node state synchronized best, but was not intuitive UX wise because of the sudden node insertion.

Screen.Recording.2026-07-07.at.18.02.55.mov

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces changes to keep the rendered gradient and the Gradient tool state in sync. It adds a normalization step after input connections (NormalizeAfterInputConnection) to reset gradient metadata on a Fill node when a gradient value chain is connected, and inserts a Transform node for chain-backed gradients if one is missing. The review feedback points out an inconsistency in the graph traversal flow type, suggesting the use of FlowType::HorizontalFlow instead of FlowType::PrimaryFlow to align with other parts of the codebase.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 6 files

Confidence score: 3/5

  • editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs now emits GraphOperationMessage::NormalizeAfterInputConnection from NodeGraphMessageHandler, which conflicts with the documented layering invariant and risks further cross-layer coupling/regressions in message flow as this path evolves — move the normalization trigger into the graph-operation layer (or update architecture boundaries explicitly) before merging.
  • editor/src/messages/tool/tool_messages/gradient_tool.rs applies Transform insertion only in the fallback PointerDown path and may queue GradientTransformSet outside StartTransaction, so similar gradient interactions can behave inconsistently and leave changes outside expected undo/abort semantics — make all relevant PointerDown branches follow the same insertion path and wrap the transform mutation inside the transaction lifecycle.
  • editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs drops output_index when checking upstream metadata initialization, so multi-output nodes can resolve from the wrong port and initialize metadata from an unintended data flow — include the output port in upstream traversal/state lookup before merging.

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs Outdated
Comment thread editor/src/messages/tool/tool_messages/gradient_tool.rs Outdated
Comment thread editor/src/messages/tool/tool_messages/gradient_tool.rs Outdated
@YohYamasaki YohYamasaki marked this pull request as draft July 7, 2026 10:39
@YohYamasaki YohYamasaki force-pushed the sync-gradient-chain-metadata-for-exposed-fill branch from 2c7bcb3 to 6acf3b6 Compare July 8, 2026 03:21
@YohYamasaki

Copy link
Copy Markdown
Contributor Author

@cubic-dev-ai review

@cubic-dev-ai

cubic-dev-ai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review

@YohYamasaki I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 3 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@YohYamasaki YohYamasaki marked this pull request as ready for review July 8, 2026 03:39

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 3 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

Comment on lines +253 to +257
// Post wire creation process
let InputConnector::Node { node_id, input_index } = input_connector else { return };
// Fill node: When a Gradient Value chain is connected to a Fill node's paint input, reset the hidden gradient metadata.
// This prevents the rendered gradient and Gradient tool state from getting out of sync.
if network_interface.reference(&node_id, selection_network_path).as_ref() == Some(&DefinitionIdentifier::ProtoNode(graphene_std::vector::fill::IDENTIFIER))

@0HyperCube 0HyperCube Jul 11, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fill or gradient specific functionality should not be inside the generic NodeGraphMessage::CreateWire. This creates a spaghetti of dependencies. Please write code related to the gradient tool inside the gradient tool.

Thanks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, thanks for the comment. I'll find the alternative way.

@0HyperCube 0HyperCube Jul 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your understanding. Hopefully it is clear why I think having seemingly generic node graph changes silently mutate specific graphic nodes is undesirable for maintainability.

Looking at the fill node, it seems the current order of priority appears to be:

  • Attributes on the List<GradientStops>
  • Hidden inputs on the fill node
  • For transform only (if value is None) then the bounding box of the layer

The concept of having the hidden inputs to the fill node seems rather confusing. My preferred solution would be to remove these altogether. This would involve the editor tooling setting attributes on the List<GradientStops>. This simplifies the data model and reduces inconsistencies.

However thanks to @Keavon's incomplete refactor (5 months it has had 3 names) it seems that is impossible to set the attributes on a tagged value that get serialized.

An alternative solution the gradient tool read the hidden inputs where appropriate. The gradient tooling should be able to determine if any of the attributes are set (either by traversing the graph looking for known nodes or using the monitor node system). Therefore it can fall back to the fill node inputs. This removes inconsistencies with the tooling and results. However it may sometimes result in confusing behaviour (e.g. if the hidden transform input is set).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think the solution you mentioned is the way to go at this moment. Thanks for the detailed explanation.

However it may sometimes result in confusing behaviour (e.g. if the hidden transform input is set).

I think so too, and it was the reason why the hidden input reset was initially implemented in NodeGraphMessage::CreateWire. But it should be possible to defer this to the interaction point of the tool.

@YohYamasaki YohYamasaki marked this pull request as draft July 11, 2026 22:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gradient tool handles desync from exposed Fill gradient chains

2 participants