Skip to content

Commit afe8075

Browse files
authored
Merge branch 'master' into 2558-free-floating-anchors-overlays
2 parents 87eb747 + f6e592d commit afe8075

File tree

5 files changed

+91
-21
lines changed

5 files changed

+91
-21
lines changed

editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,11 +1214,6 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
12141214
if is_stack_wire(&wire) { stack_wires.push(wire) } else { node_wires.push(wire) }
12151215
}
12161216

1217-
// Auto convert node to layer when inserting on a single stack wire
1218-
if stack_wires.len() == 1 && node_wires.is_empty() {
1219-
network_interface.set_to_node_or_layer(&selected_node_id, selection_network_path, true)
1220-
}
1221-
12221217
let overlapping_wire = if network_interface.is_layer(&selected_node_id, selection_network_path) {
12231218
if stack_wires.len() == 1 {
12241219
stack_wires.first()

editor/src/messages/portfolio/portfolio_message_handler.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
10031003
}
10041004
PortfolioMessage::PasteSerializedData { data } => {
10051005
if let Some(document) = self.active_document() {
1006+
let mut all_new_ids = Vec::new();
10061007
if let Ok(data) = serde_json::from_str::<Vec<CopyBufferEntry>>(&data) {
10071008
let parent = document.new_layer_parent(false);
10081009
let mut layers = Vec::new();
@@ -1019,12 +1020,15 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
10191020
document.load_layer_resources(responses);
10201021
let new_ids: HashMap<_, _> = entry.nodes.iter().map(|(id, _)| (*id, NodeId::new())).collect();
10211022
let layer = LayerNodeIdentifier::new_unchecked(new_ids[&NodeId(0)]);
1023+
all_new_ids.extend(new_ids.values().cloned());
1024+
10221025
responses.add(NodeGraphMessage::AddNodes { nodes: entry.nodes, new_ids });
10231026
responses.add(NodeGraphMessage::MoveLayerToStack { layer, parent, insert_index: 0 });
10241027
layers.push(layer);
10251028
}
10261029

10271030
responses.add(NodeGraphMessage::RunDocumentGraph);
1031+
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: all_new_ids });
10281032
responses.add(Message::StartBuffer);
10291033
responses.add(PortfolioMessage::CenterPastedLayers { layers });
10301034
}

editor/src/messages/tool/tool_messages/path_tool.rs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::consts::{
66
};
77
use crate::messages::portfolio::document::overlays::utility_functions::{path_overlays, selected_segments};
88
use crate::messages::portfolio::document::overlays::utility_types::{DrawHandles, OverlayContext};
9-
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
9+
use crate::messages::portfolio::document::utility_types::document_metadata::{DocumentMetadata, LayerNodeIdentifier};
1010
use crate::messages::portfolio::document::utility_types::network_interface::NodeNetworkInterface;
1111
use crate::messages::portfolio::document::utility_types::transformation::Axis;
1212
use crate::messages::preferences::SelectionMode;
@@ -392,13 +392,13 @@ impl PathToolData {
392392
self.saved_points_before_anchor_select_toggle.clear();
393393
}
394394

395-
pub fn selection_quad(&self) -> Quad {
396-
let bbox = self.selection_box();
395+
pub fn selection_quad(&self, metadata: &DocumentMetadata) -> Quad {
396+
let bbox = self.selection_box(metadata);
397397
Quad::from_box(bbox)
398398
}
399399

400-
pub fn calculate_selection_mode_from_direction(&mut self) -> SelectionMode {
401-
let bbox = self.selection_box();
400+
pub fn calculate_selection_mode_from_direction(&mut self, metadata: &DocumentMetadata) -> SelectionMode {
401+
let bbox = self.selection_box(metadata);
402402
let above_threshold = bbox[1].distance_squared(bbox[0]) > DRAG_DIRECTION_MODE_DETERMINATION_THRESHOLD.powi(2);
403403

404404
if self.selection_mode.is_none() && above_threshold {
@@ -414,12 +414,15 @@ impl PathToolData {
414414
self.selection_mode.unwrap_or(SelectionMode::Touched)
415415
}
416416

417-
pub fn selection_box(&self) -> [DVec2; 2] {
418-
if self.previous_mouse_position == self.drag_start_pos {
417+
pub fn selection_box(&self, metadata: &DocumentMetadata) -> [DVec2; 2] {
418+
// Convert previous mouse position to viewport space first
419+
let document_to_viewport = metadata.document_to_viewport;
420+
let previous_mouse = document_to_viewport.transform_point2(self.previous_mouse_position);
421+
if previous_mouse == self.drag_start_pos {
419422
let tolerance = DVec2::splat(SELECTION_TOLERANCE);
420423
[self.drag_start_pos - tolerance, self.drag_start_pos + tolerance]
421424
} else {
422-
[self.drag_start_pos, self.previous_mouse_position]
425+
[self.drag_start_pos, previous_mouse]
423426
}
424427
}
425428

@@ -464,6 +467,7 @@ impl PathToolData {
464467

465468
// Check if the point is already selected; if not, select the first point within the threshold (in pixels)
466469
if let Some((already_selected, mut selection_info)) = shape_editor.get_point_selection_state(&document.network_interface, input.mouse.position, SELECTION_THRESHOLD) {
470+
log::info!("entered the part where tool identifies a near point");
467471
responses.add(DocumentMessage::StartTransaction);
468472

469473
self.last_clicked_point_was_selected = already_selected;
@@ -1129,11 +1133,11 @@ impl Fsm for PathToolFsmState {
11291133
let fill_color = Some(fill_color.as_str());
11301134

11311135
let selection_mode = match tool_action_data.preferences.get_selection_mode() {
1132-
SelectionMode::Directional => tool_data.calculate_selection_mode_from_direction(),
1136+
SelectionMode::Directional => tool_data.calculate_selection_mode_from_direction(document.metadata()),
11331137
selection_mode => selection_mode,
11341138
};
11351139

1136-
let quad = tool_data.selection_quad();
1140+
let quad = tool_data.selection_quad(document.metadata());
11371141
let polygon = &tool_data.lasso_polygon;
11381142

11391143
match (selection_shape, selection_mode) {
@@ -1207,7 +1211,7 @@ impl Fsm for PathToolFsmState {
12071211
delete_segment,
12081212
},
12091213
) => {
1210-
tool_data.previous_mouse_position = input.mouse.position;
1214+
tool_data.previous_mouse_position = document.metadata().document_to_viewport.inverse().transform_point2(input.mouse.position);
12111215

12121216
if selection_shape == SelectionShapeType::Lasso {
12131217
extend_lasso(&mut tool_data.lasso_polygon, input.mouse.position);
@@ -1435,12 +1439,14 @@ impl Fsm for PathToolFsmState {
14351439
SelectionChange::Clear
14361440
};
14371441

1438-
if tool_data.drag_start_pos == tool_data.previous_mouse_position {
1442+
let document_to_viewport = document.metadata().document_to_viewport;
1443+
let previous_mouse = document_to_viewport.transform_point2(tool_data.previous_mouse_position);
1444+
if tool_data.drag_start_pos == previous_mouse {
14391445
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![] });
14401446
} else {
14411447
match selection_shape {
14421448
SelectionShapeType::Box => {
1443-
let bbox = [tool_data.drag_start_pos, tool_data.previous_mouse_position];
1449+
let bbox = [tool_data.drag_start_pos, previous_mouse];
14441450
shape_editor.select_all_in_shape(&document.network_interface, SelectionShape::Box(bbox), selection_change);
14451451
}
14461452
SelectionShapeType::Lasso => shape_editor.select_all_in_shape(&document.network_interface, SelectionShape::Lasso(&tool_data.lasso_polygon), selection_change),
@@ -1481,12 +1487,14 @@ impl Fsm for PathToolFsmState {
14811487
SelectionChange::Clear
14821488
};
14831489

1484-
if tool_data.drag_start_pos == tool_data.previous_mouse_position {
1490+
let document_to_viewport = document.metadata().document_to_viewport;
1491+
let previous_mouse = document_to_viewport.transform_point2(tool_data.previous_mouse_position);
1492+
if tool_data.drag_start_pos == previous_mouse {
14851493
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![] });
14861494
} else {
14871495
match selection_shape {
14881496
SelectionShapeType::Box => {
1489-
let bbox = [tool_data.drag_start_pos, tool_data.previous_mouse_position];
1497+
let bbox = [tool_data.drag_start_pos, previous_mouse];
14901498
shape_editor.select_all_in_shape(&document.network_interface, SelectionShape::Box(bbox), select_kind);
14911499
}
14921500
SelectionShapeType::Lasso => shape_editor.select_all_in_shape(&document.network_interface, SelectionShape::Lasso(&tool_data.lasso_polygon), select_kind),

node-graph/gcore/src/vector/vector_data.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ mod attributes;
22
mod indexed;
33
mod modification;
44

5-
use super::misc::point_to_dvec2;
5+
use super::misc::{dvec2_to_point, point_to_dvec2};
66
use super::style::{PathStyle, Stroke};
77
use crate::instances::Instances;
88
use crate::renderer::{ClickTargetType, FreePoint};
@@ -13,6 +13,7 @@ use core::borrow::Borrow;
1313
use dyn_any::DynAny;
1414
use glam::{DAffine2, DVec2};
1515
pub use indexed::VectorDataIndex;
16+
use kurbo::{Affine, Shape};
1617
pub use modification::*;
1718
use std::collections::HashMap;
1819

@@ -216,6 +217,23 @@ impl VectorData {
216217
}
217218
}
218219
vector_data
220+
}
221+
222+
pub fn close_subpaths(&mut self) {
223+
let segments_to_add: Vec<_> = self
224+
.stroke_bezier_paths()
225+
.filter(|subpath| !subpath.closed)
226+
.filter_map(|subpath| {
227+
let (first, last) = subpath.manipulator_groups().first().zip(subpath.manipulator_groups().last())?;
228+
let (start, end) = self.point_domain.resolve_id(first.id).zip(self.point_domain.resolve_id(last.id))?;
229+
Some((start, end))
230+
})
231+
.collect();
232+
233+
for (start, end) in segments_to_add {
234+
let segment_id = self.segment_domain.next_id().next_id();
235+
self.segment_domain.push(segment_id, start, end, bezier_rs::BezierHandles::Linear, StrokeId::ZERO);
236+
}
219237
}
220238

221239
/// Compute the bounding boxes of the subpaths without any transform
@@ -341,6 +359,34 @@ impl VectorData {
341359
self.point_domain.resolve_id(point).map_or(0, |point| self.segment_domain.connected_count(point))
342360
}
343361

362+
pub fn check_point_inside_shape(&self, vector_data_transform: DAffine2, point: DVec2) -> bool {
363+
let bez_paths: Vec<_> = self
364+
.stroke_bezpath_iter()
365+
.map(|mut bezpath| {
366+
// TODO: apply transform to points instead of modifying the paths
367+
bezpath.apply_affine(Affine::new(vector_data_transform.to_cols_array()));
368+
bezpath.close_path();
369+
let bbox = bezpath.bounding_box();
370+
(bezpath, bbox)
371+
})
372+
.collect();
373+
374+
// Check against all paths the point is contained in to compute the correct winding number
375+
let mut number = 0;
376+
377+
for (shape, bbox) in bez_paths {
378+
if bbox.x0 > point.x || bbox.y0 > point.y || bbox.x1 < point.x || bbox.y1 < point.y {
379+
continue;
380+
}
381+
382+
let winding = shape.winding(dvec2_to_point(point));
383+
number += winding;
384+
}
385+
386+
// Non-zero fill rule
387+
number != 0
388+
}
389+
344390
/// Points that can be extended from.
345391
///
346392
/// This is usually only points with exactly one connection unless vector meshes are enabled.

node-graph/gcore/src/vector/vector_nodes.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,6 +1715,23 @@ fn bevel(_: impl Ctx, source: VectorDataTable, #[default(10.)] distance: Length)
17151715
result
17161716
}
17171717

1718+
#[node_macro::node(category("Vector"), path(graphene_core::vector))]
1719+
fn close_path(_: impl Ctx, source: VectorDataTable) -> VectorDataTable {
1720+
let mut new_table = VectorDataTable::empty();
1721+
1722+
for mut source_instance in source.instance_iter() {
1723+
source_instance.instance.close_subpaths();
1724+
new_table.push(source_instance);
1725+
}
1726+
1727+
new_table
1728+
}
1729+
1730+
#[node_macro::node(category("Vector"), path(graphene_core::vector))]
1731+
fn point_inside(_: impl Ctx, source: VectorDataTable, point: DVec2) -> bool {
1732+
source.instance_iter().any(|instance| instance.instance.check_point_inside_shape(instance.transform, point))
1733+
}
1734+
17181735
#[node_macro::node(name("Merge by Distance"), category("Vector"), path(graphene_core::vector))]
17191736
fn merge_by_distance(_: impl Ctx, source: VectorDataTable, #[default(10.)] distance: Length) -> VectorDataTable {
17201737
let source_transform = source.transform();

0 commit comments

Comments
 (0)