Skip to content

Commit bf09d6b

Browse files
committed
Make a bbox and move content according to that
1 parent 68ad92f commit bf09d6b

File tree

3 files changed

+64
-40
lines changed

3 files changed

+64
-40
lines changed

editor/src/messages/portfolio/portfolio_message.rs

+3
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ pub enum PortfolioMessage {
8888
PasteSerializedData {
8989
data: String,
9090
},
91+
CenterPastedLayers {
92+
layers: Vec<LayerNodeIdentifier>,
93+
},
9194
PasteImage {
9295
name: Option<String>,
9396
image: Image<Color>,

editor/src/messages/portfolio/portfolio_message_handler.rs

+60-39
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::messages::debug::utility_types::MessageLoggingVerbosity;
77
use crate::messages::dialog::simple_dialogs;
88
use crate::messages::frontend::utility_types::FrontendDocumentDetails;
99
use crate::messages::layout::utility_types::widget_prelude::*;
10+
use crate::messages::portfolio::document::graph_operation::utility_types::ModifyInputsContext;
1011
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
1112
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_document_node_type;
1213
use crate::messages::portfolio::document::utility_types::clipboards::{Clipboard, CopyBufferEntry, INTERNAL_CLIPBOARD_COUNT};
@@ -19,7 +20,7 @@ use crate::node_graph_executor::{ExportConfig, NodeGraphExecutor};
1920
use graphene_core::renderer::Quad;
2021

2122
use bezier_rs::Subpath;
22-
use glam::IVec2;
23+
use glam::{DAffine2, DVec2, IVec2};
2324
use graph_craft::document::value::TaggedValue;
2425
use graph_craft::document::{DocumentNodeImplementation, NodeId, NodeInput};
2526
use graphene_core::text::{Font, TypesettingConfig};
@@ -890,49 +891,69 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
890891
if let Some(document) = self.active_document() {
891892
if let Ok(data) = serde_json::from_str::<Vec<CopyBufferEntry>>(&data) {
892893
let parent = document.new_layer_parent(false);
893-
let transform = document.metadata().document_to_viewport;
894-
895-
// Check parent bounds first since children will be pasted at same position
896-
if let Some(parent_bounds) = document.metadata().bounding_box_document(parent) {
897-
let viewport_bounds = Quad::from_box_at_zero(ipp.viewport_bounds.size());
898-
let quad = transform * Quad::from_box(parent_bounds);
899-
900-
// Calculate the translation needed to center the parent
901-
let translation = viewport_bounds.center() - quad.center();
902-
let centering_transform = quad
903-
.0
904-
.into_iter()
905-
.all(|point| !viewport_bounds.contains(point))
906-
.then_some(glam::DAffine2::from_translation(translation.round()));
907-
908-
let mut added_nodes = false;
909-
910-
for entry in data.into_iter().rev() {
911-
if !added_nodes {
912-
responses.add(DocumentMessage::DeselectAllLayers);
913-
responses.add(DocumentMessage::AddTransaction);
914-
added_nodes = true;
915-
}
894+
let mut layers = Vec::new();
895+
896+
let mut added_nodes = false;
897+
for entry in data.into_iter().rev() {
898+
if !added_nodes {
899+
responses.add(DocumentMessage::DeselectAllLayers);
900+
responses.add(DocumentMessage::AddTransaction);
901+
added_nodes = true;
902+
}
903+
904+
document.load_layer_resources(responses);
905+
let new_ids: HashMap<_, _> = entry.nodes.iter().map(|(id, _)| (*id, NodeId::new())).collect();
906+
let layer = LayerNodeIdentifier::new_unchecked(new_ids[&NodeId(0)]);
907+
responses.add(NodeGraphMessage::AddNodes { nodes: entry.nodes, new_ids });
908+
responses.add(NodeGraphMessage::MoveLayerToStack { layer, parent, insert_index: 0 });
909+
layers.push(layer);
910+
}
916911

917-
document.load_layer_resources(responses);
918-
let new_ids: HashMap<_, _> = entry.nodes.iter().map(|(id, _)| (*id, NodeId::new())).collect();
919-
let layer = LayerNodeIdentifier::new_unchecked(new_ids[&NodeId(0)]);
920-
responses.add(NodeGraphMessage::AddNodes { nodes: entry.nodes, new_ids });
921-
responses.add(NodeGraphMessage::MoveLayerToStack { layer, parent, insert_index: 0 });
922-
923-
// Apply the same translation to all layers
924-
if let Some(transform) = centering_transform {
925-
responses.add(GraphOperationMessage::TransformChange {
926-
layer,
927-
transform,
928-
transform_in: TransformIn::Viewport,
929-
skip_rerender: false,
930-
});
912+
responses.add(NodeGraphMessage::RunDocumentGraph);
913+
responses.add(PortfolioMessage::CenterPastedLayers { layers });
914+
}
915+
}
916+
}
917+
PortfolioMessage::CenterPastedLayers { layers } => {
918+
use crate::messages::portfolio::document::graph_operation::transform_utils;
919+
if let Some(document) = self.active_document_mut() {
920+
let viewport_bounds = Quad::from_box_at_zero(ipp.viewport_bounds.size());
921+
let viewport_center = viewport_bounds.center();
922+
923+
let mut positions = Vec::new();
924+
925+
for layer in &layers {
926+
if let Some(mut modify_inputs) = ModifyInputsContext::new_with_layer(*layer, &mut document.network_interface, responses) {
927+
if let Some(transform_node_id) = modify_inputs.existing_node_id("Transform", true) {
928+
if let Some(network) = modify_inputs.network_interface.network(&[]) {
929+
if let Some(node) = network.nodes.get(&transform_node_id) {
930+
let current_transform = transform_utils::get_current_transform(&node.inputs);
931+
positions.push((*layer, current_transform.translation));
932+
}
931933
}
932934
}
933-
responses.add(NodeGraphMessage::RunDocumentGraph);
934935
}
935936
}
937+
938+
if !positions.is_empty() {
939+
let mean_pos = positions.iter().fold(glam::DVec2::ZERO, |acc, (_, pos)| acc + *pos) / positions.len() as f64;
940+
let mut transform = document.metadata().document_to_viewport;
941+
942+
// Center each layer maintaining relative positions
943+
for (layer, pos) in positions {
944+
let offset_from_center = pos - mean_pos;
945+
let new_pos = viewport_center + transform.transform_vector2(offset_from_center);
946+
transform.translation = new_pos;
947+
948+
responses.add(GraphOperationMessage::TransformSet {
949+
layer,
950+
transform,
951+
transform_in: TransformIn::Viewport,
952+
skip_rerender: false,
953+
});
954+
}
955+
responses.add(NodeGraphMessage::RunDocumentGraph);
956+
}
936957
}
937958
}
938959
PortfolioMessage::PasteImage {

node-graph/gcore/src/graphic_element/renderer/quad.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ impl Quad {
3939
}
4040

4141
/// Create a box starting at (0, 0) upto [`point`]
42-
pub fn from_box_at_zero(point: DVec2) -> Self{
42+
pub fn from_box_at_zero(point: DVec2) -> Self {
4343
Self::from_box([DVec2::ZERO, point])
4444
}
4545

0 commit comments

Comments
 (0)