Transformation cage (#502)

* Render corners and edges of selection box

* Refactor

* Add drag detection

* Implement the transform handles

* Implement rotation by dragging <40px from bounds

* Refine clustered handle behaviour

* Add cursors

* Add snap angle

* Fix MMB drag whilst in select tool

* Convert calculate_pivot into a seperate function

* rename start_vec to start_offset

* Fix typo

* Remove Undo transaction on <10px mouse move

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
0HyperCube
2022-02-04 16:46:44 +00:00
committed by Keavon Chambers
co-authored by Keavon Chambers
parent 376f4da480
commit 0a1717cf77
12 changed files with 401 additions and 62 deletions
+9 -9
View File
@@ -93,18 +93,18 @@ impl SnapHandler {
}
}
/// Gets a list of snap targets for the X and Y axes in Viewport coords for the target layers (usually all layers or all non-selected layers.)
/// Gets a list of snap targets for the X and Y axes (if specified) in Viewport coords for the target layers (usually all layers or all non-selected layers.)
/// This should be called at the start of a drag.
pub fn start_snap<'a>(&mut self, document_message_handler: &DocumentMessageHandler, target_layers: impl Iterator<Item = &'a [LayerId]>) {
pub fn start_snap<'a>(&mut self, document_message_handler: &DocumentMessageHandler, target_layers: impl Iterator<Item = &'a [LayerId]>, snap_x: bool, snap_y: bool) {
if document_message_handler.snapping_enabled {
let (x_targets, y_targets) = target_layers
.filter_map(|path| document_message_handler.graphene_document.viewport_bounding_box(path).ok()?)
.flat_map(|[bound1, bound2]| [bound1, bound2, ((bound1 + bound2) / 2.)])
.map(|vec| vec.into())
.unzip();
// Could be made into sorted Vec or a HashSet for more performant lookups.
self.snap_targets = Some(
target_layers
.filter_map(|path| document_message_handler.graphene_document.viewport_bounding_box(path).ok()?)
.flat_map(|[bound1, bound2]| [bound1, bound2, ((bound1 + bound2) / 2.)])
.map(|vec| vec.into())
.unzip(),
);
self.snap_targets = Some((if snap_x { x_targets } else { Vec::new() }, if snap_y { y_targets } else { Vec::new() }));
}
}