mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-04 10:08:12 +08:00
Fix Pen tool race condition when drawing handles fast, and stuck overlays (#1283)
* Fix pen tool with async * Fix overlays staying too long * Perhaps fix the transform issue * Fix compile error * Formatting --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
committed by
Keavon Chambers
co-authored by
Keavon Chambers
parent
4d1c5fc8bf
commit
abd8e7fab6
@@ -15,7 +15,10 @@ use crate::messages::tool::common_functionality::snapping::SnapManager;
|
||||
use crate::messages::tool::utility_types::{EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType};
|
||||
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
|
||||
|
||||
use bezier_rs::Subpath;
|
||||
use document_legacy::LayerId;
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
use graph_craft::document::NodeInput;
|
||||
use graphene_core::uuid::ManipulatorGroupId;
|
||||
use graphene_core::vector::style::{Fill, Stroke};
|
||||
use graphene_core::vector::{ManipulatorPointId, SelectedType};
|
||||
@@ -227,8 +230,8 @@ impl PenToolData {
|
||||
self.subpath_index = subpath_index;
|
||||
|
||||
// Stop the handles on the first point from mirroring
|
||||
let Some(vector_data) = document.document_legacy.layer(layer).ok().and_then(|layer| layer.as_vector_data()) else { return };
|
||||
let manipulator_groups = vector_data.subpaths[subpath_index].manipulator_groups();
|
||||
let Some(subpaths) = get_subpaths(layer, document) else { return };
|
||||
let manipulator_groups = subpaths[subpath_index].manipulator_groups();
|
||||
let Some(last_handle) = (if from_start { manipulator_groups.first() } else { manipulator_groups.last() }) else { return };
|
||||
|
||||
responses.add(GraphOperationMessage::Vector {
|
||||
@@ -284,8 +287,7 @@ impl PenToolData {
|
||||
fn check_break(&mut self, document: &DocumentMessageHandler, transform: DAffine2, shape_overlay: &mut OverlayRenderer, responses: &mut VecDeque<Message>) -> Option<()> {
|
||||
// Get subpath
|
||||
let layer_path = self.path.as_ref()?;
|
||||
let vector_data = document.document_legacy.layer(layer_path).ok().and_then(|layer| layer.as_vector_data())?;
|
||||
let subpath = &vector_data.subpaths[self.subpath_index];
|
||||
let subpath = &get_subpaths(layer_path, document)?[self.subpath_index];
|
||||
|
||||
// Get the last manipulator group and the one previous to that
|
||||
let mut manipulator_groups = subpath.manipulator_groups().iter();
|
||||
@@ -336,8 +338,7 @@ impl PenToolData {
|
||||
fn finish_placing_handle(&mut self, document: &DocumentMessageHandler, transform: DAffine2, shape_overlay: &mut OverlayRenderer, responses: &mut VecDeque<Message>) -> Option<PenToolFsmState> {
|
||||
// Get subpath
|
||||
let layer_path = self.path.as_ref()?;
|
||||
let vector_data = document.document_legacy.layer(layer_path).ok().and_then(|layer| layer.as_vector_data())?;
|
||||
let subpath = &vector_data.subpaths[self.subpath_index];
|
||||
let subpath = &get_subpaths(layer_path, document)?[self.subpath_index];
|
||||
|
||||
// Get the last manipulator group and the one previous to that
|
||||
let mut manipulator_groups = subpath.manipulator_groups().iter();
|
||||
@@ -415,8 +416,7 @@ impl PenToolData {
|
||||
fn drag_handle(&mut self, document: &DocumentMessageHandler, transform: DAffine2, mouse: DVec2, modifiers: ModifierState, responses: &mut VecDeque<Message>) -> Option<PenToolFsmState> {
|
||||
// Get subpath
|
||||
let layer_path = self.path.as_ref()?;
|
||||
let vector_data = document.document_legacy.layer(layer_path).ok().and_then(|layer| layer.as_vector_data())?;
|
||||
let subpath = &vector_data.subpaths[self.subpath_index];
|
||||
let subpath = &get_subpaths(layer_path, document)?[self.subpath_index];
|
||||
|
||||
// Get the last manipulator group
|
||||
let manipulator_groups = subpath.manipulator_groups();
|
||||
@@ -433,6 +433,9 @@ impl PenToolData {
|
||||
let pos = transform.inverse().transform_point2(mouse);
|
||||
|
||||
let pos = compute_snapped_angle(&mut self.angle, modifiers.lock_angle, modifiers.snap_angle, pos, last_anchor);
|
||||
if !pos.is_finite() {
|
||||
return Some(PenToolFsmState::DraggingHandle);
|
||||
}
|
||||
|
||||
// Update points on current segment (to show preview of new handle)
|
||||
let point = ManipulatorPointId::new(last_manipulator_group.id, outwards_handle);
|
||||
@@ -466,8 +469,7 @@ impl PenToolData {
|
||||
fn place_anchor(&mut self, document: &DocumentMessageHandler, transform: DAffine2, mouse: DVec2, modifiers: ModifierState, responses: &mut VecDeque<Message>) -> Option<PenToolFsmState> {
|
||||
// Get subpath
|
||||
let layer_path = self.path.as_ref()?;
|
||||
let vector_data = document.document_legacy.layer(layer_path).ok().and_then(|layer| layer.as_vector_data())?;
|
||||
let subpath = &vector_data.subpaths[self.subpath_index];
|
||||
let subpath = &get_subpaths(layer_path, document)?[self.subpath_index];
|
||||
|
||||
// Get the last manipulator group and the one previous to that
|
||||
let mut manipulator_groups = subpath.manipulator_groups().iter();
|
||||
@@ -512,8 +514,7 @@ impl PenToolData {
|
||||
fn finish_transaction(&mut self, fsm: PenToolFsmState, document: &DocumentMessageHandler, responses: &mut VecDeque<Message>) -> Option<DocumentMessage> {
|
||||
// Get subpath
|
||||
let layer_path = self.path.as_ref()?;
|
||||
let vector_data = document.document_legacy.layer(layer_path).ok().and_then(|layer| layer.as_vector_data())?;
|
||||
let subpath = &vector_data.subpaths[self.subpath_index];
|
||||
let subpath = &get_subpaths(layer_path, document)?[self.subpath_index];
|
||||
|
||||
// Abort if only one manipulator group has been placed
|
||||
if fsm == PenToolFsmState::PlacingAnchor && subpath.len() < 3 {
|
||||
@@ -576,7 +577,20 @@ impl Fsm for PenToolFsmState {
|
||||
tool_options: &Self::ToolOptions,
|
||||
responses: &mut VecDeque<Message>,
|
||||
) -> Self {
|
||||
let transform = tool_data.path.as_ref().and_then(|path| document.document_legacy.multiply_transforms(path).ok()).unwrap_or_default();
|
||||
let mut transform = tool_data.path.as_ref().and_then(|path| document.document_legacy.multiply_transforms(path).ok()).unwrap_or_default();
|
||||
|
||||
if !transform.inverse().is_finite() {
|
||||
let parent_transform = tool_data
|
||||
.path
|
||||
.as_ref()
|
||||
.and_then(|layer_path| document.document_legacy.multiply_transforms(&layer_path[..layer_path.len() - 1]).ok());
|
||||
|
||||
transform = parent_transform.unwrap_or(DAffine2::IDENTITY);
|
||||
}
|
||||
|
||||
if !transform.inverse().is_finite() {
|
||||
transform = DAffine2::IDENTITY;
|
||||
}
|
||||
|
||||
if let ToolMessage::Pen(event) = event {
|
||||
match (self, event) {
|
||||
@@ -753,8 +767,8 @@ fn should_extend(document: &DocumentMessageHandler, pos: DVec2, tolerance: f64)
|
||||
for layer_path in document.selected_layers() {
|
||||
let Ok(viewspace) = document.document_legacy.generate_transform_relative_to_viewport(layer_path) else { continue };
|
||||
|
||||
let Some(vector_data) = document.document_legacy.layer(layer_path).ok().and_then(|layer| layer.as_vector_data()) else { continue };
|
||||
for (subpath_index, subpath) in vector_data.subpaths.iter().enumerate() {
|
||||
let subpaths = get_subpaths(layer_path, document)?;
|
||||
for (subpath_index, subpath) in subpaths.iter().enumerate() {
|
||||
if subpath.closed() {
|
||||
continue;
|
||||
}
|
||||
@@ -774,3 +788,19 @@ fn should_extend(document: &DocumentMessageHandler, pos: DVec2, tolerance: f64)
|
||||
|
||||
best
|
||||
}
|
||||
|
||||
fn get_subpaths<'a>(layer_path: &[LayerId], document: &'a DocumentMessageHandler) -> Option<&'a Vec<Subpath<ManipulatorGroupId>>> {
|
||||
let layer = document.document_legacy.layer(layer_path).ok().and_then(|layer| layer.as_layer().ok())?;
|
||||
let network = &layer.network;
|
||||
for (node, _node_id) in network.primary_flow() {
|
||||
if node.name == "Path Generator" {
|
||||
let subpaths_input = node.inputs.get(0)?;
|
||||
let NodeInput::Value { tagged_value: TaggedValue::Subpaths(subpaths), .. } = subpaths_input else {
|
||||
continue;
|
||||
};
|
||||
|
||||
return Some(subpaths);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user