mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 14:18:04 +08:00
Exclude viewport zoom from influencing scale in the Transform node set by the drawing tools (#4260)
* Keep viewport zoom out of drawing tools' Transform node * Simplify window-aligned transform helpers and fix spline DragStop fallback
This commit is contained in:
@@ -181,3 +181,44 @@ impl Resize {
|
||||
self.layer = None;
|
||||
}
|
||||
}
|
||||
|
||||
/// The viewport zoom factor, taken from the document-to-viewport transform so it accounts for zoom snapping and canvas flipping.
|
||||
/// Divide a viewport-space measurement by this to convert it to document units.
|
||||
pub fn viewport_zoom(document: &DocumentMessageHandler) -> f64 {
|
||||
document.metadata().document_to_viewport.matrix2.determinant().abs().sqrt()
|
||||
}
|
||||
|
||||
/// The viewport-space transform for a freshly drawn layer placed at `viewport_position`: window-aligned, so it is just the zoom (no tilt or flip).
|
||||
/// Routing it through [`TransformIn::Viewport`] yields a document-space layer transform that counter-rotates the tilt/flip with the zoom left out.
|
||||
/// `aspect` is an optional unitless local-frame stretch (e.g. for polygons and stars); pass [`DVec2::ONE`] for none.
|
||||
pub fn window_aligned_transform(document: &DocumentMessageHandler, viewport_position: DVec2, aspect: DVec2) -> DAffine2 {
|
||||
DAffine2::from_scale_angle_translation(viewport_zoom(document) * aspect, 0., viewport_position)
|
||||
}
|
||||
|
||||
/// [`TransformSet`](GraphOperationMessage::TransformSet) applying [`window_aligned_transform`] to a freshly drawn layer, via
|
||||
/// [`TransformIn::Viewport`] so the parent transform is resolved at execution time (also correct when the placement is deferred until after the graph runs).
|
||||
pub fn window_aligned_transform_set(document: &DocumentMessageHandler, layer: LayerNodeIdentifier, viewport_position: DVec2, aspect: DVec2) -> Message {
|
||||
GraphOperationMessage::TransformSet {
|
||||
layer,
|
||||
transform: window_aligned_transform(document, viewport_position, aspect),
|
||||
transform_in: TransformIn::Viewport,
|
||||
skip_rerender: false,
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
/// [`TransformSet`](GraphOperationMessage::TransformSet) placing a freshly drawn path-like layer (Pen, Freehand, Spline, Line, Arrow) at
|
||||
/// `viewport_position` with only a translation: the drawn geometry holds the shape (including tilt), so the Transform node stays a pure document-space offset.
|
||||
pub fn translation_transform_set(document: &DocumentMessageHandler, layer: LayerNodeIdentifier, viewport_position: DVec2) -> Message {
|
||||
// Same orientation/scale as the document-to-viewport transform, but translated to land the layer's origin at the drawn viewport position.
|
||||
let mut transform = document.metadata().document_to_viewport;
|
||||
transform.translation = viewport_position;
|
||||
|
||||
GraphOperationMessage::TransformSet {
|
||||
layer,
|
||||
transform,
|
||||
transform_in: TransformIn::Viewport,
|
||||
skip_rerender: false,
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use super::shape_utility::ShapeToolModifierKey;
|
||||
use super::*;
|
||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_proto_node_type;
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeTemplate};
|
||||
@@ -9,7 +8,6 @@ use crate::messages::tool::common_functionality::gizmos::shape_gizmos::sweep_ang
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||
use crate::messages::tool::common_functionality::shapes::shape_utility::{ShapeGizmoHandler, arc_outline};
|
||||
use crate::messages::tool::tool_messages::tool_prelude::*;
|
||||
use glam::DAffine2;
|
||||
use graph_craft::document::NodeInput;
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
use graphene_std::vector::misc::ArcType;
|
||||
@@ -159,29 +157,26 @@ impl Arc {
|
||||
};
|
||||
|
||||
let dimensions = (start - end).abs();
|
||||
let mut scale = DVec2::ONE;
|
||||
let mut aspect = 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;
|
||||
aspect.x = dimensions.x / dimensions.y;
|
||||
radius = dimensions.y / 2.;
|
||||
} else {
|
||||
scale.y = dimensions.y / dimensions.x;
|
||||
aspect.y = dimensions.y / dimensions.x;
|
||||
radius = dimensions.x / 2.;
|
||||
}
|
||||
|
||||
let radius = radius / viewport_zoom(document);
|
||||
|
||||
responses.add(NodeGraphMessage::SetInput {
|
||||
input_connector: InputConnector::node(node_id, 1),
|
||||
input: NodeInput::value(TaggedValue::F64(radius), false),
|
||||
});
|
||||
|
||||
responses.add(GraphOperationMessage::TransformSet {
|
||||
layer,
|
||||
transform: DAffine2::from_scale_angle_translation(scale, 0., start.midpoint(end)),
|
||||
transform_in: TransformIn::Viewport,
|
||||
skip_rerender: false,
|
||||
});
|
||||
responses.add(window_aligned_transform_set(document, layer, start.midpoint(end), aspect));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_proto_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::tool::common_functionality::gizmos::shape_gizmos::circle_arc_radius_handle::{RadiusHandle, RadiusHandleState};
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||
use crate::messages::tool::common_functionality::resize::{viewport_zoom, window_aligned_transform_set};
|
||||
use crate::messages::tool::common_functionality::shape_editor::ShapeState;
|
||||
use crate::messages::tool::common_functionality::shapes::shape_utility::{ShapeGizmoHandler, ShapeToolModifierKey};
|
||||
use crate::messages::tool::tool_messages::shape_tool::ShapeToolData;
|
||||
use crate::messages::tool::tool_messages::tool_prelude::*;
|
||||
use glam::DAffine2;
|
||||
use graph_craft::document::NodeInput;
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
|
||||
@@ -101,7 +100,7 @@ impl Circle {
|
||||
return;
|
||||
};
|
||||
|
||||
let dimensions = (start - end).abs();
|
||||
let dimensions = ((start - end) / viewport_zoom(document)).abs();
|
||||
|
||||
// We keep the smaller dimension's scale at 1 and scale the other dimension accordingly
|
||||
let radius: f64 = if dimensions.x > dimensions.y { dimensions.y / 2. } else { dimensions.x / 2. };
|
||||
@@ -111,11 +110,6 @@ impl Circle {
|
||||
input: NodeInput::value(TaggedValue::F64(radius), false),
|
||||
});
|
||||
|
||||
responses.add(GraphOperationMessage::TransformSet {
|
||||
layer,
|
||||
transform: DAffine2::from_scale_angle_translation(DVec2::ONE, 0., start.midpoint(end)),
|
||||
transform_in: TransformIn::Viewport,
|
||||
skip_rerender: false,
|
||||
});
|
||||
responses.add(window_aligned_transform_set(document, layer, start.midpoint(end), DVec2::ONE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use super::shape_utility::ShapeToolModifierKey;
|
||||
use super::*;
|
||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_proto_node_type;
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeTemplate};
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||
use crate::messages::tool::tool_messages::tool_prelude::*;
|
||||
use glam::DAffine2;
|
||||
use graph_craft::document::NodeInput;
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
use std::collections::VecDeque;
|
||||
@@ -36,20 +34,17 @@ impl Ellipse {
|
||||
return;
|
||||
};
|
||||
|
||||
let radius = ((start - end) / 2. / viewport_zoom(document)).abs();
|
||||
|
||||
responses.add(NodeGraphMessage::SetInput {
|
||||
input_connector: InputConnector::node(node_id, 1),
|
||||
input: NodeInput::value(TaggedValue::F64(((start.x - end.x) / 2.).abs()), false),
|
||||
input: NodeInput::value(TaggedValue::F64(radius.x), 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_translation(start.midpoint(end)),
|
||||
transform_in: TransformIn::Viewport,
|
||||
skip_rerender: false,
|
||||
input: NodeInput::value(TaggedValue::F64(radius.y), false),
|
||||
});
|
||||
responses.add(window_aligned_transform_set(document, layer, start.midpoint(end), DVec2::ONE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use super::shape_utility::ShapeToolModifierKey;
|
||||
use super::*;
|
||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_proto_node_type;
|
||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
@@ -10,7 +9,6 @@ use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||
use crate::messages::tool::common_functionality::shape_editor::ShapeState;
|
||||
use crate::messages::tool::common_functionality::shapes::shape_utility::ShapeGizmoHandler;
|
||||
use crate::messages::tool::tool_messages::tool_prelude::*;
|
||||
use glam::DAffine2;
|
||||
use graph_craft::document::NodeInput;
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
use graphene_std::NodeInputDecleration;
|
||||
@@ -117,6 +115,8 @@ impl Grid {
|
||||
|
||||
let (translation, dimensions, angle) = calculate_grid_params(start, end, is_isometric, ipp.keyboard.key(center), ipp.keyboard.key(lock_ratio));
|
||||
|
||||
let dimensions = dimensions / viewport_zoom(document);
|
||||
|
||||
// Set dimensions/spacing
|
||||
responses.add(NodeGraphMessage::SetInput {
|
||||
input_connector: InputConnector::node(node_id, SpacingInput::<f64>::INDEX),
|
||||
@@ -132,12 +132,7 @@ impl Grid {
|
||||
}
|
||||
|
||||
// Set transform
|
||||
responses.add(GraphOperationMessage::TransformSet {
|
||||
layer,
|
||||
transform: DAffine2::from_scale_angle_translation(DVec2::ONE, 0., translation),
|
||||
transform_in: TransformIn::Viewport,
|
||||
skip_rerender: false,
|
||||
});
|
||||
responses.add(window_aligned_transform_set(document, layer, translation, DVec2::ONE));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ pub mod shape_utility;
|
||||
pub mod spiral_shape;
|
||||
pub mod star_shape;
|
||||
|
||||
pub use super::resize::{viewport_zoom, window_aligned_transform_set};
|
||||
pub use super::shapes::arrow_shape::Arrow;
|
||||
pub use super::shapes::ellipse_shape::Ellipse;
|
||||
pub use super::shapes::line_shape::{Line, LineEnd};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use super::shape_utility::{ShapeToolModifierKey, update_radius_sign};
|
||||
use super::*;
|
||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::{DefinitionIdentifier, resolve_document_node_type};
|
||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
@@ -12,7 +11,6 @@ use crate::messages::tool::common_functionality::shape_editor::ShapeState;
|
||||
use crate::messages::tool::common_functionality::shapes::shape_utility::{ShapeGizmoHandler, polygon_outline};
|
||||
use crate::messages::tool::tool_messages::shape_tool::ShapeOptionsUpdate;
|
||||
use crate::messages::tool::tool_messages::tool_prelude::*;
|
||||
use glam::DAffine2;
|
||||
use graph_craft::document::NodeInput;
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
use std::collections::VecDeque;
|
||||
@@ -132,16 +130,18 @@ impl Polygon {
|
||||
let dimensions = (start - end).abs();
|
||||
|
||||
// We keep the smaller dimension's scale at 1 and scale the other dimension accordingly
|
||||
let mut scale = DVec2::ONE;
|
||||
let mut aspect = DVec2::ONE;
|
||||
let radius;
|
||||
if dimensions.x > dimensions.y {
|
||||
scale.x = dimensions.x / dimensions.y;
|
||||
aspect.x = dimensions.x / dimensions.y;
|
||||
radius = dimensions.y / 2.;
|
||||
} else {
|
||||
scale.y = dimensions.y / dimensions.x;
|
||||
aspect.y = dimensions.y / dimensions.x;
|
||||
radius = dimensions.x / 2.;
|
||||
}
|
||||
|
||||
let radius = radius / viewport_zoom(document);
|
||||
|
||||
let Some(node_id) = graph_modification_utils::get_polygon_id(layer, &document.network_interface) else {
|
||||
return;
|
||||
};
|
||||
@@ -151,12 +151,7 @@ impl Polygon {
|
||||
input: NodeInput::value(TaggedValue::F64(radius), false),
|
||||
});
|
||||
|
||||
responses.add(GraphOperationMessage::TransformSet {
|
||||
layer,
|
||||
transform: DAffine2::from_scale_angle_translation(scale, 0., (start + end) / 2.),
|
||||
transform_in: TransformIn::Viewport,
|
||||
skip_rerender: false,
|
||||
});
|
||||
responses.add(window_aligned_transform_set(document, layer, start.midpoint(end), aspect));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use super::shape_utility::ShapeToolModifierKey;
|
||||
use super::*;
|
||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_proto_node_type;
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeTemplate};
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||
use crate::messages::tool::tool_messages::tool_prelude::*;
|
||||
use glam::DAffine2;
|
||||
use graph_craft::document::NodeInput;
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
use std::collections::VecDeque;
|
||||
@@ -36,20 +34,17 @@ impl Rectangle {
|
||||
return;
|
||||
};
|
||||
|
||||
let size = ((start - end) / viewport_zoom(document)).abs();
|
||||
|
||||
responses.add(NodeGraphMessage::SetInput {
|
||||
input_connector: InputConnector::node(node_id, 1),
|
||||
input: NodeInput::value(TaggedValue::F64((start.x - end.x).abs()), false),
|
||||
input: NodeInput::value(TaggedValue::F64(size.x), 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_translation(start.midpoint(end)),
|
||||
transform_in: TransformIn::Viewport,
|
||||
skip_rerender: false,
|
||||
input: NodeInput::value(TaggedValue::F64(size.y), false),
|
||||
});
|
||||
responses.add(window_aligned_transform_set(document, layer, start.midpoint(end), DVec2::ONE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use super::*;
|
||||
use crate::messages::frontend::utility_types::MouseCursorIcon;
|
||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::{DefinitionIdentifier, resolve_document_node_type};
|
||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
@@ -135,7 +134,7 @@ impl Spiral {
|
||||
let snapped_viewport_point = document.metadata().document_to_viewport.transform_point2(snapped.snapped_point_document);
|
||||
shape_tool_data.data.snap_manager.update_indicator(snapped);
|
||||
|
||||
let dragged_distance = (viewport_drag_start - snapped_viewport_point).length();
|
||||
let dragged_distance = (viewport_drag_start - snapped_viewport_point).length() / viewport_zoom(document);
|
||||
|
||||
let Some(node_id) = graph_modification_utils::get_spiral_id(layer, &document.network_interface) else {
|
||||
return;
|
||||
@@ -155,12 +154,7 @@ impl Spiral {
|
||||
SpiralType::Logarithmic => (dragged_distance).max(0.1),
|
||||
};
|
||||
|
||||
responses.add(GraphOperationMessage::TransformSet {
|
||||
layer,
|
||||
transform: DAffine2::from_scale_angle_translation(DVec2::ONE, 0., viewport_drag_start),
|
||||
transform_in: TransformIn::Viewport,
|
||||
skip_rerender: false,
|
||||
});
|
||||
responses.add(window_aligned_transform_set(document, layer, viewport_drag_start, DVec2::ONE));
|
||||
|
||||
responses.add(NodeGraphMessage::SetInput {
|
||||
input_connector: InputConnector::node(node_id, OuterRadiusInput::INDEX),
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use super::shape_utility::{ShapeToolModifierKey, update_radius_sign};
|
||||
use super::*;
|
||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::{DefinitionIdentifier, resolve_document_node_type};
|
||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
@@ -12,7 +11,6 @@ use crate::messages::tool::common_functionality::shape_editor::ShapeState;
|
||||
use crate::messages::tool::common_functionality::shapes::shape_utility::{ShapeGizmoHandler, star_outline};
|
||||
use crate::messages::tool::tool_messages::tool_prelude::*;
|
||||
use core::f64;
|
||||
use glam::DAffine2;
|
||||
use graph_craft::document::NodeInput;
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
use std::collections::VecDeque;
|
||||
@@ -137,16 +135,18 @@ impl Star {
|
||||
let dimensions = (start - end).abs();
|
||||
|
||||
// We keep the smaller dimension's scale at 1 and scale the other dimension accordingly
|
||||
let mut scale = DVec2::ONE;
|
||||
let mut aspect = DVec2::ONE;
|
||||
let radius: f64;
|
||||
if dimensions.x > dimensions.y {
|
||||
scale.x = dimensions.x / dimensions.y;
|
||||
aspect.x = dimensions.x / dimensions.y;
|
||||
radius = dimensions.y / 2.;
|
||||
} else {
|
||||
scale.y = dimensions.y / dimensions.x;
|
||||
aspect.y = dimensions.y / dimensions.x;
|
||||
radius = dimensions.x / 2.;
|
||||
}
|
||||
|
||||
let radius = radius / viewport_zoom(document);
|
||||
|
||||
let Some(node_id) = graph_modification_utils::get_star_id(layer, &document.network_interface) else {
|
||||
return;
|
||||
};
|
||||
@@ -161,12 +161,7 @@ impl Star {
|
||||
input: NodeInput::value(TaggedValue::F64(radius / 2.), false),
|
||||
});
|
||||
|
||||
responses.add(GraphOperationMessage::TransformSet {
|
||||
layer,
|
||||
transform: DAffine2::from_scale_angle_translation(scale, 0., (start + end) / 2.),
|
||||
transform_in: TransformIn::Viewport,
|
||||
skip_rerender: false,
|
||||
});
|
||||
responses.add(window_aligned_transform_set(document, layer, start.midpoint(end), aspect));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use super::tool_prelude::*;
|
||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_network_node_type;
|
||||
use crate::messages::portfolio::document::overlays::utility_functions::path_endpoint_overlays;
|
||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||
@@ -9,6 +8,7 @@ use crate::messages::tool::common_functionality::color_selector::{
|
||||
sync_drawing_state,
|
||||
};
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||
use crate::messages::tool::common_functionality::resize::translation_transform_set;
|
||||
use crate::messages::tool::common_functionality::stroke_options::{StrokeOptionsUpdate, apply_stroke_option, create_stroke_options_popover_widget};
|
||||
use crate::messages::tool::common_functionality::utility_functions::should_extend;
|
||||
use glam::DVec2;
|
||||
@@ -309,16 +309,7 @@ impl Fsm for FreehandToolFsmState {
|
||||
|
||||
// Position the layer at the initial mouse position via Transform
|
||||
responses.add(DeferMessage::AfterGraphRun {
|
||||
messages: vec![
|
||||
GraphOperationMessage::TransformSet {
|
||||
layer,
|
||||
transform: DAffine2::from_translation(input.mouse.position),
|
||||
transform_in: TransformIn::Viewport,
|
||||
skip_rerender: false,
|
||||
}
|
||||
.into(),
|
||||
NodeGraphMessage::RunDocumentGraph.into(),
|
||||
],
|
||||
messages: vec![translation_transform_set(document, layer, input.mouse.position), NodeGraphMessage::RunDocumentGraph.into()],
|
||||
});
|
||||
|
||||
FreehandToolFsmState::Drawing
|
||||
@@ -337,7 +328,7 @@ impl Fsm for FreehandToolFsmState {
|
||||
tool_data.new_layer_viewport_start = None;
|
||||
}
|
||||
let position = if let Some(start) = tool_data.new_layer_viewport_start {
|
||||
input.mouse.position - start
|
||||
document.metadata().document_to_viewport.inverse().transform_vector2(input.mouse.position - start)
|
||||
} else {
|
||||
transform.inverse().transform_point2(input.mouse.position)
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use super::tool_prelude::*;
|
||||
use crate::consts::{COLOR_OVERLAY_BLUE, COLOR_OVERLAY_BLUE_05, HIDE_HANDLE_DISTANCE, LINE_ROTATE_SNAP_ANGLE, SEGMENT_OVERLAY_SIZE};
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::MouseKeys;
|
||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_network_node_type;
|
||||
use crate::messages::portfolio::document::overlays::utility_functions::path_overlays;
|
||||
use crate::messages::portfolio::document::overlays::utility_types::{DrawHandles, OverlayContext};
|
||||
@@ -12,6 +11,7 @@ use crate::messages::tool::common_functionality::color_selector::{
|
||||
sync_drawing_state,
|
||||
};
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils::{self, merge_layers};
|
||||
use crate::messages::tool::common_functionality::resize::translation_transform_set;
|
||||
use crate::messages::tool::common_functionality::shape_editor::ShapeState;
|
||||
use crate::messages::tool::common_functionality::snapping::{SnapCache, SnapCandidatePoint, SnapConstraint, SnapData, SnapManager, SnapTypeConfiguration};
|
||||
use crate::messages::tool::common_functionality::stroke_options::{StrokeOptionsUpdate, apply_stroke_option, create_stroke_options_popover_widget};
|
||||
@@ -1373,13 +1373,7 @@ impl PenToolData {
|
||||
// Defer the transform setup and point insertion until after the layer is created
|
||||
responses.add(DeferMessage::AfterGraphRun {
|
||||
messages: vec![
|
||||
GraphOperationMessage::TransformSet {
|
||||
layer,
|
||||
transform: DAffine2::from_translation(viewport_vec),
|
||||
transform_in: TransformIn::Viewport,
|
||||
skip_rerender: false,
|
||||
}
|
||||
.into(),
|
||||
translation_transform_set(document, layer, viewport_vec),
|
||||
GraphOperationMessage::Vector {
|
||||
layer,
|
||||
modification_type: VectorModificationType::InsertPoint { id, position: DVec2::ZERO },
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use super::tool_prelude::*;
|
||||
use crate::consts::{DRAG_THRESHOLD, PATH_JOIN_THRESHOLD, SNAP_POINT_TOLERANCE};
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::MouseKeys;
|
||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::{resolve_network_node_type, resolve_proto_node_type};
|
||||
use crate::messages::portfolio::document::overlays::utility_functions::path_endpoint_overlays;
|
||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||
@@ -12,6 +11,7 @@ use crate::messages::tool::common_functionality::color_selector::{
|
||||
sync_drawing_state,
|
||||
};
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils::{self, find_spline, merge_layers, merge_points};
|
||||
use crate::messages::tool::common_functionality::resize::translation_transform_set;
|
||||
use crate::messages::tool::common_functionality::snapping::{SnapCandidatePoint, SnapData, SnapManager, SnapTypeConfiguration, SnappedPoint};
|
||||
use crate::messages::tool::common_functionality::stroke_options::{StrokeOptionsUpdate, apply_stroke_option, create_stroke_options_popover_widget};
|
||||
use crate::messages::tool::common_functionality::utility_functions::{closest_point, should_extend};
|
||||
@@ -414,16 +414,7 @@ impl Fsm for SplineToolFsmState {
|
||||
|
||||
// Position the layer at the initial mouse position via Transform
|
||||
responses.add(DeferMessage::AfterGraphRun {
|
||||
messages: vec![
|
||||
GraphOperationMessage::TransformSet {
|
||||
layer,
|
||||
transform: DAffine2::from_translation(viewport_vec),
|
||||
transform_in: TransformIn::Viewport,
|
||||
skip_rerender: false,
|
||||
}
|
||||
.into(),
|
||||
NodeGraphMessage::RunDocumentGraph.into(),
|
||||
],
|
||||
messages: vec![translation_transform_set(document, layer, viewport_vec), NodeGraphMessage::RunDocumentGraph.into()],
|
||||
});
|
||||
|
||||
SplineToolFsmState::Drawing
|
||||
@@ -446,7 +437,7 @@ impl Fsm for SplineToolFsmState {
|
||||
// For newly created layers, the deferred TransformSet may not yet be reflected
|
||||
// in the metadata, so compute local position from the known viewport start.
|
||||
tool_data.next_point = if let Some(start) = tool_data.new_layer_viewport_start {
|
||||
viewport_pos - start
|
||||
document_to_viewport.inverse().transform_vector2(viewport_pos - start)
|
||||
} else {
|
||||
let transform = document.metadata().transform_to_viewport(layer);
|
||||
transform.inverse().transform_point2(viewport_pos)
|
||||
@@ -483,7 +474,7 @@ impl Fsm for SplineToolFsmState {
|
||||
// For newly created layers, the deferred TransformSet may not yet be reflected
|
||||
// in the metadata, so compute local position from the known viewport start.
|
||||
tool_data.next_point = if let Some(start) = tool_data.new_layer_viewport_start {
|
||||
viewport_pos - start
|
||||
document_to_viewport.inverse().transform_vector2(viewport_pos - start)
|
||||
} else {
|
||||
let transform = document.metadata().transform_to_viewport(layer);
|
||||
transform.inverse().transform_point2(viewport_pos)
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::messages::tool::common_functionality::color_selector::{
|
||||
ToolColorOptions, apply_fill_only_color_pick, apply_fill_only_enabled, refresh_slot_working_color, selection_changed_since_last_sync, solid, sync_fill_only,
|
||||
};
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||
use crate::messages::tool::common_functionality::resize::Resize;
|
||||
use crate::messages::tool::common_functionality::resize::{Resize, viewport_zoom, window_aligned_transform};
|
||||
use crate::messages::tool::common_functionality::snapping::{self, SnapCandidatePoint, SnapData};
|
||||
use crate::messages::tool::common_functionality::transformation_cage::*;
|
||||
use crate::messages::tool::common_functionality::utility_functions::text_bounding_box;
|
||||
@@ -971,17 +971,11 @@ impl Fsm for TextToolFsmState {
|
||||
return TextToolFsmState::Editing;
|
||||
}
|
||||
|
||||
// Otherwise create some new text. The drag bounds are in viewport space; map them into document space for the text's
|
||||
// transform and wrapping size, then compose with document-to-viewport so the editing overlay (a screen-space CSS matrix) carries the zoom.
|
||||
let document_to_viewport = document.metadata().document_to_viewport;
|
||||
let viewport_to_document = document_to_viewport.inverse();
|
||||
let document_start = viewport_to_document.transform_point2(start);
|
||||
let document_end = viewport_to_document.transform_point2(end);
|
||||
|
||||
let constraint_size = has_dragged.then_some((document_start - document_end).abs());
|
||||
// Otherwise create some new text. The window-aligned transform is in viewport space, so the editing overlay (a screen-space CSS matrix) carries the zoom.
|
||||
let constraint_size = has_dragged.then_some((start - end).abs() / viewport_zoom(document));
|
||||
let editing_text = EditingText {
|
||||
text: String::new(),
|
||||
transform: document_to_viewport * DAffine2::from_translation(document_start),
|
||||
transform: window_aligned_transform(document, start, DVec2::ONE),
|
||||
typesetting: TypesettingConfig {
|
||||
font_size: tool_options.font_size,
|
||||
letter_spacing: tool_options.letter_spacing,
|
||||
|
||||
@@ -190,8 +190,7 @@ where
|
||||
let mut last_b_srgb = 0u8;
|
||||
|
||||
let mut result = vec![0; data.len() * 4];
|
||||
let mut i = 0;
|
||||
for color in data {
|
||||
for (color, out) in data.iter().zip(result.chunks_exact_mut(4)) {
|
||||
let a = color.a().to_f32();
|
||||
// Smaller alpha values than this would map to fully transparent
|
||||
// anyway, avoid expensive encoding.
|
||||
@@ -215,13 +214,11 @@ where
|
||||
last_b_srgb = float_to_srgb_u8(b);
|
||||
}
|
||||
|
||||
result[i] = last_r_srgb;
|
||||
result[i + 1] = last_g_srgb;
|
||||
result[i + 2] = last_b_srgb;
|
||||
result[i + 3] = (a * 255. + 0.5) as u8;
|
||||
out[0] = last_r_srgb;
|
||||
out[1] = last_g_srgb;
|
||||
out[2] = last_b_srgb;
|
||||
out[3] = (a * 255. + 0.5) as u8;
|
||||
}
|
||||
|
||||
i += 4;
|
||||
}
|
||||
|
||||
(result, *width, *height)
|
||||
|
||||
Reference in New Issue
Block a user