mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-12-23 10:11:54 +00:00
Add dragging of layers with the select tool (#293)
* Add dragging of layers with the select tool * Transform mouse positions based on root transform * Add TODOs regarding root inverse transforms
This commit is contained in:
parent
ac7b5dd06e
commit
d15d7d0fab
2 changed files with 80 additions and 28 deletions
|
|
@ -57,6 +57,7 @@ pub enum DocumentMessage {
|
|||
SetCanvasRotation(f64),
|
||||
NudgeSelectedLayers(f64, f64),
|
||||
FlipLayer(Vec<LayerId>, bool, bool),
|
||||
DragLayer(Vec<LayerId>, DVec2),
|
||||
MoveSelectedLayersTo { path: Vec<LayerId>, insert_index: isize },
|
||||
ReorderSelectedLayers(i32), // relatve_position,
|
||||
}
|
||||
|
|
@ -647,6 +648,20 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
|
|||
);
|
||||
}
|
||||
}
|
||||
DragLayer(path, offset) => {
|
||||
// TODO: Replace root transformations with functions of the transform api
|
||||
// and do the same with all instances of `root.transform.inverse()` in other messages
|
||||
let transformed_mouse_pos = self.active_document().document.root.transform.inverse().transform_vector2(ipp.mouse.position.as_dvec2());
|
||||
let translation = offset + transformed_mouse_pos;
|
||||
if let Ok(layer) = self.active_document_mut().document.layer_mut(&path) {
|
||||
let transform = {
|
||||
let mut transform = layer.transform;
|
||||
transform.translation = translation;
|
||||
transform.to_cols_array()
|
||||
};
|
||||
responses.push_back(DocumentOperation::SetLayerTransform { path, transform }.into());
|
||||
}
|
||||
}
|
||||
message => todo!("document_action_handler does not implement: {}", message.to_discriminant().global_name()),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ impl Default for SelectToolFsmState {
|
|||
struct SelectToolData {
|
||||
drag_start: ViewportPosition,
|
||||
drag_current: ViewportPosition,
|
||||
layers_dragging: Vec<(Vec<LayerId>, DVec2)>, // Paths and offsets
|
||||
}
|
||||
|
||||
impl Fsm for SelectToolFsmState {
|
||||
|
|
@ -71,33 +72,13 @@ impl Fsm for SelectToolFsmState {
|
|||
(Ready, DragStart) => {
|
||||
data.drag_start = input.mouse.position;
|
||||
data.drag_current = input.mouse.position;
|
||||
responses.push_back(Operation::MountWorkingFolder { path: vec![] }.into());
|
||||
Dragging
|
||||
}
|
||||
(Dragging, MouseMove) => {
|
||||
data.drag_current = input.mouse.position;
|
||||
|
||||
responses.push_back(Operation::ClearWorkingFolder.into());
|
||||
responses.push_back(make_operation(data, tool_data, transform));
|
||||
|
||||
Dragging
|
||||
}
|
||||
(Dragging, DragStop) => {
|
||||
data.drag_current = input.mouse.position;
|
||||
|
||||
responses.push_back(Operation::ClearWorkingFolder.into());
|
||||
|
||||
let (point_1, point_2) = if data.drag_start == data.drag_current {
|
||||
let (x, y) = (data.drag_current.x as f64, data.drag_current.y as f64);
|
||||
let (point_1, point_2) = {
|
||||
let (x, y) = (data.drag_start.x as f64, data.drag_start.y as f64);
|
||||
(
|
||||
DVec2::new(x - SELECTION_TOLERANCE, y - SELECTION_TOLERANCE),
|
||||
DVec2::new(x + SELECTION_TOLERANCE, y + SELECTION_TOLERANCE),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
DVec2::new(data.drag_start.x as f64, data.drag_start.y as f64),
|
||||
DVec2::new(data.drag_current.x as f64, data.drag_current.y as f64),
|
||||
)
|
||||
};
|
||||
|
||||
let quad = [
|
||||
|
|
@ -107,21 +88,77 @@ impl Fsm for SelectToolFsmState {
|
|||
DVec2::new(point_1.x, point_2.y),
|
||||
];
|
||||
|
||||
responses.push_back(Operation::DiscardWorkingFolder.into());
|
||||
if data.drag_start == data.drag_current {
|
||||
if let Some(intersection) = document.document.intersects_quad_root(quad).last() {
|
||||
responses.push_back(DocumentMessage::SelectLayers(vec![intersection.clone()]).into());
|
||||
if let Some(intersection) = document.document.intersects_quad_root(quad).last() {
|
||||
// TODO: Replace root transformations with functions of the transform api
|
||||
let transformed_start = document.document.root.transform.inverse().transform_vector2(data.drag_start.as_dvec2());
|
||||
if document.layer_data.get(intersection).map_or(false, |layer_data| layer_data.selected) {
|
||||
data.layers_dragging = document
|
||||
.layer_data
|
||||
.iter()
|
||||
.filter_map(|(path, layer_data)| {
|
||||
layer_data
|
||||
.selected
|
||||
.then(|| (path.clone(), document.document.layer(path).unwrap().transform.translation - transformed_start))
|
||||
})
|
||||
.collect();
|
||||
} else {
|
||||
responses.push_back(DocumentMessage::SelectLayers(vec![]).into());
|
||||
responses.push_back(DocumentMessage::SelectLayers(vec![intersection.clone()]).into());
|
||||
data.layers_dragging = vec![(intersection.clone(), document.document.layer(intersection).unwrap().transform.translation - transformed_start)]
|
||||
}
|
||||
} else {
|
||||
responses.push_back(DocumentMessage::SelectLayers(document.document.intersects_quad_root(quad)).into());
|
||||
responses.push_back(Operation::MountWorkingFolder { path: vec![] }.into());
|
||||
data.layers_dragging = Vec::new();
|
||||
}
|
||||
|
||||
Dragging
|
||||
}
|
||||
(Dragging, MouseMove) => {
|
||||
data.drag_current = input.mouse.position;
|
||||
|
||||
if data.layers_dragging.is_empty() {
|
||||
responses.push_back(Operation::ClearWorkingFolder.into());
|
||||
responses.push_back(make_operation(data, tool_data, transform));
|
||||
} else {
|
||||
for (path, offset) in &data.layers_dragging {
|
||||
responses.push_back(DocumentMessage::DragLayer(path.clone(), offset.clone()).into());
|
||||
}
|
||||
}
|
||||
|
||||
Dragging
|
||||
}
|
||||
(Dragging, DragStop) => {
|
||||
data.drag_current = input.mouse.position;
|
||||
|
||||
if data.layers_dragging.is_empty() {
|
||||
responses.push_back(Operation::ClearWorkingFolder.into());
|
||||
responses.push_back(Operation::DiscardWorkingFolder.into());
|
||||
|
||||
if data.drag_start == data.drag_current {
|
||||
responses.push_back(DocumentMessage::SelectLayers(vec![]).into());
|
||||
} else {
|
||||
let (point_1, point_2) = (
|
||||
DVec2::new(data.drag_start.x as f64, data.drag_start.y as f64),
|
||||
DVec2::new(data.drag_current.x as f64, data.drag_current.y as f64),
|
||||
);
|
||||
|
||||
let quad = [
|
||||
DVec2::new(point_1.x, point_1.y),
|
||||
DVec2::new(point_2.x, point_1.y),
|
||||
DVec2::new(point_2.x, point_2.y),
|
||||
DVec2::new(point_1.x, point_2.y),
|
||||
];
|
||||
|
||||
responses.push_back(DocumentMessage::SelectLayers(document.document.intersects_quad_root(quad)).into());
|
||||
}
|
||||
} else {
|
||||
data.layers_dragging = Vec::new();
|
||||
}
|
||||
|
||||
Ready
|
||||
}
|
||||
(Dragging, Abort) => {
|
||||
responses.push_back(Operation::DiscardWorkingFolder.into());
|
||||
data.layers_dragging = Vec::new();
|
||||
|
||||
Ready
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue