Implement the Crop Tool for artboard resizing (#519)

* Extract transformation cage to a seperate file

* Hook up tool

* Implement resize

* Draw artboards

* centre and constrain

* Bounding box is rotated

* Fix transform handle positions for artboard

* Drag layers

* Snapping

* Fix imports

* Cleanup

* Remove allocation from bounding_boxes

* Round artboard size and position

* Hints

* Fix rotated transform cage

* Code review changes

* Hints changes

Co-authored-by: Dennis <dennis@kobert.dev>
Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
0HyperCube
2022-02-09 23:22:23 +00:00
committed by Keavon Chambers
parent 29485001e9
commit 45edeb2a2b
29 changed files with 817 additions and 340 deletions

View File

@@ -42,7 +42,7 @@ pub struct DocumentMessageHandler {
movement_handler: MovementMessageHandler,
#[serde(skip)]
overlays_message_handler: OverlaysMessageHandler,
artboard_message_handler: ArtboardMessageHandler,
pub artboard_message_handler: ArtboardMessageHandler,
#[serde(skip)]
transform_layer_handler: TransformLayerMessageHandler,
pub overlays_visible: bool,
@@ -138,6 +138,10 @@ impl DocumentMessageHandler {
self.graphene_document.combined_viewport_bounding_box(paths)
}
pub fn artboard_bounding_box_and_transform(&self, path: &[LayerId]) -> Option<([DVec2; 2], DAffine2)> {
self.artboard_message_handler.artboards_graphene_document.bounding_box_and_transform(path).unwrap_or(None)
}
/// Create a new vector shape representation with the underlying kurbo data, VectorManipulatorShape
pub fn selected_visible_layers_vector_shapes(&self, responses: &mut VecDeque<Message>) -> Vec<VectorShape> {
let shapes = self.selected_layers().filter_map(|path_to_shape| {
@@ -203,6 +207,20 @@ impl DocumentMessageHandler {
})
}
/// Returns the bounding boxes for all visible layers and artboards, optionally excluding any paths.
pub fn bounding_boxes<'a>(&'a self, ignore_document: Option<&'a Vec<Vec<LayerId>>>, ignore_artboard: Option<LayerId>) -> impl Iterator<Item = [DVec2; 2]> + 'a {
self.visible_layers()
.filter(move |path| ignore_document.map_or(true, |ignore_document| !ignore_document.iter().any(|ig| ig.as_slice() == *path)))
.filter_map(|path| self.graphene_document.viewport_bounding_box(path).ok()?)
.chain(
self.artboard_message_handler
.artboard_ids
.iter()
.filter(move |&&id| Some(id) != ignore_artboard)
.filter_map(|&path| self.artboard_message_handler.artboards_graphene_document.viewport_bounding_box(&[path]).ok()?),
)
}
fn serialize_structure(&self, folder: &Folder, structure: &mut Vec<u64>, data: &mut Vec<LayerId>, path: &mut Vec<LayerId>) {
let mut space = 0;
for (id, layer) in folder.layer_ids.iter().zip(folder.layers()).rev() {