mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-04 05:18:19 +00:00
Fix box selection bug in the Path tool where document and viewport space got mixed up (#2671)
* Fix box selection bug * Fix all layers selected on paste
This commit is contained in:
parent
2cee9e24cd
commit
3496e22f55
2 changed files with 27 additions and 15 deletions
|
@ -1003,6 +1003,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
|
||||||
}
|
}
|
||||||
PortfolioMessage::PasteSerializedData { data } => {
|
PortfolioMessage::PasteSerializedData { data } => {
|
||||||
if let Some(document) = self.active_document() {
|
if let Some(document) = self.active_document() {
|
||||||
|
let mut all_new_ids = Vec::new();
|
||||||
if let Ok(data) = serde_json::from_str::<Vec<CopyBufferEntry>>(&data) {
|
if let Ok(data) = serde_json::from_str::<Vec<CopyBufferEntry>>(&data) {
|
||||||
let parent = document.new_layer_parent(false);
|
let parent = document.new_layer_parent(false);
|
||||||
let mut layers = Vec::new();
|
let mut layers = Vec::new();
|
||||||
|
@ -1019,12 +1020,15 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
|
||||||
document.load_layer_resources(responses);
|
document.load_layer_resources(responses);
|
||||||
let new_ids: HashMap<_, _> = entry.nodes.iter().map(|(id, _)| (*id, NodeId::new())).collect();
|
let new_ids: HashMap<_, _> = entry.nodes.iter().map(|(id, _)| (*id, NodeId::new())).collect();
|
||||||
let layer = LayerNodeIdentifier::new_unchecked(new_ids[&NodeId(0)]);
|
let layer = LayerNodeIdentifier::new_unchecked(new_ids[&NodeId(0)]);
|
||||||
|
all_new_ids.extend(new_ids.values().cloned());
|
||||||
|
|
||||||
responses.add(NodeGraphMessage::AddNodes { nodes: entry.nodes, new_ids });
|
responses.add(NodeGraphMessage::AddNodes { nodes: entry.nodes, new_ids });
|
||||||
responses.add(NodeGraphMessage::MoveLayerToStack { layer, parent, insert_index: 0 });
|
responses.add(NodeGraphMessage::MoveLayerToStack { layer, parent, insert_index: 0 });
|
||||||
layers.push(layer);
|
layers.push(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.add(NodeGraphMessage::RunDocumentGraph);
|
responses.add(NodeGraphMessage::RunDocumentGraph);
|
||||||
|
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: all_new_ids });
|
||||||
responses.add(Message::StartBuffer);
|
responses.add(Message::StartBuffer);
|
||||||
responses.add(PortfolioMessage::CenterPastedLayers { layers });
|
responses.add(PortfolioMessage::CenterPastedLayers { layers });
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::consts::{
|
||||||
};
|
};
|
||||||
use crate::messages::portfolio::document::overlays::utility_functions::{path_overlays, selected_segments};
|
use crate::messages::portfolio::document::overlays::utility_functions::{path_overlays, selected_segments};
|
||||||
use crate::messages::portfolio::document::overlays::utility_types::{DrawHandles, OverlayContext};
|
use crate::messages::portfolio::document::overlays::utility_types::{DrawHandles, OverlayContext};
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::{DocumentMetadata, LayerNodeIdentifier};
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::NodeNetworkInterface;
|
use crate::messages::portfolio::document::utility_types::network_interface::NodeNetworkInterface;
|
||||||
use crate::messages::portfolio::document::utility_types::transformation::Axis;
|
use crate::messages::portfolio::document::utility_types::transformation::Axis;
|
||||||
use crate::messages::preferences::SelectionMode;
|
use crate::messages::preferences::SelectionMode;
|
||||||
|
@ -392,13 +392,13 @@ impl PathToolData {
|
||||||
self.saved_points_before_anchor_select_toggle.clear();
|
self.saved_points_before_anchor_select_toggle.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn selection_quad(&self) -> Quad {
|
pub fn selection_quad(&self, metadata: &DocumentMetadata) -> Quad {
|
||||||
let bbox = self.selection_box();
|
let bbox = self.selection_box(metadata);
|
||||||
Quad::from_box(bbox)
|
Quad::from_box(bbox)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn calculate_selection_mode_from_direction(&mut self) -> SelectionMode {
|
pub fn calculate_selection_mode_from_direction(&mut self, metadata: &DocumentMetadata) -> SelectionMode {
|
||||||
let bbox = self.selection_box();
|
let bbox = self.selection_box(metadata);
|
||||||
let above_threshold = bbox[1].distance_squared(bbox[0]) > DRAG_DIRECTION_MODE_DETERMINATION_THRESHOLD.powi(2);
|
let above_threshold = bbox[1].distance_squared(bbox[0]) > DRAG_DIRECTION_MODE_DETERMINATION_THRESHOLD.powi(2);
|
||||||
|
|
||||||
if self.selection_mode.is_none() && above_threshold {
|
if self.selection_mode.is_none() && above_threshold {
|
||||||
|
@ -414,12 +414,15 @@ impl PathToolData {
|
||||||
self.selection_mode.unwrap_or(SelectionMode::Touched)
|
self.selection_mode.unwrap_or(SelectionMode::Touched)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn selection_box(&self) -> [DVec2; 2] {
|
pub fn selection_box(&self, metadata: &DocumentMetadata) -> [DVec2; 2] {
|
||||||
if self.previous_mouse_position == self.drag_start_pos {
|
// Convert previous mouse position to viewport space first
|
||||||
|
let document_to_viewport = metadata.document_to_viewport;
|
||||||
|
let previous_mouse = document_to_viewport.transform_point2(self.previous_mouse_position);
|
||||||
|
if previous_mouse == self.drag_start_pos {
|
||||||
let tolerance = DVec2::splat(SELECTION_TOLERANCE);
|
let tolerance = DVec2::splat(SELECTION_TOLERANCE);
|
||||||
[self.drag_start_pos - tolerance, self.drag_start_pos + tolerance]
|
[self.drag_start_pos - tolerance, self.drag_start_pos + tolerance]
|
||||||
} else {
|
} else {
|
||||||
[self.drag_start_pos, self.previous_mouse_position]
|
[self.drag_start_pos, previous_mouse]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,6 +467,7 @@ impl PathToolData {
|
||||||
|
|
||||||
// Check if the point is already selected; if not, select the first point within the threshold (in pixels)
|
// Check if the point is already selected; if not, select the first point within the threshold (in pixels)
|
||||||
if let Some((already_selected, mut selection_info)) = shape_editor.get_point_selection_state(&document.network_interface, input.mouse.position, SELECTION_THRESHOLD) {
|
if let Some((already_selected, mut selection_info)) = shape_editor.get_point_selection_state(&document.network_interface, input.mouse.position, SELECTION_THRESHOLD) {
|
||||||
|
log::info!("entered the part where tool identifies a near point");
|
||||||
responses.add(DocumentMessage::StartTransaction);
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
self.last_clicked_point_was_selected = already_selected;
|
self.last_clicked_point_was_selected = already_selected;
|
||||||
|
@ -1129,11 +1133,11 @@ impl Fsm for PathToolFsmState {
|
||||||
let fill_color = Some(fill_color.as_str());
|
let fill_color = Some(fill_color.as_str());
|
||||||
|
|
||||||
let selection_mode = match tool_action_data.preferences.get_selection_mode() {
|
let selection_mode = match tool_action_data.preferences.get_selection_mode() {
|
||||||
SelectionMode::Directional => tool_data.calculate_selection_mode_from_direction(),
|
SelectionMode::Directional => tool_data.calculate_selection_mode_from_direction(document.metadata()),
|
||||||
selection_mode => selection_mode,
|
selection_mode => selection_mode,
|
||||||
};
|
};
|
||||||
|
|
||||||
let quad = tool_data.selection_quad();
|
let quad = tool_data.selection_quad(document.metadata());
|
||||||
let polygon = &tool_data.lasso_polygon;
|
let polygon = &tool_data.lasso_polygon;
|
||||||
|
|
||||||
match (selection_shape, selection_mode) {
|
match (selection_shape, selection_mode) {
|
||||||
|
@ -1207,7 +1211,7 @@ impl Fsm for PathToolFsmState {
|
||||||
delete_segment,
|
delete_segment,
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
tool_data.previous_mouse_position = input.mouse.position;
|
tool_data.previous_mouse_position = document.metadata().document_to_viewport.inverse().transform_point2(input.mouse.position);
|
||||||
|
|
||||||
if selection_shape == SelectionShapeType::Lasso {
|
if selection_shape == SelectionShapeType::Lasso {
|
||||||
extend_lasso(&mut tool_data.lasso_polygon, input.mouse.position);
|
extend_lasso(&mut tool_data.lasso_polygon, input.mouse.position);
|
||||||
|
@ -1435,12 +1439,14 @@ impl Fsm for PathToolFsmState {
|
||||||
SelectionChange::Clear
|
SelectionChange::Clear
|
||||||
};
|
};
|
||||||
|
|
||||||
if tool_data.drag_start_pos == tool_data.previous_mouse_position {
|
let document_to_viewport = document.metadata().document_to_viewport;
|
||||||
|
let previous_mouse = document_to_viewport.transform_point2(tool_data.previous_mouse_position);
|
||||||
|
if tool_data.drag_start_pos == previous_mouse {
|
||||||
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![] });
|
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![] });
|
||||||
} else {
|
} else {
|
||||||
match selection_shape {
|
match selection_shape {
|
||||||
SelectionShapeType::Box => {
|
SelectionShapeType::Box => {
|
||||||
let bbox = [tool_data.drag_start_pos, tool_data.previous_mouse_position];
|
let bbox = [tool_data.drag_start_pos, previous_mouse];
|
||||||
shape_editor.select_all_in_shape(&document.network_interface, SelectionShape::Box(bbox), selection_change);
|
shape_editor.select_all_in_shape(&document.network_interface, SelectionShape::Box(bbox), selection_change);
|
||||||
}
|
}
|
||||||
SelectionShapeType::Lasso => shape_editor.select_all_in_shape(&document.network_interface, SelectionShape::Lasso(&tool_data.lasso_polygon), selection_change),
|
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 {
|
||||||
SelectionChange::Clear
|
SelectionChange::Clear
|
||||||
};
|
};
|
||||||
|
|
||||||
if tool_data.drag_start_pos == tool_data.previous_mouse_position {
|
let document_to_viewport = document.metadata().document_to_viewport;
|
||||||
|
let previous_mouse = document_to_viewport.transform_point2(tool_data.previous_mouse_position);
|
||||||
|
if tool_data.drag_start_pos == previous_mouse {
|
||||||
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![] });
|
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![] });
|
||||||
} else {
|
} else {
|
||||||
match selection_shape {
|
match selection_shape {
|
||||||
SelectionShapeType::Box => {
|
SelectionShapeType::Box => {
|
||||||
let bbox = [tool_data.drag_start_pos, tool_data.previous_mouse_position];
|
let bbox = [tool_data.drag_start_pos, previous_mouse];
|
||||||
shape_editor.select_all_in_shape(&document.network_interface, SelectionShape::Box(bbox), select_kind);
|
shape_editor.select_all_in_shape(&document.network_interface, SelectionShape::Box(bbox), select_kind);
|
||||||
}
|
}
|
||||||
SelectionShapeType::Lasso => shape_editor.select_all_in_shape(&document.network_interface, SelectionShape::Lasso(&tool_data.lasso_polygon), select_kind),
|
SelectionShapeType::Lasso => shape_editor.select_all_in_shape(&document.network_interface, SelectionShape::Lasso(&tool_data.lasso_polygon), select_kind),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue