diff --git a/editor/src/messages/tool/tool_messages/brush_tool.rs b/editor/src/messages/tool/tool_messages/brush_tool.rs index dd32c50fb9..c2c19d71d7 100644 --- a/editor/src/messages/tool/tool_messages/brush_tool.rs +++ b/editor/src/messages/tool/tool_messages/brush_tool.rs @@ -9,8 +9,9 @@ use crate::messages::tool::common_functionality::color_selector::{ToolColorOptio use graph_craft::document::value::TaggedValue; use graph_craft::document::{NodeId, NodeInput}; use graphene_std::Color; +use graphene_std::NodeParameter; use graphene_std::brush::basic_brush::basic_brush as active_brush; -use graphene_std::brush::{Channel, Stroke}; +use graphene_std::brush::{Channel, Stroke, brush_strokes}; use graphene_std::color::SRGBA8; use graphene_std::vector::style::FillChoice; @@ -233,16 +234,16 @@ impl BrushTool { return; }; let value = |index: usize| node.inputs.get(index).and_then(|input| input.as_value()); - if let Some(TaggedValue::F64(diameter)) = value(STROKES_DIAMETER_INPUT) { + if let Some(TaggedValue::F64(diameter)) = value(brush_strokes::DiameterInput::INDEX) { self.options.diameter = *diameter; } - if let Some(TaggedValue::F64(hardness)) = value(STROKES_HARDNESS_INPUT) { + if let Some(TaggedValue::F64(hardness)) = value(brush_strokes::HardnessInput::INDEX) { self.options.hardness = *hardness; } - if let Some(TaggedValue::F64(flow)) = value(STROKES_FLOW_INPUT) { + if let Some(TaggedValue::F64(flow)) = value(brush_strokes::FlowInput::INDEX) { self.options.flow = *flow; } - if let Some(TaggedValue::Color(color)) = value(STROKES_COLOR_INPUT) + if let Some(TaggedValue::Color(color)) = value(brush_strokes::ColorInput::INDEX) && *color != self.options.active_color() { responses.add(ToolMessage::SelectWorkingColor { color: *color, primary: true }); @@ -252,11 +253,6 @@ impl BrushTool { } } -const STROKES_COLOR_INPUT: usize = 1; -const STROKES_DIAMETER_INPUT: usize = 2; -const STROKES_HARDNESS_INPUT: usize = 3; -const STROKES_FLOW_INPUT: usize = 4; - #[derive(Clone, Debug, Default)] struct BrushToolData { stroke: Stroke, @@ -292,12 +288,13 @@ impl BrushToolData { } let parent = selected_layer.parent(document.metadata()).filter(|&parent| parent != LayerNodeIdentifier::ROOT_PARENT)?; - if !self.load_brush_layer(document, parent) { - return None; - } + let brush_layer = parent + .ancestors(document.metadata()) + .take_while(|&ancestor| ancestor != LayerNodeIdentifier::ROOT_PARENT) + .find(|&ancestor| self.load_brush_layer(document, ancestor))?; let Some(output) = document.network_interface.upstream_output_connector(&InputConnector::node_at_index(selected_layer.to_node(), 1), &[]) else { - return Some((parent, BrushTarget::FillEmpty { layer: selected_layer })); + return Some((brush_layer, BrushTarget::FillEmpty { layer: selected_layer })); }; let new_group = || { @@ -305,22 +302,22 @@ impl BrushToolData { BrushTarget::NewGroup { parent, insert_index } }; let OutputConnector::Node { node_id: strokes_node_id, .. } = output else { - return Some((parent, new_group())); + return Some((brush_layer, new_group())); }; - if document.network_interface.reference(&strokes_node_id, &[]) != Some(DefinitionIdentifier::ProtoNode(graphene_std::brush::brush_strokes::IDENTIFIER)) { - return Some((parent, new_group())); + if document.network_interface.reference(&strokes_node_id, &[]) != Some(DefinitionIdentifier::ProtoNode(brush_strokes::IDENTIFIER)) { + return Some((brush_layer, new_group())); } let strokes = document .network_interface .document_network() .nodes .get(&strokes_node_id) - .and_then(|node| node.inputs.first()) + .and_then(|node| node.inputs.get(brush_strokes::StrokesInput::INDEX)) .and_then(|input| input.as_value()) .and_then(|value| if let TaggedValue::Strokes(strokes) = value { Some(strokes.clone()) } else { None }); match strokes { - Some(strokes) if Self::style_matches(document, strokes_node_id, options) => Some((parent, BrushTarget::Existing { strokes_node_id, strokes })), - _ => Some((parent, new_group())), + Some(strokes) if Self::style_matches(document, strokes_node_id, options) => Some((brush_layer, BrushTarget::Existing { strokes_node_id, strokes })), + _ => Some((brush_layer, new_group())), } } @@ -354,10 +351,10 @@ impl BrushToolData { return false; }; let value = |index: usize| node.inputs.get(index).and_then(|input| input.as_value()); - matches!(value(STROKES_COLOR_INPUT), Some(TaggedValue::Color(color)) if *color == options.active_color()) - && matches!(value(STROKES_DIAMETER_INPUT), Some(TaggedValue::F64(diameter)) if *diameter == options.diameter) - && matches!(value(STROKES_HARDNESS_INPUT), Some(TaggedValue::F64(hardness)) if *hardness == options.hardness) - && matches!(value(STROKES_FLOW_INPUT), Some(TaggedValue::F64(flow)) if *flow == options.flow) + matches!(value(brush_strokes::ColorInput::INDEX), Some(TaggedValue::Color(color)) if *color == options.active_color()) + && matches!(value(brush_strokes::DiameterInput::INDEX), Some(TaggedValue::F64(diameter)) if *diameter == options.diameter) + && matches!(value(brush_strokes::HardnessInput::INDEX), Some(TaggedValue::F64(hardness)) if *hardness == options.hardness) + && matches!(value(brush_strokes::FlowInput::INDEX), Some(TaggedValue::F64(flow)) if *flow == options.flow) } fn push_sample(&mut self, position: DVec2, pressure: Option, elapsed_milliseconds: f64) { @@ -376,7 +373,7 @@ impl BrushToolData { strokes.push(self.stroke.clone()); responses.add(NodeGraphMessage::SetInputValue { node_id: stroke_node_id, - input_index: 0, + input_index: brush_strokes::StrokesInput::INDEX, value: TaggedValue::Strokes(strokes).into(), }); } @@ -562,7 +559,11 @@ fn selected_strokes_node(document: &DocumentMessageHandler) -> Option { selected_layer.children(document.metadata()).next()? } else { let parent = selected_layer.parent(document.metadata()).filter(|&parent| parent != LayerNodeIdentifier::ROOT_PARENT)?; - if !is_brush_layer(document, parent) { + if !parent + .ancestors(document.metadata()) + .take_while(|&ancestor| ancestor != LayerNodeIdentifier::ROOT_PARENT) + .any(|ancestor| is_brush_layer(document, ancestor)) + { return None; } selected_layer @@ -571,7 +572,7 @@ fn selected_strokes_node(document: &DocumentMessageHandler) -> Option { let OutputConnector::Node { node_id, .. } = document.network_interface.upstream_output_connector(&InputConnector::node_at_index(group.to_node(), 1), &[])? else { return None; }; - (document.network_interface.reference(&node_id, &[]) == Some(DefinitionIdentifier::ProtoNode(graphene_std::brush::brush_strokes::IDENTIFIER))).then_some(node_id) + (document.network_interface.reference(&node_id, &[]) == Some(DefinitionIdentifier::ProtoNode(brush_strokes::IDENTIFIER))).then_some(node_id) } fn is_brush_layer(document: &DocumentMessageHandler, candidate: LayerNodeIdentifier) -> bool {