mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 05:48:12 +08:00
Fix tool overlays and snap targets to use upstream Path node geometry, not downstream final geometry (#4114)
* Fix tool overlays and snap targets to use upstream Path node geometry not downstream final geometry * Snap to upstream Path free points, dedupe the lookup via a helper
This commit is contained in:
@@ -26,7 +26,7 @@ use graphene_std::ContextDependencies;
|
||||
use graphene_std::math::quad::Quad;
|
||||
use graphene_std::subpath::Subpath;
|
||||
use graphene_std::transform::Footprint;
|
||||
use graphene_std::vector::click_target::{ClickTarget, ClickTargetType};
|
||||
use graphene_std::vector::click_target::{ClickTarget, ClickTargetType, FreePoint};
|
||||
use graphene_std::vector::{PointId, Vector, VectorModificationType};
|
||||
use kurbo::BezPath;
|
||||
use memo_network::MemoNetwork;
|
||||
@@ -3191,8 +3191,8 @@ impl NodeNetworkInterface {
|
||||
let nodes = network_metadata
|
||||
.persistent_metadata
|
||||
.node_metadata
|
||||
.iter()
|
||||
.filter_map(|(node_id, _)| if self.is_layer(node_id, network_path) { Some(*node_id) } else { None })
|
||||
.keys()
|
||||
.filter_map(|node_id| if self.is_layer(node_id, network_path) { Some(*node_id) } else { None })
|
||||
.collect::<Vec<_>>();
|
||||
let layer_widths = nodes
|
||||
.iter()
|
||||
@@ -3234,6 +3234,39 @@ impl NodeNetworkInterface {
|
||||
self.document_metadata.layer_vector_data.get(&layer).map(|arc| arc.as_ref().clone())
|
||||
}
|
||||
|
||||
/// The vector geometry an upstream Path node would surface for editing.
|
||||
/// This is the result of `compute_modified_vector`, but only if a visible 'Path' node is actually upstream.
|
||||
/// Useful for tool overlays and snap target collection usages that want to match the Path tool's view
|
||||
/// (e.g. the pre-solidified centerline for a Solidify Stroke layer) and otherwise do nothing.
|
||||
pub fn upstream_path_node_vector(&self, layer: LayerNodeIdentifier) -> Option<Vector> {
|
||||
let graph_layer = graph_modification_utils::NodeGraphLayer::new(layer, self);
|
||||
graph_layer.upstream_visible_node_id_from_name_in_layer(&DefinitionIdentifier::Network("Path".into()))?;
|
||||
self.compute_modified_vector(layer)
|
||||
}
|
||||
|
||||
/// Outline targets for the Select tool's hover/selection overlay, mirroring the Path tool's view.
|
||||
/// Returns `Some` when an upstream Path node exists so the outline matches what the Path tool edits
|
||||
/// (e.g. the pre-solidified centerline for a Solidify Stroke layer); returns `None` otherwise so the
|
||||
/// caller can fall back to the layer's recorded `outlines`/`click_targets`.
|
||||
pub fn path_aware_outline_targets(&self, layer: LayerNodeIdentifier) -> Option<Vec<ClickTargetType>> {
|
||||
let vector = self.upstream_path_node_vector(layer)?;
|
||||
|
||||
let mut targets = Vec::new();
|
||||
let subpaths: Vec<Subpath<PointId>> = vector.stroke_bezier_paths().collect();
|
||||
if !subpaths.is_empty() {
|
||||
targets.push(ClickTargetType::CompoundPath(subpaths));
|
||||
}
|
||||
|
||||
for &point_id in vector.point_domain.ids() {
|
||||
if !vector.any_connected(point_id) {
|
||||
let position = vector.point_domain.position_from_id(point_id).unwrap_or_default();
|
||||
targets.push(ClickTargetType::FreePoint(FreePoint::new(point_id, position)));
|
||||
}
|
||||
}
|
||||
|
||||
Some(targets)
|
||||
}
|
||||
|
||||
/// Loads the structure of layer nodes from a node graph.
|
||||
pub fn load_structure(&mut self) {
|
||||
self.document_metadata.structure = HashMap::from_iter([(LayerNodeIdentifier::ROOT_PARENT, NodeRelations::default())]);
|
||||
|
||||
Reference in New Issue
Block a user