mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-30 19:28:12 +08:00
Refactor shape gizmo interactivity to support future shape tools (#2748)
* impl GizmoHandlerTrait,Gizmo-manager and add comments * Code review --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
1875779b0a
commit
d8d2a51926
@@ -416,7 +416,7 @@ mod test_freehand {
|
||||
editor
|
||||
.handle_message(GraphOperationMessage::TransformSet {
|
||||
layer: artboard,
|
||||
transform: DAffine2::from_scale_angle_translation(DVec2::new(1.5, 0.8), 0.3, DVec2::new(10.0, -5.0)),
|
||||
transform: DAffine2::from_scale_angle_translation(DVec2::new(1.5, 0.8), 0.3, DVec2::new(10., -5.)),
|
||||
transform_in: TransformIn::Local,
|
||||
skip_rerender: false,
|
||||
})
|
||||
@@ -424,14 +424,14 @@ mod test_freehand {
|
||||
|
||||
editor.select_tool(ToolType::Freehand).await;
|
||||
|
||||
let mouse_points = [DVec2::new(150.0, 100.0), DVec2::new(200.0, 150.0), DVec2::new(250.0, 130.0), DVec2::new(300.0, 170.0)];
|
||||
let mouse_points = [DVec2::new(150., 100.), DVec2::new(200., 150.), DVec2::new(250., 130.), DVec2::new(300., 170.)];
|
||||
|
||||
// Expected points that will actually be captured by the tool
|
||||
let expected_captured_points = &mouse_points[1..];
|
||||
editor.drag_path(&mouse_points, ModifierKeys::empty()).await;
|
||||
|
||||
let vector_data_list = get_vector_data(&mut editor).await;
|
||||
verify_path_points(&vector_data_list, expected_captured_points, 1.0).expect("Path points verification failed");
|
||||
verify_path_points(&vector_data_list, expected_captured_points, 1.).expect("Path points verification failed");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -439,7 +439,7 @@ mod test_freehand {
|
||||
let mut editor = EditorTestUtils::create();
|
||||
editor.new_document().await;
|
||||
|
||||
let initial_points = [DVec2::new(100.0, 100.0), DVec2::new(200.0, 200.0), DVec2::new(300.0, 100.0)];
|
||||
let initial_points = [DVec2::new(100., 100.), DVec2::new(200., 200.), DVec2::new(300., 100.)];
|
||||
|
||||
editor.select_tool(ToolType::Freehand).await;
|
||||
|
||||
@@ -491,7 +491,7 @@ mod test_freehand {
|
||||
|
||||
assert!(endpoint_viewport_pos.is_finite(), "Endpoint position is not finite");
|
||||
|
||||
let extension_points = [DVec2::new(400.0, 200.0), DVec2::new(500.0, 100.0)];
|
||||
let extension_points = [DVec2::new(400., 200.), DVec2::new(500., 100.)];
|
||||
|
||||
let layer_node_id = {
|
||||
let document = editor.active_document();
|
||||
@@ -558,7 +558,7 @@ mod test_freehand {
|
||||
|
||||
editor.select_tool(ToolType::Freehand).await;
|
||||
|
||||
let initial_points = [DVec2::new(100.0, 100.0), DVec2::new(200.0, 200.0), DVec2::new(300.0, 100.0)];
|
||||
let initial_points = [DVec2::new(100., 100.), DVec2::new(200., 200.), DVec2::new(300., 100.)];
|
||||
|
||||
let first_point = initial_points[0];
|
||||
editor.move_mouse(first_point.x, first_point.y, ModifierKeys::empty(), MouseKeys::empty()).await;
|
||||
@@ -599,7 +599,7 @@ mod test_freehand {
|
||||
})
|
||||
.await;
|
||||
|
||||
let second_path_points = [DVec2::new(400.0, 100.0), DVec2::new(500.0, 200.0), DVec2::new(600.0, 100.0)];
|
||||
let second_path_points = [DVec2::new(400., 100.), DVec2::new(500., 200.), DVec2::new(600., 100.)];
|
||||
|
||||
let first_second_point = second_path_points[0];
|
||||
editor.move_mouse(first_second_point.x, first_second_point.y, ModifierKeys::SHIFT, MouseKeys::empty()).await;
|
||||
@@ -677,12 +677,12 @@ mod test_freehand {
|
||||
|
||||
editor.select_tool(ToolType::Freehand).await;
|
||||
|
||||
let custom_line_weight = 5.0;
|
||||
let custom_line_weight = 5.;
|
||||
editor
|
||||
.handle_message(ToolMessage::Freehand(FreehandToolMessage::UpdateOptions(FreehandOptionsUpdate::LineWeight(custom_line_weight))))
|
||||
.await;
|
||||
|
||||
let points = [DVec2::new(100.0, 100.0), DVec2::new(200.0, 200.0), DVec2::new(300.0, 100.0)];
|
||||
let points = [DVec2::new(100., 100.), DVec2::new(200., 200.), DVec2::new(300., 100.)];
|
||||
|
||||
let first_point = points[0];
|
||||
editor.move_mouse(first_point.x, first_point.y, ModifierKeys::empty(), MouseKeys::empty()).await;
|
||||
|
||||
@@ -718,7 +718,7 @@ mod test_gradient {
|
||||
let mut editor = EditorTestUtils::create();
|
||||
editor.new_document().await;
|
||||
|
||||
editor.handle_message(NavigationMessage::CanvasZoomSet { zoom_factor: 2.0 }).await;
|
||||
editor.handle_message(NavigationMessage::CanvasZoomSet { zoom_factor: 2. }).await;
|
||||
|
||||
editor.drag_tool(ToolType::Rectangle, -5., -3., 100., 100., ModifierKeys::empty()).await;
|
||||
|
||||
@@ -727,7 +727,7 @@ mod test_gradient {
|
||||
editor
|
||||
.handle_message(GraphOperationMessage::TransformSet {
|
||||
layer: selected_layer,
|
||||
transform: DAffine2::from_scale_angle_translation(DVec2::new(1.5, 0.8), 0.3, DVec2::new(10.0, -5.0)),
|
||||
transform: DAffine2::from_scale_angle_translation(DVec2::new(1.5, 0.8), 0.3, DVec2::new(10., -5.)),
|
||||
transform_in: TransformIn::Local,
|
||||
skip_rerender: false,
|
||||
})
|
||||
@@ -803,7 +803,7 @@ mod test_gradient {
|
||||
stops.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
|
||||
|
||||
let positions: Vec<f64> = stops.iter().map(|(pos, _)| *pos).collect();
|
||||
assert_stops_at_positions(&positions, &[0.0, 0.5, 1.0], 0.1);
|
||||
assert_stops_at_positions(&positions, &[0., 0.5, 1.], 0.1);
|
||||
|
||||
let middle_color = stops[1].1.to_rgba8_srgb();
|
||||
|
||||
@@ -843,7 +843,7 @@ mod test_gradient {
|
||||
|
||||
// Check positions are now correctly ordered
|
||||
let updated_positions: Vec<f64> = updated_stops.iter().map(|(pos, _)| *pos).collect();
|
||||
assert_stops_at_positions(&updated_positions, &[0.0, 0.8, 1.0], 0.1);
|
||||
assert_stops_at_positions(&updated_positions, &[0., 0.8, 1.], 0.1);
|
||||
|
||||
// Colors should maintain their associations with the stop points
|
||||
assert_eq!(updated_stops[0].1.to_rgba8_srgb(), Color::BLUE.to_rgba8_srgb());
|
||||
@@ -877,7 +877,7 @@ mod test_gradient {
|
||||
let positions: Vec<f64> = updated_gradient.stops.iter().map(|(pos, _)| *pos).collect();
|
||||
|
||||
// Use helper function to verify positions
|
||||
assert_stops_at_positions(&positions, &[0.0, 0.25, 0.75, 1.0], 0.05);
|
||||
assert_stops_at_positions(&positions, &[0., 0.25, 0.75, 1.], 0.05);
|
||||
|
||||
// Select the stop at position 0.75 and delete it
|
||||
let position2 = DVec2::new(75., 0.);
|
||||
@@ -903,7 +903,7 @@ mod test_gradient {
|
||||
let final_positions: Vec<f64> = final_gradient.stops.iter().map(|(pos, _)| *pos).collect();
|
||||
|
||||
// Verify final positions with helper function
|
||||
assert_stops_at_positions(&final_positions, &[0.0, 0.25, 1.0], 0.05);
|
||||
assert_stops_at_positions(&final_positions, &[0., 0.25, 1.], 0.05);
|
||||
|
||||
// Additional verification that 0.75 stop is gone
|
||||
assert!(!final_positions.iter().any(|pos| (pos - 0.75).abs() < 0.05), "Stop at position 0.75 should have been deleted");
|
||||
|
||||
@@ -6,13 +6,13 @@ use crate::messages::portfolio::document::utility_types::document_metadata::Laye
|
||||
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::{self, NodeGraphLayer};
|
||||
use crate::messages::tool::common_functionality::gizmos::gizmo_manager::GizmoManager;
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils::NodeGraphLayer;
|
||||
use crate::messages::tool::common_functionality::resize::Resize;
|
||||
use crate::messages::tool::common_functionality::shape_gizmos::number_of_points_handle::{NumberOfPointsHandle, NumberOfPointsHandleState};
|
||||
use crate::messages::tool::common_functionality::shape_gizmos::point_radius_handle::{PointRadiusHandle, PointRadiusHandleState};
|
||||
use crate::messages::tool::common_functionality::shapes::line_shape::{LineToolData, clicked_on_line_endpoints};
|
||||
use crate::messages::tool::common_functionality::shapes::polygon_shape::Polygon;
|
||||
use crate::messages::tool::common_functionality::shapes::shape_utility::{ShapeToolModifierKey, ShapeType, anchor_overlays, polygon_outline, star_outline, transform_cage_overlays};
|
||||
use crate::messages::tool::common_functionality::shapes::shape_utility::{ShapeToolModifierKey, ShapeType, anchor_overlays, transform_cage_overlays};
|
||||
use crate::messages::tool::common_functionality::shapes::star_shape::Star;
|
||||
use crate::messages::tool::common_functionality::shapes::{Ellipse, Line, Rectangle};
|
||||
use crate::messages::tool::common_functionality::snapping::{self, SnapCandidatePoint, SnapData, SnapTypeConfiguration};
|
||||
@@ -22,6 +22,8 @@ use graph_craft::document::value::TaggedValue;
|
||||
use graph_craft::document::{NodeId, NodeInput};
|
||||
use graphene_std::Color;
|
||||
use graphene_std::renderer::Quad;
|
||||
use graphene_std::vector::misc::ArcType;
|
||||
use std::vec;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ShapeTool {
|
||||
@@ -36,6 +38,7 @@ pub struct ShapeToolOptions {
|
||||
stroke: ToolColorOptions,
|
||||
vertices: u32,
|
||||
shape_type: ShapeType,
|
||||
arc_type: ArcType,
|
||||
}
|
||||
|
||||
impl Default for ShapeToolOptions {
|
||||
@@ -44,8 +47,9 @@ impl Default for ShapeToolOptions {
|
||||
line_weight: DEFAULT_STROKE_WIDTH,
|
||||
fill: ToolColorOptions::new_secondary(),
|
||||
stroke: ToolColorOptions::new_primary(),
|
||||
shape_type: ShapeType::Polygon,
|
||||
vertices: 5,
|
||||
shape_type: ShapeType::Polygon,
|
||||
arc_type: ArcType::Open,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,6 +64,7 @@ pub enum ShapeOptionsUpdate {
|
||||
WorkingColors(Option<Color>, Option<Color>),
|
||||
Vertices(u32),
|
||||
ShapeType(ShapeType),
|
||||
ArcType(ArcType),
|
||||
}
|
||||
|
||||
#[impl_message(Message, ToolMessage, Shape)]
|
||||
@@ -195,6 +200,9 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for ShapeTo
|
||||
ShapeOptionsUpdate::Vertices(vertices) => {
|
||||
self.options.vertices = vertices;
|
||||
}
|
||||
ShapeOptionsUpdate::ArcType(arc_type) => {
|
||||
self.options.arc_type = arc_type;
|
||||
}
|
||||
}
|
||||
|
||||
self.fsm_state.update_hints(responses);
|
||||
@@ -217,8 +225,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for ShapeTo
|
||||
| ShapeToolFsmState::ResizingBounds
|
||||
| ShapeToolFsmState::DraggingLineEndpoints
|
||||
| ShapeToolFsmState::RotatingBounds
|
||||
| ShapeToolFsmState::DraggingStarInnerRadius
|
||||
| ShapeToolFsmState::DraggingStarNumberPointHandle
|
||||
| ShapeToolFsmState::ModifyingGizmo
|
||||
| ShapeToolFsmState::SkewingBounds { .. } => {
|
||||
actions!(ShapeToolMessageDiscriminant;
|
||||
DragStop,
|
||||
@@ -263,12 +270,9 @@ pub enum ShapeToolFsmState {
|
||||
Ready(ShapeType),
|
||||
Drawing(ShapeType),
|
||||
|
||||
// Line shape-specific
|
||||
// Gizmos
|
||||
DraggingLineEndpoints,
|
||||
|
||||
// Star shape-specific
|
||||
DraggingStarInnerRadius,
|
||||
DraggingStarNumberPointHandle,
|
||||
ModifyingGizmo,
|
||||
|
||||
// Transform cage
|
||||
ResizingBounds,
|
||||
@@ -306,9 +310,8 @@ pub struct ShapeToolData {
|
||||
// Current shape which is being drawn
|
||||
current_shape: ShapeType,
|
||||
|
||||
// Gizmo data
|
||||
pub point_radius_handle: PointRadiusHandle,
|
||||
pub number_of_points_handle: NumberOfPointsHandle,
|
||||
// Gizmos
|
||||
gizmo_manger: GizmoManager,
|
||||
}
|
||||
|
||||
impl ShapeToolData {
|
||||
@@ -324,26 +327,6 @@ impl ShapeToolData {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn outlines(&self, document: &DocumentMessageHandler, overlay_context: &mut OverlayContext) {
|
||||
if let Some(layer) = self.number_of_points_handle.layer.or(self.point_radius_handle.layer) {
|
||||
star_outline(layer, document, overlay_context);
|
||||
polygon_outline(layer, document, overlay_context);
|
||||
return;
|
||||
}
|
||||
|
||||
// Fallback: apply to all selected visible & unlocked star layers
|
||||
for layer in document
|
||||
.network_interface
|
||||
.selected_nodes()
|
||||
.selected_visible_and_unlocked_layers(&document.network_interface)
|
||||
.filter(|layer| {
|
||||
graph_modification_utils::get_star_id(*layer, &document.network_interface).is_some() || graph_modification_utils::get_polygon_id(*layer, &document.network_interface).is_some()
|
||||
}) {
|
||||
star_outline(layer, document, overlay_context);
|
||||
polygon_outline(layer, document, overlay_context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Fsm for ShapeToolFsmState {
|
||||
@@ -382,30 +365,24 @@ impl Fsm for ShapeToolFsmState {
|
||||
.map(|pos| document.metadata().document_to_viewport.transform_point2(pos))
|
||||
.unwrap_or(input.mouse.position);
|
||||
let is_resizing_or_rotating = matches!(self, ShapeToolFsmState::ResizingBounds | ShapeToolFsmState::SkewingBounds { .. } | ShapeToolFsmState::RotatingBounds);
|
||||
let dragging_start_gizmos = matches!(self, Self::DraggingStarInnerRadius);
|
||||
|
||||
if matches!(self, ShapeToolFsmState::DraggingStarInnerRadius | Self::DraggingStarNumberPointHandle | Self::Ready(_)) && !input.keyboard.key(Key::Control) {
|
||||
// Manage state handling of the number of point gizmos
|
||||
tool_data.number_of_points_handle.handle_actions(document, input, mouse_position, &mut overlay_context, responses);
|
||||
|
||||
// Manage state handling of point radius handle gizmo
|
||||
tool_data.point_radius_handle.handle_actions(document, mouse_position);
|
||||
|
||||
tool_data.number_of_points_handle.overlays(document, input, shape_editor, mouse_position, &mut overlay_context);
|
||||
tool_data
|
||||
.point_radius_handle
|
||||
.overlays(tool_data.number_of_points_handle.layer.is_some(), document, input, mouse_position, &mut overlay_context);
|
||||
tool_data.outlines(document, &mut overlay_context);
|
||||
if matches!(self, Self::Ready(_)) && !input.keyboard.key(Key::Control) {
|
||||
tool_data.gizmo_manger.handle_actions(mouse_position, document, responses);
|
||||
tool_data.gizmo_manger.overlays(document, input, shape_editor, mouse_position, &mut overlay_context);
|
||||
}
|
||||
|
||||
let hovered = tool_data.number_of_points_handle.is_hovering() || tool_data.number_of_points_handle.is_dragging() || !tool_data.point_radius_handle.is_inactive();
|
||||
let modifying_transform_cage = matches!(self, ShapeToolFsmState::ResizingBounds | ShapeToolFsmState::RotatingBounds | ShapeToolFsmState::SkewingBounds { .. });
|
||||
if matches!(self, ShapeToolFsmState::ModifyingGizmo) && !input.keyboard.key(Key::Control) {
|
||||
tool_data.gizmo_manger.dragging_overlays(document, input, shape_editor, mouse_position, &mut overlay_context);
|
||||
}
|
||||
|
||||
if !is_resizing_or_rotating && !dragging_start_gizmos && !hovered && !modifying_transform_cage {
|
||||
let modifying_transform_cage = matches!(self, ShapeToolFsmState::ResizingBounds | ShapeToolFsmState::RotatingBounds | ShapeToolFsmState::SkewingBounds { .. });
|
||||
let hovering_over_gizmo = tool_data.gizmo_manger.hovering_over_gizmo();
|
||||
|
||||
if !is_resizing_or_rotating && !matches!(self, ShapeToolFsmState::ModifyingGizmo) && !modifying_transform_cage && !hovering_over_gizmo {
|
||||
tool_data.data.snap_manager.draw_overlays(SnapData::new(document, input), &mut overlay_context);
|
||||
}
|
||||
|
||||
if modifying_transform_cage {
|
||||
if modifying_transform_cage && !matches!(self, ShapeToolFsmState::ModifyingGizmo) {
|
||||
transform_cage_overlays(document, tool_data, &mut overlay_context);
|
||||
}
|
||||
|
||||
@@ -418,7 +395,9 @@ impl Fsm for ShapeToolFsmState {
|
||||
return self;
|
||||
}
|
||||
|
||||
transform_cage_overlays(document, tool_data, &mut overlay_context);
|
||||
if !hovering_over_gizmo {
|
||||
transform_cage_overlays(document, tool_data, &mut overlay_context);
|
||||
}
|
||||
|
||||
let dragging_bounds = tool_data
|
||||
.bounding_box_manager
|
||||
@@ -430,10 +409,10 @@ impl Fsm for ShapeToolFsmState {
|
||||
let edges = bounds.check_selected_edges(input.mouse.position);
|
||||
let is_skewing = matches!(self, ShapeToolFsmState::SkewingBounds { .. });
|
||||
let is_near_square = edges.is_some_and(|hover_edge| bounds.over_extended_edge_midpoint(input.mouse.position, hover_edge));
|
||||
if is_skewing || (dragging_bounds && is_near_square && !is_resizing_or_rotating) {
|
||||
if is_skewing || (dragging_bounds && is_near_square && !is_resizing_or_rotating && !hovering_over_gizmo) {
|
||||
bounds.render_skew_gizmos(&mut overlay_context, tool_data.skew_edge);
|
||||
}
|
||||
if !is_skewing && dragging_bounds {
|
||||
if !is_skewing && dragging_bounds && !hovering_over_gizmo {
|
||||
if let Some(edges) = edges {
|
||||
tool_data.skew_edge = bounds.get_closest_edge(edges, input.mouse.position);
|
||||
}
|
||||
@@ -559,28 +538,9 @@ impl Fsm for ShapeToolFsmState {
|
||||
|
||||
tool_data.line_data.drag_current = mouse_pos;
|
||||
|
||||
// Check if dragging the inner vertices of a star
|
||||
if tool_data.point_radius_handle.hovered() {
|
||||
tool_data.last_mouse_position = mouse_pos;
|
||||
tool_data.point_radius_handle.update_state(PointRadiusHandleState::Dragging);
|
||||
|
||||
// Always store it in document space
|
||||
if tool_data.gizmo_manger.handle_click() {
|
||||
tool_data.data.drag_start = document.metadata().document_to_viewport.inverse().transform_point2(mouse_pos);
|
||||
|
||||
responses.add(DocumentMessage::StartTransaction);
|
||||
return ShapeToolFsmState::DraggingStarInnerRadius;
|
||||
}
|
||||
|
||||
// Check if dragging the number of points handle of a star or polygon
|
||||
if tool_data.number_of_points_handle.is_hovering() {
|
||||
tool_data.last_mouse_position = mouse_pos;
|
||||
tool_data.number_of_points_handle.update_state(NumberOfPointsHandleState::Dragging);
|
||||
|
||||
// Always store it in document space
|
||||
tool_data.data.drag_start = document.metadata().document_to_viewport.inverse().transform_point2(mouse_pos);
|
||||
|
||||
responses.add(DocumentMessage::StartTransaction);
|
||||
return ShapeToolFsmState::DraggingStarNumberPointHandle;
|
||||
return ShapeToolFsmState::ModifyingGizmo;
|
||||
}
|
||||
|
||||
// If clicked on endpoints of a selected line, drag its endpoints
|
||||
@@ -653,13 +613,13 @@ impl Fsm for ShapeToolFsmState {
|
||||
tool_options.fill.apply_fill(layer, responses);
|
||||
}
|
||||
ShapeType::Line => {
|
||||
tool_data.line_data.angle = 0.;
|
||||
tool_data.line_data.weight = tool_options.line_weight;
|
||||
tool_data.line_data.editing_layer = Some(layer);
|
||||
}
|
||||
}
|
||||
tool_options.stroke.apply_stroke(tool_options.line_weight, layer, responses);
|
||||
|
||||
tool_options.stroke.apply_stroke(tool_options.line_weight, layer, responses);
|
||||
tool_data.data.layer = Some(layer);
|
||||
|
||||
ShapeToolFsmState::Drawing(tool_data.current_shape)
|
||||
@@ -695,23 +655,13 @@ impl Fsm for ShapeToolFsmState {
|
||||
|
||||
self
|
||||
}
|
||||
(ShapeToolFsmState::DraggingStarInnerRadius, ShapeToolMessage::PointerMove(..)) => {
|
||||
if let Some(layer) = tool_data.point_radius_handle.layer {
|
||||
tool_data.point_radius_handle.update_inner_radius(document, input, layer, responses, tool_data.data.drag_start);
|
||||
tool_data.last_mouse_position = input.mouse.position;
|
||||
}
|
||||
(ShapeToolFsmState::ModifyingGizmo, ShapeToolMessage::PointerMove(..)) => {
|
||||
responses.add(DocumentMessage::StartTransaction);
|
||||
tool_data.gizmo_manger.handle_update(tool_data.data.drag_start, document, input, responses);
|
||||
|
||||
responses.add(OverlaysMessage::Draw);
|
||||
|
||||
ShapeToolFsmState::DraggingStarInnerRadius
|
||||
}
|
||||
(ShapeToolFsmState::DraggingStarNumberPointHandle, ShapeToolMessage::PointerMove(..)) => {
|
||||
tool_data.number_of_points_handle.update_number_of_sides(document, input, responses, tool_data.data.drag_start);
|
||||
|
||||
tool_data.last_mouse_position = input.mouse.position;
|
||||
responses.add(OverlaysMessage::Draw);
|
||||
|
||||
ShapeToolFsmState::DraggingStarNumberPointHandle
|
||||
ShapeToolFsmState::ModifyingGizmo
|
||||
}
|
||||
(ShapeToolFsmState::ResizingBounds, ShapeToolMessage::PointerMove(modifier)) => {
|
||||
if let Some(bounds) = &mut tool_data.bounding_box_manager {
|
||||
@@ -773,12 +723,12 @@ impl Fsm for ShapeToolFsmState {
|
||||
.and_then(|bounding_box| bounding_box.check_selected_edges(input.mouse.position))
|
||||
.is_some();
|
||||
|
||||
let cursor = tool_data
|
||||
.bounding_box_manager
|
||||
.as_ref()
|
||||
.map_or(MouseCursorIcon::Default, |bounds| bounds.get_cursor(input, true, dragging_bounds, Some(tool_data.skew_edge)));
|
||||
let cursor = tool_data.bounding_box_manager.as_ref().map_or(MouseCursorIcon::Crosshair, |bounds| {
|
||||
let cursor = bounds.get_cursor(input, true, dragging_bounds, Some(tool_data.skew_edge));
|
||||
if cursor == MouseCursorIcon::Default { MouseCursorIcon::Crosshair } else { cursor }
|
||||
});
|
||||
|
||||
if tool_data.cursor != cursor && !input.keyboard.key(Key::Control) && tool_data.point_radius_handle.is_inactive() && !all_selected_layers_line {
|
||||
if tool_data.cursor != cursor && !input.keyboard.key(Key::Control) && !all_selected_layers_line {
|
||||
tool_data.cursor = cursor;
|
||||
responses.add(FrontendMessage::UpdateMouseCursor { cursor });
|
||||
}
|
||||
@@ -811,15 +761,13 @@ impl Fsm for ShapeToolFsmState {
|
||||
| ShapeToolFsmState::ResizingBounds
|
||||
| ShapeToolFsmState::RotatingBounds
|
||||
| ShapeToolFsmState::SkewingBounds { .. }
|
||||
| ShapeToolFsmState::DraggingStarInnerRadius
|
||||
| ShapeToolFsmState::DraggingStarNumberPointHandle,
|
||||
| ShapeToolFsmState::ModifyingGizmo,
|
||||
ShapeToolMessage::DragStop,
|
||||
) => {
|
||||
input.mouse.finish_transaction(tool_data.data.drag_start, responses);
|
||||
tool_data.data.cleanup(responses);
|
||||
|
||||
tool_data.number_of_points_handle.cleanup();
|
||||
tool_data.point_radius_handle.cleanup();
|
||||
tool_data.gizmo_manger.handle_cleanup();
|
||||
|
||||
if let Some(bounds) = &mut tool_data.bounding_box_manager {
|
||||
bounds.original_transforms.clear();
|
||||
@@ -837,17 +785,14 @@ impl Fsm for ShapeToolFsmState {
|
||||
| ShapeToolFsmState::ResizingBounds
|
||||
| ShapeToolFsmState::RotatingBounds
|
||||
| ShapeToolFsmState::SkewingBounds { .. }
|
||||
| ShapeToolFsmState::DraggingStarInnerRadius
|
||||
| ShapeToolFsmState::DraggingStarNumberPointHandle,
|
||||
| ShapeToolFsmState::ModifyingGizmo,
|
||||
ShapeToolMessage::Abort,
|
||||
) => {
|
||||
responses.add(DocumentMessage::AbortTransaction);
|
||||
tool_data.data.cleanup(responses);
|
||||
tool_data.line_data.dragging_endpoint = None;
|
||||
|
||||
// Reset gizmo state
|
||||
tool_data.number_of_points_handle.cleanup();
|
||||
tool_data.point_radius_handle.cleanup();
|
||||
tool_data.gizmo_manger.handle_cleanup();
|
||||
|
||||
if let Some(bounds) = &mut tool_data.bounding_box_manager {
|
||||
bounds.original_transforms.clear();
|
||||
@@ -952,9 +897,7 @@ impl Fsm for ShapeToolFsmState {
|
||||
HintGroup(vec![HintInfo::mouse(MouseMotion::Rmb, ""), HintInfo::keys([Key::Escape], "Cancel").prepend_slash()]),
|
||||
HintGroup(vec![HintInfo::keys([Key::Control], "Unlock Slide")]),
|
||||
]),
|
||||
ShapeToolFsmState::DraggingStarInnerRadius | ShapeToolFsmState::DraggingStarNumberPointHandle => {
|
||||
HintData(vec![HintGroup(vec![HintInfo::mouse(MouseMotion::Rmb, ""), HintInfo::keys([Key::Escape], "Cancel").prepend_slash()])])
|
||||
}
|
||||
ShapeToolFsmState::ModifyingGizmo => HintData(vec![HintGroup(vec![HintInfo::mouse(MouseMotion::Rmb, ""), HintInfo::keys([Key::Escape], "Cancel").prepend_slash()])]),
|
||||
};
|
||||
|
||||
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||
|
||||
@@ -656,15 +656,15 @@ mod test_spline_tool {
|
||||
editor.new_document().await;
|
||||
|
||||
// Zooming the viewport
|
||||
editor.handle_message(NavigationMessage::CanvasZoomSet { zoom_factor: 2.0 }).await;
|
||||
editor.handle_message(NavigationMessage::CanvasZoomSet { zoom_factor: 2. }).await;
|
||||
|
||||
// Selecting the spline tool
|
||||
editor.select_tool(ToolType::Spline).await;
|
||||
|
||||
// Adding points by clicking at different positions
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(50.0, 50.0), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(100.0, 50.0), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(150.0, 100.0), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(50., 50.), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(100., 50.), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(150., 100.), ModifierKeys::empty()).await;
|
||||
|
||||
// Finish the spline
|
||||
editor.handle_message(SplineToolMessage::Confirm).await;
|
||||
@@ -686,7 +686,7 @@ mod test_spline_tool {
|
||||
let layer_to_viewport = document.metadata().transform_to_viewport(layer);
|
||||
|
||||
// Expected points in viewport coordinates
|
||||
let expected_points = vec![DVec2::new(50.0, 50.0), DVec2::new(100.0, 50.0), DVec2::new(150.0, 100.0)];
|
||||
let expected_points = vec![DVec2::new(50., 50.), DVec2::new(100., 50.), DVec2::new(150., 100.)];
|
||||
|
||||
// Assert all points are correctly positioned
|
||||
assert_point_positions(&vector_data, layer_to_viewport, &expected_points, 1e-10);
|
||||
@@ -697,15 +697,15 @@ mod test_spline_tool {
|
||||
let mut editor = EditorTestUtils::create();
|
||||
editor.new_document().await;
|
||||
|
||||
let pan_amount = DVec2::new(200.0, 150.0);
|
||||
let pan_amount = DVec2::new(200., 150.);
|
||||
editor.handle_message(NavigationMessage::CanvasPan { delta: pan_amount }).await;
|
||||
|
||||
editor.select_tool(ToolType::Spline).await;
|
||||
|
||||
// Add points by clicking at different positions
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(50.0, 50.0), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(100.0, 50.0), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(150.0, 100.0), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(50., 50.), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(100., 50.), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(150., 100.), ModifierKeys::empty()).await;
|
||||
|
||||
editor.handle_message(SplineToolMessage::Confirm).await;
|
||||
|
||||
@@ -726,7 +726,7 @@ mod test_spline_tool {
|
||||
let layer_to_viewport = document.metadata().transform_to_viewport(layer);
|
||||
|
||||
// Expected points in viewport coordinates
|
||||
let expected_points = vec![DVec2::new(50.0, 50.0), DVec2::new(100.0, 50.0), DVec2::new(150.0, 100.0)];
|
||||
let expected_points = vec![DVec2::new(50., 50.), DVec2::new(100., 50.), DVec2::new(150., 100.)];
|
||||
|
||||
// Assert all points are correctly positioned
|
||||
assert_point_positions(&vector_data, layer_to_viewport, &expected_points, 1e-10);
|
||||
@@ -738,12 +738,12 @@ mod test_spline_tool {
|
||||
editor.new_document().await;
|
||||
|
||||
// Tilt/rotate the viewport (45 degrees)
|
||||
editor.handle_message(NavigationMessage::CanvasTiltSet { angle_radians: 45.0_f64.to_radians() }).await;
|
||||
editor.handle_message(NavigationMessage::CanvasTiltSet { angle_radians: 45_f64.to_radians() }).await;
|
||||
editor.select_tool(ToolType::Spline).await;
|
||||
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(50.0, 50.0), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(100.0, 50.0), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(150.0, 100.0), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(50., 50.), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(100., 50.), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(150., 100.), ModifierKeys::empty()).await;
|
||||
|
||||
editor.handle_message(SplineToolMessage::Confirm).await;
|
||||
|
||||
@@ -764,7 +764,7 @@ mod test_spline_tool {
|
||||
let layer_to_viewport = document.metadata().transform_to_viewport(layer);
|
||||
|
||||
// Expected points in viewport coordinates
|
||||
let expected_points = vec![DVec2::new(50.0, 50.0), DVec2::new(100.0, 50.0), DVec2::new(150.0, 100.0)];
|
||||
let expected_points = vec![DVec2::new(50., 50.), DVec2::new(100., 50.), DVec2::new(150., 100.)];
|
||||
|
||||
// Assert all points are correctly positioned
|
||||
assert_point_positions(&vector_data, layer_to_viewport, &expected_points, 1e-10);
|
||||
@@ -777,14 +777,14 @@ mod test_spline_tool {
|
||||
|
||||
// Applying multiple transformations
|
||||
editor.handle_message(NavigationMessage::CanvasZoomSet { zoom_factor: 1.5 }).await;
|
||||
editor.handle_message(NavigationMessage::CanvasPan { delta: DVec2::new(100.0, 75.0) }).await;
|
||||
editor.handle_message(NavigationMessage::CanvasTiltSet { angle_radians: 30.0_f64.to_radians() }).await;
|
||||
editor.handle_message(NavigationMessage::CanvasPan { delta: DVec2::new(100., 75.) }).await;
|
||||
editor.handle_message(NavigationMessage::CanvasTiltSet { angle_radians: 30_f64.to_radians() }).await;
|
||||
|
||||
editor.select_tool(ToolType::Spline).await;
|
||||
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(50.0, 50.0), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(100.0, 50.0), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(150.0, 100.0), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(50., 50.), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(100., 50.), ModifierKeys::empty()).await;
|
||||
editor.click_tool(ToolType::Spline, MouseKeys::LEFT, DVec2::new(150., 100.), ModifierKeys::empty()).await;
|
||||
|
||||
editor.handle_message(SplineToolMessage::Confirm).await;
|
||||
if let Err(e) = editor.eval_graph().await {
|
||||
@@ -803,7 +803,7 @@ mod test_spline_tool {
|
||||
let layer_to_viewport = document.metadata().transform_to_viewport(layer);
|
||||
|
||||
// Expected points in viewport coordinates
|
||||
let expected_points = vec![DVec2::new(50.0, 50.0), DVec2::new(100.0, 50.0), DVec2::new(150.0, 100.0)];
|
||||
let expected_points = vec![DVec2::new(50., 50.), DVec2::new(100., 50.), DVec2::new(150., 100.)];
|
||||
|
||||
// Assert all points are correctly positioned
|
||||
assert_point_positions(&vector_data, layer_to_viewport, &expected_points, 1e-10);
|
||||
|
||||
Reference in New Issue
Block a user