mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 16:38:13 +08:00
fixes
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
use super::node_properties;
|
use super::node_properties;
|
||||||
use super::utility_types::{BoxSelection, ContextMenuInformation, DragStart, FrontendNode};
|
use super::utility_types::{BoxSelection, ContextMenuInformation, FrontendNode};
|
||||||
use crate::consts::GRID_SIZE;
|
use crate::consts::GRID_SIZE;
|
||||||
use crate::messages::clipboard::utility_types::ClipboardContent;
|
use crate::messages::clipboard::utility_types::ClipboardContent;
|
||||||
use crate::messages::input_mapper::utility_types::macros::{action_shortcut, action_shortcut_manual};
|
use crate::messages::input_mapper::utility_types::macros::{action_shortcut, action_shortcut_manual};
|
||||||
@@ -56,11 +56,10 @@ pub struct NodeGraphMessageHandler {
|
|||||||
pub network: Vec<NodeId>,
|
pub network: Vec<NodeId>,
|
||||||
has_selection: bool,
|
has_selection: bool,
|
||||||
widgets: [LayoutGroup; 2],
|
widgets: [LayoutGroup; 2],
|
||||||
|
/// This stores the coordinate of the click relative to the top left selected node.
|
||||||
|
pub drag_start: Option<DVec2>,
|
||||||
/// Used to add a transaction for the first node move when dragging.
|
/// Used to add a transaction for the first node move when dragging.
|
||||||
/// Used to prevent entering a nested network if the node is dragged after double clicking
|
pub node_has_moved_in_drag: bool,
|
||||||
node_has_moved_in_drag: bool,
|
|
||||||
/// See DragStart for notes
|
|
||||||
pub drag_start: Option<DragStart>,
|
|
||||||
// Store the selected chain nodes on drag start so they can be reconnected if shaken
|
// Store the selected chain nodes on drag start so they can be reconnected if shaken
|
||||||
pub drag_start_chain_nodes: Vec<NodeId>,
|
pub drag_start_chain_nodes: Vec<NodeId>,
|
||||||
/// If dragging the background to create a box selection, this stores its starting point in node graph coordinates,
|
/// If dragging the background to create a box selection, this stores its starting point in node graph coordinates,
|
||||||
@@ -936,6 +935,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let mut updated_selected = selected_nodes.selected_nodes().cloned().collect::<Vec<_>>();
|
let mut updated_selected = selected_nodes.selected_nodes().cloned().collect::<Vec<_>>();
|
||||||
|
log::debug!("updated_selected: {:?}", updated_selected);
|
||||||
let mut modified_selected = false;
|
let mut modified_selected = false;
|
||||||
|
|
||||||
// Add to/remove from selection if holding Shift or Ctrl
|
// Add to/remove from selection if holding Shift or Ctrl
|
||||||
@@ -963,9 +963,12 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
|
|||||||
|
|
||||||
// If this node is selected (whether from before or just now), prepare it for dragging
|
// If this node is selected (whether from before or just now), prepare it for dragging
|
||||||
if updated_selected.contains(&clicked_id) {
|
if updated_selected.contains(&clicked_id) {
|
||||||
if let Some(selected_top_left) = network_interface.selected_nodes_bounding_box(breadcrumb_network_path) {
|
let Some(selected_top_left) = network_interface.nodes_bounding_box(&updated_selected, selection_network_path) else {
|
||||||
self.drag_start = Some(DragStart::new(node_graph_point - selected_top_left[0]));
|
log::error!("Could not get selected nodes bounding box in PointerDown");
|
||||||
|
return;
|
||||||
};
|
};
|
||||||
|
self.drag_start = Some(node_graph_point - selected_top_left[0]);
|
||||||
|
self.node_has_moved_in_drag = false;
|
||||||
let selected_chain_nodes = updated_selected
|
let selected_chain_nodes = updated_selected
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|node_id| network_interface.is_chain(node_id, selection_network_path))
|
.filter(|node_id| network_interface.is_chain(node_id, selection_network_path))
|
||||||
@@ -980,7 +983,6 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
|
|||||||
.filter(|node_id| network_interface.is_chain(node_id, selection_network_path))
|
.filter(|node_id| network_interface.is_chain(node_id, selection_network_path))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
self.node_has_moved_in_drag = false;
|
|
||||||
self.update_node_graph_hints(responses);
|
self.update_node_graph_hints(responses);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1099,8 +1101,8 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
|
|||||||
}
|
}
|
||||||
} else if let Some(drag_start) = &mut self.drag_start {
|
} else if let Some(drag_start) = &mut self.drag_start {
|
||||||
let moved = sync_selected_node_position_with_mouse(network_interface, breadcrumb_network_path, drag_start, point, responses);
|
let moved = sync_selected_node_position_with_mouse(network_interface, breadcrumb_network_path, drag_start, point, responses);
|
||||||
if !drag_start.dragged && moved {
|
if !self.node_has_moved_in_drag && moved {
|
||||||
drag_start.dragged = true;
|
self.node_has_moved_in_drag = true;
|
||||||
if ipp.keyboard.get(Key::Alt as usize) {
|
if ipp.keyboard.get(Key::Alt as usize) {
|
||||||
responses.add(NodeGraphMessage::DuplicateSelectedNodes);
|
responses.add(NodeGraphMessage::DuplicateSelectedNodes);
|
||||||
// Duplicating sets a 2x2 offset, so shift the nodes back to the original position
|
// Duplicating sets a 2x2 offset, so shift the nodes back to the original position
|
||||||
@@ -1179,7 +1181,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
|
|||||||
self.preview_on_mouse_up = None;
|
self.preview_on_mouse_up = None;
|
||||||
}
|
}
|
||||||
if let Some(node_to_deselect) = self.deselect_on_pointer_up.take()
|
if let Some(node_to_deselect) = self.deselect_on_pointer_up.take()
|
||||||
&& self.drag_start.as_ref().is_some_and(|start| !start.dragged)
|
&& self.node_has_moved_in_drag
|
||||||
{
|
{
|
||||||
let mut new_selected_nodes = selected_nodes.selected_nodes_ref().clone();
|
let mut new_selected_nodes = selected_nodes.selected_nodes_ref().clone();
|
||||||
new_selected_nodes.remove(node_to_deselect);
|
new_selected_nodes.remove(node_to_deselect);
|
||||||
@@ -1243,7 +1245,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// End of dragging a node
|
// End of dragging a node
|
||||||
else if let Some(drag_start) = &self.drag_start {
|
else if self.drag_start.is_some() {
|
||||||
self.shift_without_push = false;
|
self.shift_without_push = false;
|
||||||
|
|
||||||
// Reset all offsets to end the rubber banding while dragging
|
// Reset all offsets to end the rubber banding while dragging
|
||||||
@@ -1254,16 +1256,15 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Only select clicked node if multiple are selected and they were not dragged
|
// Only select clicked node if multiple are selected and they were not dragged
|
||||||
if let Some(select_if_not_dragged) = self.select_if_not_dragged {
|
if let Some(select_if_not_dragged) = self.select_if_not_dragged
|
||||||
if !drag_start.dragged
|
&& !self.node_has_moved_in_drag
|
||||||
&& (selected_nodes.selected_nodes_ref().len() != 1
|
&& (selected_nodes.selected_nodes_ref().len() != 1
|
||||||
|| selected_nodes
|
|| selected_nodes
|
||||||
.selected_nodes_ref()
|
.selected_nodes_ref()
|
||||||
.first()
|
.first()
|
||||||
.is_some_and(|first_selected_node| *first_selected_node != select_if_not_dragged))
|
.is_some_and(|first_selected_node| *first_selected_node != select_if_not_dragged))
|
||||||
{
|
{
|
||||||
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![select_if_not_dragged] })
|
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![select_if_not_dragged] })
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try expand the upstream chain for all layers if there is an eligible node
|
// Try expand the upstream chain for all layers if there is an eligible node
|
||||||
@@ -1284,7 +1285,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
// Check if a single node was dragged onto a wire and that the node was dragged onto the wire
|
// Check if a single node was dragged onto a wire and that the node was dragged onto the wire
|
||||||
if selected_nodes.selected_nodes_ref().len() == 1 && self.drag_start.as_ref().is_some_and(|drag_start| drag_start.dragged) {
|
if selected_nodes.selected_nodes_ref().len() == 1 && self.node_has_moved_in_drag {
|
||||||
let selected_node_id = selected_nodes.selected_nodes_ref()[0];
|
let selected_node_id = selected_nodes.selected_nodes_ref()[0];
|
||||||
let has_primary_output_connection = network_interface
|
let has_primary_output_connection = network_interface
|
||||||
.outward_wires(selection_network_path)
|
.outward_wires(selection_network_path)
|
||||||
@@ -2728,8 +2729,8 @@ impl NodeGraphMessageHandler {
|
|||||||
// A wire is in progress and its start and end connectors are set
|
// A wire is in progress and its start and end connectors are set
|
||||||
let wiring = self.wire_in_progress_from_connector.is_some();
|
let wiring = self.wire_in_progress_from_connector.is_some();
|
||||||
|
|
||||||
// Node dragging is in progress (having already moved at least one pixel from the mouse down position)
|
// Node dragging is in progress (having already moved one grid space)
|
||||||
let dragging_nodes = self.drag_start.as_ref().is_some_and(|drag_start| drag_start.dragged);
|
let dragging_nodes = self.node_has_moved_in_drag;
|
||||||
|
|
||||||
// A box selection is in progress
|
// A box selection is in progress
|
||||||
let dragging_box_selection = self.box_selection_start.is_some_and(|(_, box_selection_dragged)| box_selection_dragged);
|
let dragging_box_selection = self.box_selection_start.is_some_and(|(_, box_selection_dragged)| box_selection_dragged);
|
||||||
@@ -2820,19 +2821,19 @@ impl PartialEq for NodeGraphMessageHandler {
|
|||||||
fn sync_selected_node_position_with_mouse(
|
fn sync_selected_node_position_with_mouse(
|
||||||
network_interface: &mut NodeNetworkInterface,
|
network_interface: &mut NodeNetworkInterface,
|
||||||
breadcrumb_network_path: &[NodeId],
|
breadcrumb_network_path: &[NodeId],
|
||||||
drag_start: &DragStart,
|
drag_start: &DVec2,
|
||||||
mouse_position_node_graph_space: DVec2,
|
mouse_position_node_graph_space: DVec2,
|
||||||
responses: &mut VecDeque<Message>,
|
responses: &mut VecDeque<Message>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let Some(selected_nodes_bbox) = network_interface.selected_nodes_bounding_box(breadcrumb_network_path) else {
|
if let Some(selected_nodes_bbox) = network_interface.selected_nodes_bounding_box(breadcrumb_network_path) {
|
||||||
log::error!("Could not get selected_nodes_bounding_box when dragging");
|
let target_center = selected_nodes_bbox[0] + drag_start;
|
||||||
return false;
|
let offset = mouse_position_node_graph_space - target_center;
|
||||||
};
|
let graph_delta = IVec2::new((offset.x / 24.).round() as i32, (offset.y / 24.).round() as i32);
|
||||||
let target_center = selected_nodes_bbox[0] + drag_start.drag_start_offset;
|
if graph_delta != IVec2::ZERO {
|
||||||
let offset = mouse_position_node_graph_space - target_center;
|
responses.add(NodeGraphMessage::ShiftSelectedNodesByAmount { graph_delta, rubber_band: true });
|
||||||
let graph_delta = IVec2::new((offset.x / 24.).round() as i32, (offset.y / 24.).round() as i32);
|
};
|
||||||
if graph_delta != IVec2::ZERO {
|
graph_delta != IVec2::ZERO
|
||||||
responses.add(NodeGraphMessage::ShiftSelectedNodesByAmount { graph_delta, rubber_band: true });
|
} else {
|
||||||
};
|
false
|
||||||
graph_delta != IVec2::ZERO
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,23 +110,6 @@ pub struct FrontendNodeType {
|
|||||||
pub input_types: Vec<String>,
|
pub input_types: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If dragging the selected nodes, this stores the coordinate of the click relative to the top left selected node.
|
|
||||||
/// Once the nodes have been dragged, it is toggled to the Yes variant.
|
|
||||||
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize, specta::Type)]
|
|
||||||
pub struct DragStart {
|
|
||||||
pub drag_start_offset: DVec2,
|
|
||||||
pub dragged: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DragStart {
|
|
||||||
pub fn new(drag_start: DVec2) -> Self {
|
|
||||||
DragStart {
|
|
||||||
drag_start_offset: drag_start,
|
|
||||||
dragged: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize, specta::Type)]
|
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||||
pub struct Transform {
|
pub struct Transform {
|
||||||
pub scale: f64,
|
pub scale: f64,
|
||||||
|
|||||||
@@ -3011,10 +3011,13 @@ impl NodeNetworkInterface {
|
|||||||
log::error!("Could not get selected nodes in selected_nodes_bounding_box_viewport");
|
log::error!("Could not get selected nodes in selected_nodes_bounding_box_viewport");
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
selected_nodes
|
let nodes = selected_nodes.selected_nodes().cloned().collect::<Vec<_>>();
|
||||||
.selected_nodes()
|
|
||||||
.cloned()
|
self.nodes_bounding_box(&nodes, network_path)
|
||||||
.collect::<Vec<_>>()
|
}
|
||||||
|
|
||||||
|
pub fn nodes_bounding_box(&mut self, nodes: &Vec<NodeId>, network_path: &[NodeId]) -> Option<[DVec2; 2]> {
|
||||||
|
nodes
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|node_id| {
|
.filter_map(|node_id| {
|
||||||
self.node_click_targets(node_id, network_path)
|
self.node_click_targets(node_id, network_path)
|
||||||
|
|||||||
Reference in New Issue
Block a user