diff --git a/editor/src/messages/portfolio/document/utility_types/misc.rs b/editor/src/messages/portfolio/document/utility_types/misc.rs index c474bf9665..2394dc73b0 100644 --- a/editor/src/messages/portfolio/document/utility_types/misc.rs +++ b/editor/src/messages/portfolio/document/utility_types/misc.rs @@ -307,6 +307,19 @@ pub enum PathSnapSource { IntersectionPoint, } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum GradientSnapSource { + Endpoint, +} + +impl fmt::Display for GradientSnapSource { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + GradientSnapSource::Endpoint => write!(f, "Gradient: Endpoint"), + } + } +} + impl fmt::Display for PathSnapSource { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -347,6 +360,7 @@ pub enum SnapSource { Artboard(ArtboardSnapSource), Path(PathSnapSource), Alignment(AlignmentSnapSource), + Gradient(GradientSnapSource), } impl SnapSource { @@ -377,6 +391,7 @@ impl fmt::Display for SnapSource { SnapSource::Artboard(artboard_snap_source) => write!(f, "{artboard_snap_source}"), SnapSource::Path(path_snap_source) => write!(f, "{path_snap_source}"), SnapSource::Alignment(alignment_snap_source) => write!(f, "{alignment_snap_source}"), + SnapSource::Gradient(gradient_snap_source) => write!(f, "{gradient_snap_source}"), } } } diff --git a/editor/src/messages/tool/common_functionality/snapping.rs b/editor/src/messages/tool/common_functionality/snapping.rs index 9b53cce626..6089e4dad9 100644 --- a/editor/src/messages/tool/common_functionality/snapping.rs +++ b/editor/src/messages/tool/common_functionality/snapping.rs @@ -259,6 +259,11 @@ impl SnapManager { let snapped = self.free_snap(snap_data, &point, SnapTypeConfiguration::default()); self.update_indicator(snapped); } + pub fn gradient_preview_draw(&mut self, snap_data: &SnapData, mouse: DVec2) { + let point = SnapCandidatePoint::gradient_handle(snap_data.document.metadata().document_to_viewport.inverse().transform_point2(mouse)); + let snapped = self.free_snap(snap_data, &point, SnapTypeConfiguration::default()); + self.update_indicator(snapped); + } pub fn indicator_pos(&self) -> Option { self.indicator.as_ref().map(|point| point.snapped_point_document) diff --git a/editor/src/messages/tool/common_functionality/snapping/layer_snapper.rs b/editor/src/messages/tool/common_functionality/snapping/layer_snapper.rs index 9919855716..18a190ac20 100644 --- a/editor/src/messages/tool/common_functionality/snapping/layer_snapper.rs +++ b/editor/src/messages/tool/common_functionality/snapping/layer_snapper.rs @@ -453,6 +453,10 @@ impl SnapCandidatePoint { Self::new_source(document_point, SnapSource::Path(PathSnapSource::AnchorPointWithFreeHandles)) } + pub fn gradient_handle(document_point: DVec2) -> Self { + Self::new_source(document_point, SnapSource::Gradient(GradientSnapSource::Endpoint)) + } + pub fn handle_neighbors(document_point: DVec2, neighbors: impl Into>) -> Self { let mut point = Self::new_source(document_point, SnapSource::Path(PathSnapSource::AnchorPointWithFreeHandles)); point.neighbors = neighbors.into(); diff --git a/editor/src/messages/tool/tool_messages/gradient_tool.rs b/editor/src/messages/tool/tool_messages/gradient_tool.rs index fd18cc1125..14dc8dba73 100644 --- a/editor/src/messages/tool/tool_messages/gradient_tool.rs +++ b/editor/src/messages/tool/tool_messages/gradient_tool.rs @@ -4,7 +4,7 @@ use crate::messages::portfolio::document::overlays::utility_types::OverlayContex use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier; use crate::messages::tool::common_functionality::auto_panning::AutoPanning; use crate::messages::tool::common_functionality::graph_modification_utils::{NodeGraphLayer, get_gradient}; -use crate::messages::tool::common_functionality::snapping::SnapManager; +use crate::messages::tool::common_functionality::snapping::{SnapCandidatePoint, SnapData, SnapManager, SnapTypeConfiguration}; use graphene_std::vector::style::{Fill, Gradient, GradientType}; #[derive(Default, ExtractField)] @@ -378,6 +378,9 @@ impl Fsm for GradientToolFsmState { } } + let snap_data = SnapData::new(document, input, viewport); + tool_data.snap_manager.draw_overlays(snap_data, &mut overlay_context); + self } (GradientToolFsmState::Ready { .. }, GradientToolMessage::SelectionChanged) => { @@ -591,7 +594,15 @@ impl Fsm for GradientToolFsmState { } (GradientToolFsmState::Drawing, GradientToolMessage::PointerMove { constrain_axis }) => { if let Some(selected_gradient) = &mut tool_data.selected_gradient { - let mouse = input.mouse.position; // tool_data.snap_manager.snap_position(responses, document, input.mouse.position); + let mut mouse = input.mouse.position; + let snap_data = SnapData::new(document, input, viewport); + let point = SnapCandidatePoint::gradient_handle(document.metadata().document_to_viewport.inverse().transform_point2(mouse)); + let snapped = tool_data.snap_manager.free_snap(&snap_data, &point, SnapTypeConfiguration::default()); + if snapped.is_snapped() { + mouse = document.metadata().document_to_viewport.transform_point2(snapped.snapped_point_document); + } + tool_data.snap_manager.update_indicator(snapped); + selected_gradient.update_gradient( mouse, responses, @@ -661,6 +672,9 @@ impl Fsm for GradientToolFsmState { } } + let snap_data = SnapData::new(document, input, viewport); + tool_data.snap_manager.gradient_preview_draw(&snap_data, mouse); + responses.add(OverlaysMessage::Draw); GradientToolFsmState::Ready { hover_insertion } }