Make primitive shape tools no longer draw transformed unit shapes (#2236)

* Line tool pt.1

* Line tool complete

* Fix hints

* Rectangle tool

* Fix bad naming

* Ellipse tool but cant get id

* Fix line tool

* Polygon tool

* Revert unrequested Line tool keybind change; code review cleanup

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Nitish Choudhary 2025-02-05 15:55:07 +05:30 committed by GitHub
parent 0865605f74
commit da752e5324
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 122 additions and 29 deletions

View File

@ -223,6 +223,26 @@ pub fn get_fill_id(layer: LayerNodeIdentifier, network_interface: &NodeNetworkIn
NodeGraphLayer::new(layer, network_interface).upstream_node_id_from_name("Fill")
}
pub fn get_ellipse_id(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option<NodeId> {
NodeGraphLayer::new(layer, network_interface).upstream_node_id_from_name("Ellipse")
}
pub fn get_line_id(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option<NodeId> {
NodeGraphLayer::new(layer, network_interface).upstream_node_id_from_name("Line")
}
pub fn get_polygon_id(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option<NodeId> {
NodeGraphLayer::new(layer, network_interface).upstream_node_id_from_name("Regular Polygon")
}
pub fn get_rectangle_id(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option<NodeId> {
NodeGraphLayer::new(layer, network_interface).upstream_node_id_from_name("Rectangle")
}
pub fn get_star_id(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option<NodeId> {
NodeGraphLayer::new(layer, network_interface).upstream_node_id_from_name("Star")
}
pub fn get_text_id(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option<NodeId> {
NodeGraphLayer::new(layer, network_interface).upstream_node_id_from_name("Text")
}

View File

@ -3,6 +3,7 @@ use crate::consts::DEFAULT_STROKE_WIDTH;
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
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::network_interface::InputConnector;
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
use crate::messages::tool::common_functionality::graph_modification_utils;
@ -220,12 +221,26 @@ impl Fsm for EllipseToolFsmState {
(EllipseToolFsmState::Drawing, EllipseToolMessage::PointerMove { center, lock_ratio }) => {
if let Some([start, end]) = shape_data.calculate_points(document, input, center, lock_ratio) {
if let Some(layer) = shape_data.layer {
let Some(node_id) = graph_modification_utils::get_ellipse_id(layer, &document.network_interface) else {
return self;
};
responses.add(NodeGraphMessage::SetInput {
input_connector: InputConnector::node(node_id, 1),
input: NodeInput::value(TaggedValue::F64(((start.x - end.x) / 2.).abs()), false),
});
responses.add(NodeGraphMessage::SetInput {
input_connector: InputConnector::node(node_id, 2),
input: NodeInput::value(TaggedValue::F64(((start.y - end.y) / 2.).abs()), false),
});
responses.add(GraphOperationMessage::TransformSet {
layer,
transform: DAffine2::from_scale_angle_translation((end - start).abs(), 0., (start + end) / 2.),
transform: DAffine2::from_translation((start + end) / 2.),
transform_in: TransformIn::Viewport,
skip_rerender: false,
});
responses.add(NodeGraphMessage::RunDocumentGraph);
}
}

View File

@ -1,9 +1,8 @@
use super::tool_prelude::*;
use crate::consts::{DEFAULT_STROKE_WIDTH, LINE_ROTATE_SNAP_ANGLE};
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
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::{document_metadata::LayerNodeIdentifier, network_interface::InputConnector};
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
use crate::messages::tool::common_functionality::graph_modification_utils;
@ -179,23 +178,24 @@ impl Fsm for LineToolFsmState {
let node_type = resolve_document_node_type("Line").expect("Line node does not exist");
let node = node_type.node_template_input_override([
None,
Some(NodeInput::value(TaggedValue::DVec2(DVec2::ZERO), false)),
Some(NodeInput::value(TaggedValue::DVec2(DVec2::X), false)),
Some(NodeInput::value(
TaggedValue::DVec2(document.metadata().document_to_viewport.transform_point2(tool_data.drag_start)),
false,
)),
Some(NodeInput::value(
TaggedValue::DVec2(document.metadata().document_to_viewport.transform_point2(tool_data.drag_start)),
false,
)),
]);
let nodes = vec![(NodeId(0), node)];
let layer = graph_modification_utils::new_custom(NodeId::new(), nodes, document.new_layer_bounding_artboard(input), responses);
responses.add(Message::StartBuffer);
responses.add(GraphOperationMessage::TransformSet {
layer,
transform: DAffine2::from_scale_angle_translation(DVec2::ONE, 0., input.mouse.position),
transform_in: TransformIn::Viewport,
skip_rerender: false,
});
tool_options.stroke.apply_stroke(tool_options.line_weight, layer, responses);
tool_data.layer = Some(layer);
tool_data.layer = Some(layer);
tool_data.angle = 0.;
tool_data.weight = tool_options.line_weight;
LineToolFsmState::Drawing
@ -206,7 +206,7 @@ impl Fsm for LineToolFsmState {
let keyboard = &input.keyboard;
let ignore = if let Some(layer) = tool_data.layer { vec![layer] } else { vec![] };
let snap_data = SnapData::ignore(document, input, &ignore);
responses.add(generate_transform(tool_data, snap_data, keyboard.key(lock_angle), keyboard.key(snap_angle), keyboard.key(center)));
generate_line(tool_data, snap_data, keyboard.key(lock_angle), keyboard.key(snap_angle), keyboard.key(center), responses);
// Auto-panning
let messages = [
@ -287,7 +287,7 @@ impl Fsm for LineToolFsmState {
}
}
fn generate_transform(tool_data: &mut LineToolData, snap_data: SnapData, lock_angle: bool, snap_angle: bool, center: bool) -> Message {
fn generate_line(tool_data: &mut LineToolData, snap_data: SnapData, lock_angle: bool, snap_angle: bool, center: bool, responses: &mut VecDeque<Message>) {
let document_to_viewport = snap_data.document.metadata().document_to_viewport;
let mut document_points = [tool_data.drag_start, document_to_viewport.inverse().transform_point2(tool_data.drag_current)];
@ -347,17 +347,18 @@ fn generate_transform(tool_data: &mut LineToolData, snap_data: SnapData, lock_an
snap.update_indicator(snapped);
}
// Used for keeping the same angle next frame
tool_data.angle = -(document_points[1] - document_points[0]).angle_to(DVec2::X);
let Some(node_id) = graph_modification_utils::get_line_id(tool_data.layer.unwrap(), &snap_data.document.network_interface) else {
return;
};
let viewport_points = [document_to_viewport.transform_point2(document_points[0]), document_to_viewport.transform_point2(document_points[1])];
let line_length = (viewport_points[1] - viewport_points[0]).length();
let angle = -(viewport_points[1] - viewport_points[0]).angle_to(DVec2::X);
GraphOperationMessage::TransformSet {
layer: tool_data.layer.unwrap(),
transform: glam::DAffine2::from_scale_angle_translation(DVec2::new(line_length, 1.), angle, viewport_points[0]),
transform_in: TransformIn::Viewport,
skip_rerender: false,
}
.into()
responses.add(NodeGraphMessage::SetInput {
input_connector: InputConnector::node(node_id, 1),
input: NodeInput::value(TaggedValue::DVec2(document_points[0]), false),
});
responses.add(NodeGraphMessage::SetInput {
input_connector: InputConnector::node(node_id, 2),
input: NodeInput::value(TaggedValue::DVec2(document_points[1]), false),
});
responses.add(NodeGraphMessage::RunDocumentGraph);
}

View File

@ -282,12 +282,55 @@ impl Fsm for PolygonToolFsmState {
// TODO: make the scale impact the polygon/star node - we need to determine how to allow the polygon node to make irregular shapes
update_radius_sign(end, start, layer, document, responses);
let dimensions = (start - end).abs();
let mut scale = DVec2::ONE;
let radius: f64;
// We keep the smaller dimension's scale at 1 and scale the other dimension accordingly
if dimensions.x > dimensions.y {
scale.x = dimensions.x / dimensions.y;
radius = dimensions.y / 2.;
} else {
scale.y = dimensions.y / dimensions.x;
radius = dimensions.x / 2.;
}
match tool_options.polygon_type {
PolygonType::Convex => {
let Some(node_id) = graph_modification_utils::get_polygon_id(layer, &document.network_interface) else {
return self;
};
responses.add(NodeGraphMessage::SetInput {
input_connector: InputConnector::node(node_id, 2),
input: NodeInput::value(TaggedValue::F64(radius), false),
});
}
PolygonType::Star => {
let Some(node_id) = graph_modification_utils::get_star_id(layer, &document.network_interface) else {
return self;
};
responses.add(NodeGraphMessage::SetInput {
input_connector: InputConnector::node(node_id, 2),
input: NodeInput::value(TaggedValue::F64(radius), false),
});
responses.add(NodeGraphMessage::SetInput {
input_connector: InputConnector::node(node_id, 3),
input: NodeInput::value(TaggedValue::F64(radius / 2.), false),
});
}
}
responses.add(GraphOperationMessage::TransformSet {
layer,
transform: DAffine2::from_scale_angle_translation((end - start).abs(), 0., (start + end) / 2.),
transform: DAffine2::from_scale_angle_translation(scale, 0., (start + end) / 2.),
transform_in: TransformIn::Viewport,
skip_rerender: false,
});
responses.add(NodeGraphMessage::RunDocumentGraph);
}
}

View File

@ -1,7 +1,7 @@
use super::tool_prelude::*;
use crate::consts::DEFAULT_STROKE_WIDTH;
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_document_node_type;
use crate::messages::portfolio::document::{graph_operation::utility_types::TransformIn, overlays::utility_types::OverlayContext};
use crate::messages::portfolio::document::{graph_operation::utility_types::TransformIn, overlays::utility_types::OverlayContext, utility_types::network_interface::InputConnector};
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
use crate::messages::tool::common_functionality::graph_modification_utils;
@ -225,12 +225,26 @@ impl Fsm for RectangleToolFsmState {
if let Some([start, end]) = shape_data.calculate_points(document, input, center, lock_ratio) {
if let Some(layer) = shape_data.layer {
// TODO: make the scale impact the rect node
let Some(node_id) = graph_modification_utils::get_rectangle_id(layer, &document.network_interface) else {
return self;
};
responses.add(NodeGraphMessage::SetInput {
input_connector: InputConnector::node(node_id, 1),
input: NodeInput::value(TaggedValue::F64((start.x - end.x).abs()), false),
});
responses.add(NodeGraphMessage::SetInput {
input_connector: InputConnector::node(node_id, 2),
input: NodeInput::value(TaggedValue::F64((start.y - end.y).abs()), false),
});
responses.add(GraphOperationMessage::TransformSet {
layer,
transform: DAffine2::from_scale_angle_translation((end - start).abs(), 0., (start + end) / 2.),
transform: DAffine2::from_translation((start + end) / 2.),
transform_in: TransformIn::Viewport,
skip_rerender: false,
});
responses.add(NodeGraphMessage::RunDocumentGraph);
}
}