Add DocumentMode groundwork with MaskMode and Q toggle#4001
Add DocumentMode groundwork with MaskMode and Q toggle#4001krVatsal wants to merge 7 commits intoGraphiteEditor:masterfrom
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a new DocumentMode enum, including a MaskMode variant, and integrates it into the DocumentMessageHandler to allow toggling and setting the document mode. The review feedback suggests ensuring UI consistency by triggering PortfolioMessage::UpdateDocumentWidgets when the mode changes and recommends uncommenting and updating the fmt::Display implementation for DocumentMode to avoid leaving dead code.
ca57043 to
268ec73
Compare
|
I wanted to continue with the work on part of my proposed changes but that needs these changes, should i continue adding further commits to this PR only? It would be great if you review this and then i can follow up with further changes for marquee selection. @Keavon |
|
These changes comprise a relatively small change set, so you can and should continue adding functionality since this is so far just the user's entry point to a not-yet-built feature. |
There was a problem hiding this comment.
3 issues found across 4 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="editor/src/messages/portfolio/document/document_message_handler.rs">
<violation number="1" location="editor/src/messages/portfolio/document/document_message_handler.rs:1161">
P1: Mask group creation can self-parent because parent resolution happens after entering MaskMode and storing the same mask group ID used for the new layer.</violation>
<violation number="2" location="editor/src/messages/portfolio/document/document_message_handler.rs:1192">
P1: Applying mask on `ExitMaskMode` mutates the graph without transaction boundaries, unlike the discard branch, causing inconsistent undo/history behavior.</violation>
<violation number="3" location="editor/src/messages/portfolio/document/document_message_handler.rs:1194">
P1: Mask apply path discards authored mask content by using a placeholder 1x1 white image and then deleting the mask group.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| } else { | ||
| // Rasterize the mask group and apply it to target layers | ||
| if let Some(mask_group_id) = self.mask_group_id { | ||
| responses.add(GraphOperationMessage::ApplyMaskStencil { |
There was a problem hiding this comment.
P1: Applying mask on ExitMaskMode mutates the graph without transaction boundaries, unlike the discard branch, causing inconsistent undo/history behavior.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At editor/src/messages/portfolio/document/document_message_handler.rs, line 1192:
<comment>Applying mask on `ExitMaskMode` mutates the graph without transaction boundaries, unlike the discard branch, causing inconsistent undo/history behavior.</comment>
<file context>
@@ -1133,16 +1142,69 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
+ } else {
+ // Rasterize the mask group and apply it to target layers
+ if let Some(mask_group_id) = self.mask_group_id {
+ responses.add(GraphOperationMessage::ApplyMaskStencil {
+ layers: self.mask_target_layers.clone(),
+ mask_image: graphene_std::raster::Image::new(1, 1, graphene_std::Color::WHITE),
</file context>
| if let Some(mask_group_id) = self.mask_group_id { | ||
| responses.add(GraphOperationMessage::ApplyMaskStencil { | ||
| layers: self.mask_target_layers.clone(), | ||
| mask_image: graphene_std::raster::Image::new(1, 1, graphene_std::Color::WHITE), |
There was a problem hiding this comment.
P1: Mask apply path discards authored mask content by using a placeholder 1x1 white image and then deleting the mask group.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At editor/src/messages/portfolio/document/document_message_handler.rs, line 1194:
<comment>Mask apply path discards authored mask content by using a placeholder 1x1 white image and then deleting the mask group.</comment>
<file context>
@@ -1133,16 +1142,69 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
+ if let Some(mask_group_id) = self.mask_group_id {
+ responses.add(GraphOperationMessage::ApplyMaskStencil {
+ layers: self.mask_target_layers.clone(),
+ mask_image: graphene_std::raster::Image::new(1, 1, graphene_std::Color::WHITE),
+ });
+ responses.add(NodeGraphMessage::DeleteNodes {
</file context>
| responses.add(DocumentMessage::AddTransaction); | ||
|
|
||
| // Create the mask group layer as an empty custom layer container | ||
| graph_modification_utils::new_custom(mask_group_id, Vec::new(), self.new_layer_parent(true), responses); |
There was a problem hiding this comment.
P1: Mask group creation can self-parent because parent resolution happens after entering MaskMode and storing the same mask group ID used for the new layer.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At editor/src/messages/portfolio/document/document_message_handler.rs, line 1161:
<comment>Mask group creation can self-parent because parent resolution happens after entering MaskMode and storing the same mask group ID used for the new layer.</comment>
<file context>
@@ -1133,16 +1142,69 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
+ responses.add(DocumentMessage::AddTransaction);
+
+ // Create the mask group layer as an empty custom layer container
+ graph_modification_utils::new_custom(mask_group_id, Vec::new(), self.new_layer_parent(true), responses);
+
+ // Set the mask group opacity to 50% so the user can see artwork beneath
</file context>
This PR implements the early groundwork for Document Mode as planned for community bonding / week 1 in Marquee Selection Masking.
It introduces MaskMode and wires a keyboard toggle, while intentionally avoiding rendering or visual feature work.
What this PR changes?
Scope and intent