mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-23 20:18:11 +08:00
Add an arrow to the Shape tool (#3343)
* add arrow shape feature in editor Signed-off-by: krVatsal <kumarvatsal34@gmail.com> * fix the arrow tool to show arrow in viewport space Signed-off-by: krVatsal <kumarvatsal34@gmail.com> * fix the direction of arrow and make the new arrow node Signed-off-by: krVatsal <kumarvatsal34@gmail.com> * updated arrow tool to hae start and end points Signed-off-by: krVatsal <kumarvatsal34@gmail.com> * fixed calculate point bug Signed-off-by: krVatsal <kumarvatsal34@gmail.com> * fixed some bugs of arrow positioning Signed-off-by: krVatsal <kumarvatsal34@gmail.com> * fixed formatting in whole codebase and added fill to arrow Signed-off-by: krVatsal <kumarvatsal34@gmail.com> * fix --------- Signed-off-by: krVatsal <kumarvatsal34@gmail.com> Co-authored-by: Timon <me@timon.zip>
This commit is contained in:
@@ -364,6 +364,10 @@ pub fn get_arc_id(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInt
|
||||
NodeGraphLayer::new(layer, network_interface).upstream_node_id_from_name("Arc")
|
||||
}
|
||||
|
||||
pub fn get_arrow_id(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option<NodeId> {
|
||||
NodeGraphLayer::new(layer, network_interface).upstream_node_id_from_name("Arrow")
|
||||
}
|
||||
|
||||
pub fn get_spiral_id(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option<NodeId> {
|
||||
NodeGraphLayer::new(layer, network_interface).upstream_node_id_from_name("Spiral")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
use super::shape_utility::ShapeToolModifierKey;
|
||||
use super::*;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_document_node_type;
|
||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeTemplate};
|
||||
use crate::messages::prelude::*;
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||
use glam::DVec2;
|
||||
use graph_craft::document::NodeInput;
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Arrow;
|
||||
|
||||
impl Arrow {
|
||||
pub fn create_node(document: &DocumentMessageHandler, drag_start: DVec2) -> NodeTemplate {
|
||||
let node_type = resolve_document_node_type("Arrow").expect("Arrow node does not exist");
|
||||
let viewport_pos = document.metadata().document_to_viewport.transform_point2(drag_start);
|
||||
node_type.node_template_input_override([
|
||||
None,
|
||||
Some(NodeInput::value(TaggedValue::DVec2(viewport_pos), false)), // start
|
||||
Some(NodeInput::value(TaggedValue::DVec2(viewport_pos), false)), // end
|
||||
Some(NodeInput::value(TaggedValue::F64(10.), false)), // shaft_width
|
||||
Some(NodeInput::value(TaggedValue::F64(30.), false)), // head_width
|
||||
Some(NodeInput::value(TaggedValue::F64(20.), false)), // head_length
|
||||
])
|
||||
}
|
||||
|
||||
pub fn update_shape(
|
||||
document: &DocumentMessageHandler,
|
||||
input: &InputPreprocessorMessageHandler,
|
||||
_viewport: &ViewportMessageHandler,
|
||||
layer: LayerNodeIdentifier,
|
||||
tool_data: &mut ShapeToolData,
|
||||
_modifier: ShapeToolModifierKey,
|
||||
responses: &mut VecDeque<Message>,
|
||||
) {
|
||||
// Track current mouse position in viewport space
|
||||
tool_data.line_data.drag_current = input.mouse.position;
|
||||
|
||||
// Convert both points to document space (matching Line tool pattern)
|
||||
let document_to_viewport = document.metadata().document_to_viewport;
|
||||
let start_document = tool_data.data.drag_start;
|
||||
let end_document = document_to_viewport.inverse().transform_point2(tool_data.line_data.drag_current);
|
||||
|
||||
// Calculate length in document space for validation
|
||||
let delta = end_document - start_document;
|
||||
let length_document = delta.length();
|
||||
if length_document < 1e-6 {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(node_id) = graph_modification_utils::get_arrow_id(layer, &document.network_interface) else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Calculate proportional dimensions based on arrow length
|
||||
let shaft_width = length_document * 0.1;
|
||||
let head_width = length_document * 0.3;
|
||||
let head_length = length_document * 0.2;
|
||||
|
||||
// Update Arrow node parameters with document space coordinates (like Line tool)
|
||||
responses.add(NodeGraphMessage::SetInput {
|
||||
input_connector: InputConnector::node(node_id, 1),
|
||||
input: NodeInput::value(TaggedValue::DVec2(start_document), false),
|
||||
});
|
||||
responses.add(NodeGraphMessage::SetInput {
|
||||
input_connector: InputConnector::node(node_id, 2),
|
||||
input: NodeInput::value(TaggedValue::DVec2(end_document), false),
|
||||
});
|
||||
responses.add(NodeGraphMessage::SetInput {
|
||||
input_connector: InputConnector::node(node_id, 3),
|
||||
input: NodeInput::value(TaggedValue::F64(shaft_width), false),
|
||||
});
|
||||
responses.add(NodeGraphMessage::SetInput {
|
||||
input_connector: InputConnector::node(node_id, 4),
|
||||
input: NodeInput::value(TaggedValue::F64(head_width), false),
|
||||
});
|
||||
responses.add(NodeGraphMessage::SetInput {
|
||||
input_connector: InputConnector::node(node_id, 5),
|
||||
input: NodeInput::value(TaggedValue::F64(head_length), false),
|
||||
});
|
||||
|
||||
responses.add(NodeGraphMessage::RunDocumentGraph);
|
||||
}
|
||||
|
||||
pub fn overlays(_document: &DocumentMessageHandler, _tool_data: &ShapeToolData, _overlay_context: &mut OverlayContext) {}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod arc_shape;
|
||||
pub mod arrow_shape;
|
||||
pub mod circle_shape;
|
||||
pub mod ellipse_shape;
|
||||
pub mod grid_shape;
|
||||
@@ -9,6 +10,7 @@ pub mod shape_utility;
|
||||
pub mod spiral_shape;
|
||||
pub mod star_shape;
|
||||
|
||||
pub use super::shapes::arrow_shape::Arrow;
|
||||
pub use super::shapes::ellipse_shape::Ellipse;
|
||||
pub use super::shapes::line_shape::{Line, LineEnd};
|
||||
pub use super::shapes::rectangle_shape::Rectangle;
|
||||
|
||||
@@ -33,6 +33,7 @@ pub enum ShapeType {
|
||||
Grid,
|
||||
Rectangle,
|
||||
Ellipse,
|
||||
Arrow,
|
||||
Line,
|
||||
}
|
||||
|
||||
@@ -47,6 +48,7 @@ impl ShapeType {
|
||||
Self::Spiral => "Spiral",
|
||||
Self::Rectangle => "Rectangle",
|
||||
Self::Ellipse => "Ellipse",
|
||||
Self::Arrow => "Arrow",
|
||||
Self::Line => "Line",
|
||||
})
|
||||
.into()
|
||||
@@ -57,6 +59,7 @@ impl ShapeType {
|
||||
Self::Line => "Line Tool",
|
||||
Self::Rectangle => "Rectangle Tool",
|
||||
Self::Ellipse => "Ellipse Tool",
|
||||
Self::Arrow => "Arrow Tool",
|
||||
_ => "",
|
||||
})
|
||||
.into()
|
||||
@@ -75,6 +78,7 @@ impl ShapeType {
|
||||
Self::Line => "VectorLineTool",
|
||||
Self::Rectangle => "VectorRectangleTool",
|
||||
Self::Ellipse => "VectorEllipseTool",
|
||||
Self::Arrow => "VectorArrowTool",
|
||||
_ => "",
|
||||
})
|
||||
.into()
|
||||
@@ -85,6 +89,7 @@ impl ShapeType {
|
||||
Self::Line => ToolType::Line,
|
||||
Self::Rectangle => ToolType::Rectangle,
|
||||
Self::Ellipse => ToolType::Ellipse,
|
||||
Self::Arrow => ToolType::Shape,
|
||||
_ => ToolType::Shape,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user