Source code for node_editor.node_edge_intersect

# -*- coding: utf-8 -*-
"""
A module containing the intersecting nodes functionality. If a node gets dragged and dropped on an existing edge
it will intersect that edge.
"""
from qtpy.QtWidgets import QGraphicsView
from qtpy.QtCore import QRectF
from node_editor.node_edge import Edge


[docs]class EdgeIntersect: def __init__(self, grView: "QGraphicsView"): self.grScene = grView.grScene self.grView = grView self.draggedNode = None self.hoveredList = []
[docs] def enterState(self, node: "Node"): """ Initialize when we enter the state :param node: :class:`~node_editor.node_node.Node` which we started to drag :type node: :class:`~nodeeditor.node_node.Node` """ self.hoveredList = [] self.draggedNode = node
[docs] def leaveState(self, scene_pos_x: float, scene_pos_y: float): """ Deinit when we leave this state :param scene_pos_x: scene position x :type scene_pos_x: `float` :param scene_pos_y: scene position y :type scene_pos_y: `float` """ self.dropNode(self.draggedNode, scene_pos_x, scene_pos_y) self.draggedNode = None self.hoveredList = []
[docs] def dropNode(self, node: "Node", scene_pos_x: float, scene_pos_y: float): """ Code handling the dropping of a node on an existing edge. :param scene_pos_x: scene position x :type scene_pos_x: `float` :param scene_pos_y: scene position y :type scene_pos_y: `float` """ node_box = self.hotZoneRect(node) # check if the node is dropped on an existing edge edge = self.intersect(node_box) if edge is None: return if self.isConnected(node): return # determine the order of start and end if edge.start_socket.is_output: socket_start = edge.start_socket socket_end = edge.end_socket else: socket_start = edge.end_socket socket_end = edge.start_socket # The new edges will have the same edge_type as the intersected edge edge_type = edge.edge_type edge.remove() self.grView.grScene.scene.history.storeHistory('Delete existing edge', setModified=True) new_node_socket_in = node.inputs[0] Edge(self.grScene.scene, socket_start, new_node_socket_in, edge_type=edge_type) new_node_socket_out = node.outputs[0] Edge(self.grScene.scene, new_node_socket_out, socket_end, edge_type=edge_type) self.grView.grScene.scene.history.storeHistory('Created new edges by dropping node', setModified=True)
[docs] def hotZoneRect(self, node: 'Node') -> 'QRectF': """ Returns A QRectF of creating a box around a node :param node: :class:`~node_editor.node_node.Node` for which we want to get `QRectF` describing its position and area :type node: :class:`~nodeeditor.node_node.Node` :return: `QRectF` describing node's position and area :rtype: `QRectF` """ nodePos = node.grNode.scenePos() x = nodePos.x() y = nodePos.y() w = node.grNode.width h = node.grNode.height return QRectF(x, y, w, h)
[docs] def update(self, scene_pos_x: float, scene_pos_y: float): """ Updating during mouse move when grView is in this state :param scene_pos_x: scene position x :type scene_pos_x: `float` :param scene_pos_y: scene position y :type scene_pos_y: `float` """ rect = self.hotZoneRect(self.draggedNode) grItems = self.grScene.items(rect) for grEdge in self.hoveredList: grEdge.hovered = False self.hoveredList = [] for grItem in grItems: if hasattr(grItem, 'edge') and not self.draggedNode.hasConnectedEdge(grItem.edge): self.hoveredList.append(grItem) grItem.hovered = True
[docs] def intersect(self, node_box: 'QRectF') -> 'Edge': """ Checking for intersection of a rectangle (usually a `Node`) with edges in the scene :param node_box: `QRectF` for which we want find intersecting `Edges` :type node_box: `QRectF` :return: :class:`~node_editor.node_edge.Edge` or `None` if the node is being cut by an `Edge` :rtype: :class:`~nodeeditor.node_edge.Edge` """ # returns the first edge that intersects with the dropped node, ignores the rest grItems = self.grScene.items(node_box) for grItem in grItems: if hasattr(grItem, 'edge') and not self.draggedNode.hasConnectedEdge(grItem.edge): return grItem.edge return None
[docs] def isConnected(self, node: 'Node'): """ Return ``True`` if node got any connections :param node: :class:`~node_editor.node_node.Node` which connections to check :type node: :class:`~nodeeditor.node_node.Node` :return: """ # Nodes with only inputs or outputs are excluded if node.inputs == [] or node.outputs == []: return True # Check if the node has edges connected return node.getInput() or node.getOutputs()