mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-02 06:28:11 +08:00
Fix transformation cage centered-scaling to use the center as its pivot (#769)
* Add centre of transformation * Add alt support * New breaking file format version * Spelling Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
a6bdabcbaa
commit
440a9a6dd6
@@ -176,7 +176,8 @@ impl Fsm for ArtboardToolFsmState {
|
||||
|
||||
bounding_box.selected_edges = edges.map(|(top, bottom, left, right)| {
|
||||
let edges = SelectedEdges::new(top, bottom, left, right, bounding_box.bounds);
|
||||
bounding_box.pivot = edges.calculate_pivot();
|
||||
bounding_box.opposite_pivot = edges.calculate_pivot();
|
||||
|
||||
edges
|
||||
});
|
||||
|
||||
@@ -189,11 +190,17 @@ impl Fsm for ArtboardToolFsmState {
|
||||
let snap_x = selected_edges.2 || selected_edges.3;
|
||||
let snap_y = selected_edges.0 || selected_edges.1;
|
||||
|
||||
tool_data
|
||||
.snap_manager
|
||||
.start_snap(document, document.bounding_boxes(None, Some(tool_data.selected_board.unwrap()), font_cache), snap_x, snap_y);
|
||||
let board = tool_data.selected_board.unwrap();
|
||||
tool_data.snap_manager.start_snap(document, document.bounding_boxes(None, Some(board), font_cache), snap_x, snap_y);
|
||||
tool_data.snap_manager.add_all_document_handles(document, &[], &[], &[]);
|
||||
|
||||
if let Some(bounds) = &mut tool_data.bounding_box_overlays {
|
||||
let pivot = document.artboard_message_handler.artboards_graphene_document.pivot(&[board], font_cache).unwrap_or_default();
|
||||
let root = document.graphene_document.root.transform;
|
||||
let pivot = root.inverse().transform_point2(pivot);
|
||||
bounds.center_of_transformation = pivot;
|
||||
}
|
||||
|
||||
ArtboardToolFsmState::ResizingBounds
|
||||
} else {
|
||||
let tolerance = DVec2::splat(SELECTION_TOLERANCE);
|
||||
@@ -249,11 +256,7 @@ impl Fsm for ArtboardToolFsmState {
|
||||
let mouse_position = input.mouse.position;
|
||||
let snapped_mouse_position = tool_data.snap_manager.snap_position(responses, document, mouse_position);
|
||||
|
||||
let (mut position, size) = movement.new_size(snapped_mouse_position, bounds.transform, from_center, constrain_square);
|
||||
if from_center {
|
||||
position = movement.center_position(position, size);
|
||||
}
|
||||
|
||||
let (position, size) = movement.new_size(snapped_mouse_position, bounds.transform, from_center, bounds.center_of_transformation, constrain_square);
|
||||
responses.push_back(
|
||||
ArtboardMessage::ResizeArtboard {
|
||||
artboard: tool_data.selected_board.unwrap(),
|
||||
|
||||
@@ -418,7 +418,7 @@ impl Fsm for SelectToolFsmState {
|
||||
|
||||
bounding_box.selected_edges = edges.map(|(top, bottom, left, right)| {
|
||||
let edges = SelectedEdges::new(top, bottom, left, right, bounding_box.bounds);
|
||||
bounding_box.pivot = edges.calculate_pivot();
|
||||
bounding_box.opposite_pivot = edges.calculate_pivot();
|
||||
edges
|
||||
});
|
||||
|
||||
@@ -452,13 +452,21 @@ impl Fsm for SelectToolFsmState {
|
||||
|
||||
tool_data.layers_dragging = selected;
|
||||
|
||||
if let Some(bounds) = &mut tool_data.bounding_box_overlays {
|
||||
let document = &document.graphene_document;
|
||||
|
||||
let selected = &tool_data.layers_dragging.iter().collect::<Vec<_>>();
|
||||
let mut selected = Selected::new(&mut bounds.original_transforms, &mut bounds.center_of_transformation, selected, responses, document);
|
||||
bounds.center_of_transformation = selected.mean_average_of_pivots(font_cache);
|
||||
}
|
||||
|
||||
ResizingBounds
|
||||
} else if rotating_bounds {
|
||||
if let Some(bounds) = &mut tool_data.bounding_box_overlays {
|
||||
let selected = selected.iter().collect::<Vec<_>>();
|
||||
let mut selected = Selected::new(&mut bounds.original_transforms, &mut bounds.pivot, &selected, responses, &document.graphene_document);
|
||||
let mut selected = Selected::new(&mut bounds.original_transforms, &mut bounds.center_of_transformation, &selected, responses, &document.graphene_document);
|
||||
|
||||
*selected.pivot = selected.calculate_pivot(font_cache);
|
||||
bounds.center_of_transformation = selected.mean_average_of_pivots(font_cache);
|
||||
}
|
||||
|
||||
tool_data.layers_dragging = selected;
|
||||
@@ -543,11 +551,12 @@ impl Fsm for SelectToolFsmState {
|
||||
|
||||
let snapped_mouse_position = tool_data.snap_manager.snap_position(responses, document, mouse_position);
|
||||
|
||||
let (_, size) = movement.new_size(snapped_mouse_position, bounds.transform, center, axis_align);
|
||||
let delta = movement.bounds_to_scale_transform(center, size);
|
||||
let (_, size) = movement.new_size(snapped_mouse_position, bounds.transform, center, bounds.center_of_transformation, axis_align);
|
||||
let delta = movement.bounds_to_scale_transform(size);
|
||||
|
||||
let selected = tool_data.layers_dragging.iter().collect::<Vec<_>>();
|
||||
let mut selected = Selected::new(&mut bounds.original_transforms, &mut bounds.pivot, &selected, responses, &document.graphene_document);
|
||||
let selected = &tool_data.layers_dragging.iter().collect::<Vec<_>>();
|
||||
let pivot = if center { &mut bounds.center_of_transformation } else { &mut bounds.opposite_pivot };
|
||||
let mut selected = Selected::new(&mut bounds.original_transforms, pivot, selected, responses, &document.graphene_document);
|
||||
|
||||
selected.update_transforms(delta);
|
||||
}
|
||||
@@ -557,8 +566,8 @@ impl Fsm for SelectToolFsmState {
|
||||
(RotatingBounds, PointerMove { snap_angle, .. }) => {
|
||||
if let Some(bounds) = &mut tool_data.bounding_box_overlays {
|
||||
let angle = {
|
||||
let start_offset = tool_data.drag_start - bounds.pivot;
|
||||
let end_offset = input.mouse.position - bounds.pivot;
|
||||
let start_offset = tool_data.drag_start - bounds.center_of_transformation;
|
||||
let end_offset = input.mouse.position - bounds.center_of_transformation;
|
||||
|
||||
start_offset.angle_between(end_offset)
|
||||
};
|
||||
@@ -573,7 +582,7 @@ impl Fsm for SelectToolFsmState {
|
||||
let delta = DAffine2::from_angle(snapped_angle);
|
||||
|
||||
let selected = tool_data.layers_dragging.iter().collect::<Vec<_>>();
|
||||
let mut selected = Selected::new(&mut bounds.original_transforms, &mut bounds.pivot, &selected, responses, &document.graphene_document);
|
||||
let mut selected = Selected::new(&mut bounds.original_transforms, &mut bounds.center_of_transformation, &selected, responses, &document.graphene_document);
|
||||
|
||||
selected.update_transforms(delta);
|
||||
}
|
||||
@@ -672,7 +681,7 @@ impl Fsm for SelectToolFsmState {
|
||||
let selected = tool_data.layers_dragging.iter().collect::<Vec<_>>();
|
||||
let mut selected = Selected::new(
|
||||
&mut bounding_box_overlays.original_transforms,
|
||||
&mut bounding_box_overlays.pivot,
|
||||
&mut bounding_box_overlays.opposite_pivot,
|
||||
&selected,
|
||||
responses,
|
||||
&document.graphene_document,
|
||||
@@ -865,7 +874,7 @@ impl SelectToolData {
|
||||
|
||||
// Duplicate each previously selected layer and select the new ones.
|
||||
for layer_path in Document::shallowest_unique_layers(self.layers_dragging.iter_mut()) {
|
||||
// Moves the origional back to its starting position.
|
||||
// Moves the original back to its starting position.
|
||||
responses.push_front(
|
||||
Operation::TransformLayerInViewport {
|
||||
path: layer_path.clone(),
|
||||
@@ -875,7 +884,7 @@ impl SelectToolData {
|
||||
);
|
||||
|
||||
// Copy the layers.
|
||||
// Not using the Copy message allows us to retrieve the ids of the new layers to initalise the drag.
|
||||
// Not using the Copy message allows us to retrieve the ids of the new layers to initialize the drag.
|
||||
let layer = match document.graphene_document.layer(layer_path) {
|
||||
Ok(layer) => layer.clone(),
|
||||
Err(e) => {
|
||||
@@ -907,7 +916,7 @@ impl SelectToolData {
|
||||
|
||||
/// Removes the duplicated layers. Called when alt is released and the layers have been duplicated.
|
||||
fn stop_duplicates(&mut self, responses: &mut VecDeque<Message>) {
|
||||
let origionals = match self.not_duplicated_layers.take() {
|
||||
let originals = match self.not_duplicated_layers.take() {
|
||||
Some(x) => x,
|
||||
None => return,
|
||||
};
|
||||
@@ -919,8 +928,8 @@ impl SelectToolData {
|
||||
responses.push_back(Operation::DeleteLayer { path: layer_path.clone() }.into());
|
||||
}
|
||||
|
||||
// Move the origional to under the mouse
|
||||
for layer_path in Document::shallowest_unique_layers(origionals.iter()) {
|
||||
// Move the original to under the mouse
|
||||
for layer_path in Document::shallowest_unique_layers(originals.iter()) {
|
||||
responses.push_front(
|
||||
Operation::TransformLayerInViewport {
|
||||
path: layer_path.clone(),
|
||||
@@ -930,14 +939,14 @@ impl SelectToolData {
|
||||
);
|
||||
}
|
||||
|
||||
// Select the origionals
|
||||
// Select the originals
|
||||
responses.push_back(
|
||||
DocumentMessage::SetSelectedLayers {
|
||||
replacement_selected_layers: origionals.clone(),
|
||||
replacement_selected_layers: originals.clone(),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
self.layers_dragging = origionals;
|
||||
self.layers_dragging = originals;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user