Skip to content
2 changes: 1 addition & 1 deletion editor/src/messages/input_mapper/input_mappings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ pub fn input_mappings() -> Mapping {
entry!(PointerMove; refresh_keys=[Control, Shift], action_dispatch=TransformLayerMessage::PointerMove { slow_key: Shift, increments_key: Control }),
//
// SelectToolMessage
entry!(PointerMove; refresh_keys=[Control, Alt, Shift], action_dispatch=SelectToolMessage::PointerMove { modifier_keys: SelectToolPointerKeys { axis_align: Shift, snap_angle: Shift, center: Alt, duplicate: Alt } }),
entry!(PointerMove; refresh_keys=[Control, Alt, Shift], action_dispatch=SelectToolMessage::PointerMove { modifier_keys: SelectToolPointerKeys { axis_align: Shift, snap_angle: Shift, center: Alt, duplicate: Alt, space_drag: Space } }),
entry!(KeyDown(MouseLeft); action_dispatch=SelectToolMessage::DragStart { extend_selection: Shift, remove_from_selection: Alt, select_deepest: Accel, lasso_select: Control, skew: Control }),
entry!(KeyUp(MouseLeft); action_dispatch=SelectToolMessage::DragStop { remove_from_selection: Alt }),
entry!(KeyDown(Enter); action_dispatch=SelectToolMessage::Enter),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1503,6 +1503,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
snap_angle: Key::Shift,
center: Key::Alt,
duplicate: Key::Alt,
space_drag: Key::Space,
},
});
responses.add(NodeGraphMessage::RunDocumentGraph);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ pub struct NodeGraphMessageHandler {
frontend_nodes: Vec<NodeId>,
/// Used to keep track of what wires are sent to the front end so the old ones can be removed
frontend_wires: HashSet<(NodeId, usize)>,
/// The last mouse position in viewport coordinates when space was pressed
last_mouse_viewport_for_space: Option<DVec2>,
}

/// NodeGraphMessageHandler always modifies the network which the selected nodes are in. No GraphOperationMessages should be added here, since those messages will always affect the document network.
Expand Down Expand Up @@ -1017,6 +1019,21 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
let messages = [NodeGraphMessage::PointerOutsideViewport { shift }.into(), NodeGraphMessage::PointerMove { shift }.into()];
self.auto_panning.setup_by_mouse_position(ipp, viewport, &messages, responses);

if ipp.keyboard.get(Key::Space as usize) {
if let Some(last_mouse) = self.last_mouse_viewport_for_space {
let delta = ipp.mouse.position - last_mouse;
if let Some((box_start, _)) = &mut self.box_selection_start {
let graph_delta = network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.inverse().transform_vector2(delta);
*box_start += graph_delta;
} else {
responses.add(NavigationMessage::CanvasPan { delta });
}
}
self.last_mouse_viewport_for_space = Some(ipp.mouse.position);
} else {
self.last_mouse_viewport_for_space = None;
}

let viewport_location = ipp.mouse.position;
let point = network_metadata
.persistent_metadata
Expand Down Expand Up @@ -2811,6 +2828,7 @@ impl Default for NodeGraphMessageHandler {
end_index: None,
frontend_nodes: Vec::new(),
frontend_wires: HashSet::new(),
last_mouse_viewport_for_space: None,
}
}
}
Expand All @@ -2829,5 +2847,6 @@ impl PartialEq for NodeGraphMessageHandler {
&& self.wire_in_progress_from_connector == other.wire_in_progress_from_connector
&& self.wire_in_progress_to_connector == other.wire_in_progress_to_connector
&& self.context_menu == other.context_menu
&& self.last_mouse_viewport_for_space == other.last_mouse_viewport_for_space
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,35 @@ impl OriginalTransforms {
Some(transform_utils::get_current_transform(&document_node.inputs))
}

pub fn shift(&mut self, delta: DVec2, metadata: &DocumentMetadata) {
match self {
OriginalTransforms::Layer(layer_map) => {
for (&layer, transform) in layer_map {
let to = metadata.downstream_transform_to_viewport(layer);
let layer_delta = to.inverse() * DAffine2::from_translation(delta) * to;
*transform = layer_delta * *transform;
}
}
OriginalTransforms::Path(path_map) => {
for (&layer, points) in path_map {
let to = metadata.transform_to_viewport(layer);
let layer_delta = to.inverse() * DAffine2::from_translation(delta) * to;
for anchor in points.anchors.values_mut() {
anchor.initial = layer_delta.transform_point2(anchor.initial);
anchor.current = layer_delta.transform_point2(anchor.current);
}
for handle in points.handles.values_mut() {
handle.initial = layer_delta.transform_point2(handle.initial);
handle.relative = layer_delta.transform_point2(handle.relative);
if let Some((_, pos)) = &mut handle.mirror {
*pos = layer_delta.transform_point2(*pos);
}
}
}
}
}
}

pub fn update<'a>(&mut self, selected: &'a [LayerNodeIdentifier], network_interface: &NodeNetworkInterface, shape_editor: Option<&'a ShapeState>) {
match self {
OriginalTransforms::Layer(layer_map) => {
Expand Down
23 changes: 23 additions & 0 deletions editor/src/messages/tool/common_functionality/resize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ pub struct Resize {
pub drag_start: DVec2,
pub layer: Option<LayerNodeIdentifier>,
pub snap_manager: SnapManager,

pub last_mouse_viewport_for_space: Option<DVec2>,
pub base_drag_start: DVec2,
}

impl Resize {
Expand All @@ -20,6 +23,8 @@ impl Resize {
let point = SnapCandidatePoint::handle(root_transform.inverse().transform_point2(input.mouse.position));
let snapped = self.snap_manager.free_snap(&SnapData::new(document, input, viewport), &point, SnapTypeConfiguration::default());
self.drag_start = snapped.snapped_point_document;
self.base_drag_start = self.drag_start;
self.last_mouse_viewport_for_space = None;
}

/// Calculate the drag start position in viewport space.
Expand Down Expand Up @@ -119,6 +124,24 @@ impl Resize {
let ignore = if let Some(layer) = self.layer { vec![layer] } else { vec![] };
let snap_data = &SnapData::ignore(document, input, viewport, &ignore);

let space_down = input.keyboard.get(Key::Space as usize);
if space_down {
if self.last_mouse_viewport_for_space.is_none() {
self.last_mouse_viewport_for_space = Some(mouse);
self.base_drag_start = self.drag_start;
}
let total_offset_viewport = mouse - self.last_mouse_viewport_for_space.unwrap();
let total_offset_document = document_to_viewport.inverse().transform_vector2(total_offset_viewport);
self.drag_start = self.base_drag_start + total_offset_document;
} else {
if let Some(initial_mouse) = self.last_mouse_viewport_for_space {
let total_offset_viewport = mouse - initial_mouse;
let total_offset_document = document_to_viewport.inverse().transform_vector2(total_offset_viewport);
self.drag_start = self.base_drag_start + total_offset_document;
}
self.last_mouse_viewport_for_space = None;
}

if lock_ratio {
let viewport_size = points_viewport[1] - points_viewport[0];
let raw_size = if in_document {
Expand Down
18 changes: 18 additions & 0 deletions editor/src/messages/tool/common_functionality/shapes/line_shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,24 @@ impl Line {
shape_tool_data.line_data.drag_current = ipp.mouse.position;

let keyboard = &ipp.keyboard;

let current_mouse = ipp.mouse.position;
let space_down = keyboard.key(Key::Space);

if space_down {
if let Some(previous_mouse) = shape_tool_data.data.last_mouse_viewport_for_space {
let delta_viewport = current_mouse - previous_mouse;
if delta_viewport.length_squared() > 0. {
let document_to_viewport = document.metadata().document_to_viewport;
let delta_document = document_to_viewport.inverse().transform_vector2(delta_viewport);
shape_tool_data.data.drag_start += delta_document;
}
}
shape_tool_data.data.last_mouse_viewport_for_space = Some(current_mouse);
} else {
shape_tool_data.data.last_mouse_viewport_for_space = None;
}

let ignore = [layer];
let snap_data = SnapData::ignore(document, ipp, viewport, &ignore);
let mut document_points = generate_line(shape_tool_data, snap_data, keyboard.key(lock_angle), keyboard.key(snap_angle), keyboard.key(center));
Expand Down
60 changes: 60 additions & 0 deletions editor/src/messages/tool/tool_messages/artboard_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ struct ArtboardToolData {
snap_candidates: Vec<SnapCandidatePoint>,
dragging_current_artboard_location: glam::IVec2,
draw: Resize,
last_mouse_viewport_for_space: Option<DVec2>,
}

impl ArtboardToolData {
Expand Down Expand Up @@ -315,6 +316,32 @@ impl Fsm for ArtboardToolFsmState {
state
}
(ArtboardToolFsmState::ResizingBounds, ArtboardToolMessage::PointerMove { constrain_axis_or_aspect, center }) => {
let current_mouse = input.mouse.position;
let space_down = input.keyboard.get(Key::Space as usize);
if space_down {
if let Some(previous_mouse) = tool_data.last_mouse_viewport_for_space {
let delta_viewport = current_mouse - previous_mouse;
if delta_viewport.length_squared() > 0. {
let document_to_viewport = document.metadata().document_to_viewport;
let delta_document = document_to_viewport.inverse().transform_vector2(delta_viewport);

if let Some(bounds) = &mut tool_data.bounding_box_manager {
bounds.center_of_transformation += delta_viewport;
if let Some(movement) = &mut bounds.selected_edges {
movement.bounds[0] += delta_document;
movement.bounds[1] += delta_document;
}
tool_data.drag_start += delta_document;
}
}
}
tool_data.last_mouse_viewport_for_space = Some(current_mouse);
} else {
tool_data.last_mouse_viewport_for_space = None;
}

// responses.add(OverlaysMessage::Draw);

let from_center = input.keyboard.get(center as usize);
let constrain_square = input.keyboard.get(constrain_axis_or_aspect as usize);
tool_data.resize_artboard(responses, document, input, viewport, from_center, constrain_square);
Expand All @@ -329,6 +356,22 @@ impl Fsm for ArtboardToolFsmState {
ArtboardToolFsmState::ResizingBounds
}
(ArtboardToolFsmState::Dragging, ArtboardToolMessage::PointerMove { constrain_axis_or_aspect, center }) => {
let current_mouse = input.mouse.position;
if input.keyboard.get(Key::Space as usize) {
if let Some(previous_mouse) = tool_data.last_mouse_viewport_for_space {
let delta_viewport = current_mouse - previous_mouse;
if delta_viewport.length_squared() > 0. {
let document_to_viewport = document.metadata().document_to_viewport;
let delta_document = document_to_viewport.inverse().transform_vector2(delta_viewport);
tool_data.drag_start += delta_document;
tool_data.drag_current += delta_document;
}
}
tool_data.last_mouse_viewport_for_space = Some(current_mouse);
} else {
tool_data.last_mouse_viewport_for_space = None;
}

if let Some(bounds) = &mut tool_data.bounding_box_manager {
let axis_align = input.keyboard.get(constrain_axis_or_aspect as usize);

Expand Down Expand Up @@ -368,6 +411,23 @@ impl Fsm for ArtboardToolFsmState {
ArtboardToolFsmState::Dragging
}
(ArtboardToolFsmState::Drawing, ArtboardToolMessage::PointerMove { constrain_axis_or_aspect, center }) => {
let current_mouse = input.mouse.position;

let space_down = input.keyboard.get(Key::Space as usize);
if space_down {
if let Some(previous_mouse) = tool_data.last_mouse_viewport_for_space {
let delta_viewport = current_mouse - previous_mouse;
if delta_viewport.length_squared() > 0. {
let document_to_viewport = document.metadata().document_to_viewport;
let delta_document = document_to_viewport.inverse().transform_vector2(delta_viewport);
tool_data.drag_start += delta_document;
}
}
tool_data.last_mouse_viewport_for_space = Some(current_mouse);
} else {
tool_data.last_mouse_viewport_for_space = None;
}

// The draw.calculate_points_ignore_layer uses this value to avoid snapping to itself.
tool_data.draw.layer = tool_data.selected_artboard;
let [start, end] = tool_data.draw.calculate_points_ignore_layer(document, input, viewport, center, constrain_axis_or_aspect, true);
Expand Down
29 changes: 29 additions & 0 deletions editor/src/messages/tool/tool_messages/freehand_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ struct FreehandToolData {
dragged: bool,
weight: f64,
layer: Option<LayerNodeIdentifier>,
last_mouse_for_space: Option<DVec2>,
points: Vec<(PointId, DVec2)>,
}

impl Fsm for FreehandToolFsmState {
Expand Down Expand Up @@ -253,6 +255,7 @@ impl Fsm for FreehandToolFsmState {
tool_data.dragged = false;
tool_data.end_point = None;
tool_data.weight = tool_options.line_weight;
tool_data.points.clear();

// Extend an endpoint of the selected path
let selected_nodes = document.network_interface.selected_nodes();
Expand Down Expand Up @@ -297,6 +300,31 @@ impl Fsm for FreehandToolFsmState {
FreehandToolFsmState::Drawing
}
(FreehandToolFsmState::Drawing, FreehandToolMessage::PointerMove) => {
let space_down = input.keyboard.get(Key::Space as usize);
if space_down {
if let Some(previous_mouse) = tool_data.last_mouse_for_space {
let delta_viewport = input.mouse.position - previous_mouse;
if delta_viewport.length_squared() > 0. {
let document_to_viewport = document.metadata().document_to_viewport;
let delta_document = document_to_viewport.inverse().transform_vector2(delta_viewport);

if let Some(layer) = tool_data.layer {
if let Some((pos, _)) = &mut tool_data.end_point {
*pos += delta_document;
}
for (id, point) in &mut tool_data.points {
*point += delta_document;
let modification_type = VectorModificationType::ApplyPointDelta { point: *id, delta: delta_document };
responses.add(GraphOperationMessage::Vector { layer, modification_type });
}
}
}
}
tool_data.last_mouse_for_space = Some(input.mouse.position);
} else {
tool_data.last_mouse_for_space = None;
}

if let Some(layer) = tool_data.layer {
let transform = document.metadata().transform_to_viewport(layer);
let position = transform.inverse().transform_point2(input.mouse.position);
Expand Down Expand Up @@ -382,6 +410,7 @@ fn extend_path_with_next_segment(tool_data: &mut FreehandToolData, position: DVe

tool_data.dragged = true;
tool_data.end_point = Some((position, id));
tool_data.points.push((id, position));
}

#[cfg(test)]
Expand Down
Loading