Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,8 @@ impl<'a> Selected<'a> {
tool_type: &'a ToolType,
pen_handle: Option<&'a mut DVec2>,
) -> Self {
// If user is using the Select tool or Shape tool then use the original layer transforms
if (*tool_type == ToolType::Select || *tool_type == ToolType::Shape) && (*original_transforms == OriginalTransforms::Path(HashMap::new())) {
// For Select, Shape, and Artboard tools, switch to layer-based transforms if currently initialized as empty path transforms
if (*tool_type == ToolType::Select || *tool_type == ToolType::Shape || *tool_type == ToolType::Artboard) && (*original_transforms == OriginalTransforms::Path(HashMap::new())) {
*original_transforms = OriginalTransforms::Layer(HashMap::new());
}

Expand Down Expand Up @@ -630,6 +630,10 @@ impl<'a> Selected<'a> {

// TODO: Cache the result of `shallowest_unique_layers` to avoid this heavy computation every frame of movement, see https://github.com/GraphiteEditor/Graphite/pull/481
for layer in self.network_interface.shallowest_unique_layers(&[]) {
// Skip artboard layers when using the Artboard tool to prevent accidental transformations
if *self.tool_type == ToolType::Artboard && self.network_interface.is_artboard(&layer.to_node(), &[]) {
continue;
}
Comment thread
atchamwa marked this conversation as resolved.
match &mut self.original_transforms {
OriginalTransforms::Layer(layer_transforms) => Self::transform_layer(self.network_interface.document_metadata(), layer, layer_transforms.get(&layer), transformation, self.responses),
OriginalTransforms::Path(path_transforms) => {
Expand Down
1 change: 1 addition & 0 deletions editor/src/messages/tool/tool_messages/artboard_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@ impl Fsm for ArtboardToolFsmState {
HintGroup(vec![HintInfo::mouse(MouseMotion::LmbDrag, "Draw Artboard")]),
HintGroup(vec![HintInfo::mouse(MouseMotion::LmbDrag, "Move Artboard")]),
HintGroup(vec![HintInfo::keys([Key::Backspace], "Delete Artboard")]),
HintGroup(vec![HintInfo::multi_keys([[Key::KeyG], [Key::KeyS]], "Grab/Scale Selected")]),
]),
ArtboardToolFsmState::Dragging => HintData(vec![
HintGroup(vec![HintInfo::mouse(MouseMotion::Rmb, ""), HintInfo::keys([Key::Escape], "Cancel").prepend_slash()]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::messages::tool::common_functionality::shape_editor::ShapeState;
use crate::messages::tool::tool_messages::select_tool;
use crate::messages::tool::tool_messages::tool_prelude::Key;
use crate::messages::tool::utility_types::{ToolData, ToolType};
use glam::{DAffine2, DVec2};
use glam::{DAffine2, DVec2, IVec2};
use graphene_std::renderer::Quad;
use graphene_std::vector::click_target::ClickTargetType;
use graphene_std::vector::misc::ManipulatorPointId;
Expand Down Expand Up @@ -94,6 +94,8 @@ pub struct TransformLayerMessageHandler {

// Path tool (ghost outlines showing pre-transform geometry)
ghost_outline: Vec<(Vec<ClickTargetType>, DAffine2)>,

original_artboard_bounds: HashMap<LayerNodeIdentifier, [DVec2; 2]>,
}

#[message_handler_data]
Expand All @@ -111,15 +113,21 @@ impl MessageHandler<TransformLayerMessage, TransformLayerMessageContext<'_>> for
let using_select_tool = tool_data.active_tool_type == ToolType::Select;
let using_pen_tool = tool_data.active_tool_type == ToolType::Pen;
let using_shape_tool = tool_data.active_tool_type == ToolType::Shape;
let using_artboard_tool = tool_data.active_tool_type == ToolType::Artboard;

// TODO: Add support for transforming layer not in the document network
let selected_layers = document
let mut selected_layers = document
.network_interface
.selected_nodes()
.selected_layers(document.metadata())
.filter(|&layer| document.network_interface.is_visible(&layer.to_node(), &[]) && !document.network_interface.is_locked(&layer.to_node(), &[]))
.collect::<Vec<_>>();

// Ensure only artboard layers are transformed when using the Artboard tool
if using_artboard_tool {
selected_layers.retain(|layer| document.network_interface.is_artboard(&layer.to_node(), &[]));
}

let mut selected = Selected::new(
&mut self.original_transforms,
&mut self.pivot,
Expand Down Expand Up @@ -312,6 +320,7 @@ impl MessageHandler<TransformLayerMessage, TransformLayerMessageContext<'_>> for
if final_transform {
self.transform_operation = TransformOperation::None;
self.operation_count = 0;
self.original_artboard_bounds.clear();
}

if using_pen_tool {
Expand Down Expand Up @@ -390,13 +399,32 @@ impl MessageHandler<TransformLayerMessage, TransformLayerMessageContext<'_>> for
});
}
TransformLayerMessage::BeginGRS { operation: transform_type } => {
// Artboards don't support rotation yet
if using_artboard_tool && transform_type == TransformType::Rotate {
return;
}
if using_artboard_tool && selected_layers.is_empty() {
return;
}
// Prepare artboard bounds
if using_artboard_tool {
self.original_artboard_bounds.clear();
for &layer in &selected_layers {
if !document.network_interface.is_artboard(&layer.to_node(), &[]) {
continue;
}
if let Some(bounds) = document.metadata().bounding_box_document(layer) {
self.original_artboard_bounds.insert(layer, bounds);
}
}
}
Comment thread
atchamwa marked this conversation as resolved.
let selected_points: Vec<&ManipulatorPointId> = shape_editor.selected_points().collect();
let selected_segments = shape_editor.selected_segments().collect::<Vec<_>>();

if using_path_tool {
Self::set_ghost_outline(&mut self.ghost_outline, shape_editor, document);
if (selected_points.is_empty() && selected_segments.is_empty())
|| (!using_path_tool && !using_select_tool && !using_pen_tool && !using_shape_tool)
|| (!using_path_tool && !using_select_tool && !using_pen_tool && !using_shape_tool && !using_artboard_tool)
|| selected_layers.is_empty()
|| (transform_type.equivalent_to(self.transform_operation) && !self.was_grabbing)
{
Expand Down Expand Up @@ -497,6 +525,7 @@ impl MessageHandler<TransformLayerMessage, TransformLayerMessageContext<'_>> for
responses.add(ToolMessage::UpdateHints);
} else {
selected.original_transforms.clear();
self.original_artboard_bounds.clear();
self.typing.clear();
self.transform_operation = TransformOperation::None;

Expand Down Expand Up @@ -580,6 +609,30 @@ impl MessageHandler<TransformLayerMessage, TransformLayerMessageContext<'_>> for
};
}

if using_artboard_tool && !self.original_artboard_bounds.is_empty() && self.transform_operation != TransformOperation::None {
// Compute the full transform
let inner = match self.transform_operation {
TransformOperation::Grabbing(translation) => DAffine2::from_translation(translation.to_dvec(&self.state, document)),
TransformOperation::Scaling(scale) => DAffine2::from_scale(scale.to_dvec(self.state.is_rounded_to_intervals)),
_ => DAffine2::IDENTITY,
};
let normalized_transform = self.state.local_to_viewport_transform();
let local_viewport_transform = normalized_transform * inner * normalized_transform.inverse();
let pivot_translation = DAffine2::from_translation(self.state.pivot_viewport(document));
let viewport_transform = pivot_translation * local_viewport_transform * pivot_translation.inverse();
let document_to_viewport = document.metadata().document_to_viewport;
let document_transform = document_to_viewport.inverse() * viewport_transform * document_to_viewport;

// Resize artboards based on transformed bounds
for (&layer, &original_bounds) in &self.original_artboard_bounds {
let new_top_left = document_transform.transform_point2(original_bounds[0]);
let new_bottom_right = document_transform.transform_point2(original_bounds[1]);
let location = new_top_left.min(new_bottom_right).round().as_ivec2();
let dimensions = (new_bottom_right - new_top_left).abs().round().as_ivec2().max(IVec2::ONE);
responses.add(GraphOperationMessage::ResizeArtboard { layer, location, dimensions });
}
}

self.mouse_position = input.mouse.position;
}
TransformLayerMessage::SelectionChanged => {
Expand Down