def draw_path(self, start_port, end_port, cursor_pos=None): """ Draws the path between ports. Args: start_port (PortItem): port used to draw the starting point. end_port (PortItem): port used to draw the end point. cursor_pos (QtCore.QPointF): cursor position if specified this will be the draw end point. """ if not start_port: return offset = (start_port.boundingRect().width() / 2) pos1 = start_port.scenePos() pos1.setX(pos1.x() + offset) pos1.setY(pos1.y() + offset) if cursor_pos: pos2 = cursor_pos elif end_port: offset = start_port.boundingRect().width() / 2 pos2 = end_port.scenePos() pos2.setX(pos2.x() + offset) pos2.setY(pos2.y() + offset) else: return line = QtCore.QLineF(pos1, pos2) path = QtGui.QPainterPath() path.moveTo(line.x1(), line.y1()) if self.viewer_pipe_layout() == PIPE_LAYOUT_STRAIGHT: path.lineTo(pos2) self.setPath(path) return ctr_offset_x1, ctr_offset_x2 = pos1.x(), pos2.x() tangent = ctr_offset_x1 - ctr_offset_x2 tangent = (tangent * -1) if tangent < 0 else tangent max_width = start_port.node.boundingRect().width() / 2 tangent = max_width if tangent > max_width else tangent if start_port.port_type == IN_PORT: ctr_offset_x1 -= tangent ctr_offset_x2 += tangent else: ctr_offset_x1 += tangent ctr_offset_x2 -= tangent ctr_point1 = QtCore.QPointF(ctr_offset_x1, pos1.y()) ctr_point2 = QtCore.QPointF(ctr_offset_x2, pos2.y()) path.cubicTo(ctr_point1, ctr_point2, pos2) self.setPath(path)
def draw_triangle_port(painter, rect, info): """ Custom paint function for drawing a Triangle shaped port. Args: painter (QtGui.QPainter): painter object. rect (QtCore.QRectF): port rect used to describe parameters needed to draw. info (dict): information describing the ports current state. { 'port_type': 'in', 'color': (0, 0, 0), 'border_color': (255, 255, 255), 'multi_connection': False, 'connected': False, 'hovered': False, } """ painter.save() size = int(rect.height() / 2) triangle = QtGui.QPolygonF() triangle.append(QtCore.QPointF(-size, size)) triangle.append(QtCore.QPointF(0.0, -size)) triangle.append(QtCore.QPointF(size, size)) transform = QtGui.QTransform() transform.translate(rect.center().x(), rect.center().y()) port_poly = transform.map(triangle) # mouse over port color. if info['hovered']: color = QtGui.QColor(14, 45, 59) border_color = QtGui.QColor(136, 255, 35) # port connected color. elif info['connected']: color = QtGui.QColor(195, 60, 60) border_color = QtGui.QColor(200, 130, 70) # default port color else: color = QtGui.QColor(*info['color']) border_color = QtGui.QColor(*info['border_color']) pen = QtGui.QPen(border_color, 1.8) pen.setJoinStyle(QtCore.Qt.MiterJoin) painter.setPen(pen) painter.setBrush(color) painter.drawPolygon(port_poly) painter.restore()
def __init__(self, input_port=None, output_port=None): super(Pipe, self).__init__() self.setZValue(Z_VAL_PIPE) self.setAcceptHoverEvents(True) self._color = PIPE_DEFAULT_COLOR self._style = PIPE_STYLE_DEFAULT self._active = False self._highlight = False self._input_port = input_port self._output_port = output_port size = 6.0 self._arrow = QtGui.QPolygonF() self._arrow.append(QtCore.QPointF(-size, size)) self._arrow.append(QtCore.QPointF(0.0, -size * 1.5)) self._arrow.append(QtCore.QPointF(size, size))
def mouseReleaseEvent(self, event): if event.button() == QtCore.Qt.LeftButton: self.LMB_state = False elif event.button() == QtCore.Qt.RightButton: self.RMB_state = False elif event.button() == QtCore.Qt.MiddleButton: self.MMB_state = False # hide pipe slicer. if self._pipe_slicer.isVisible(): self._on_pipes_sliced(self._pipe_slicer.path()) p = QtCore.QPointF(0.0, 0.0) self._pipe_slicer.draw_path(p, p) self._pipe_slicer.setVisible(False) # hide selection marquee if self._rubber_band.isVisible(): rect = self._rubber_band.rect() map_rect = self.mapToScene(rect).boundingRect() self._rubber_band.hide() self.scene().update(map_rect) # find position changed nodes and emit signal. moved_nodes = { n: xy_pos for n, xy_pos in self._node_positions.items() if n.xy_pos != xy_pos } if moved_nodes: self.moved_nodes.emit(moved_nodes) # reset recorded positions. self._node_positions = {} super(NodeViewer, self).mouseReleaseEvent(event)
def __init__(self, input_port=None, output_port=None): super(Pipe, self).__init__() self.setZValue(Z_VAL_PIPE) self.setAcceptHoverEvents(True) self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable) self._color = PIPE_DEFAULT_COLOR self._style = PIPE_STYLE_DEFAULT self._active = False self._highlight = False self._input_port = input_port self._output_port = output_port size = 6.0 self._arrow = QtGui.QPolygonF() self._arrow.append(QtCore.QPointF(-size, size)) self._arrow.append(QtCore.QPointF(0.0, -size * 1.5)) self._arrow.append(QtCore.QPointF(size, size)) self.setCacheMode(ITEM_CACHE_MODE)
def itemChange(self, change, value): if change == self.ItemPositionChange: mx, my = self.controller.minimum_size x = mx if value.x() < mx else value.x() y = my if value.y() < my else value.y() value = QtCore.QPointF(x, y) self.controller.on_sizer_pos_changed(value) return value return super().itemChange(change, value)
def itemChange(self, change, value): if change == self.ItemPositionChange: item = self.parentItem() mx, my = item.minimum_size x = mx if value.x() < mx else value.x() y = my if value.y() < my else value.y() value = QtCore.QPointF(x, y) item.on_sizer_pos_changed(value) return value return super(BackdropSizer, self).itemChange(change, value)
def paint(self, painter, option, widget): """ Draws the slicer pipe. Args: painter (QtGui.QPainter): painter used for drawing the item. option (QtGui.QStyleOptionGraphicsItem): used to describe the parameters needed to draw. widget (QtWidgets.QWidget): not used. """ color = QtGui.QColor(*PIPE_SLICER_COLOR) p1 = self.path().pointAtPercent(0) p2 = self.path().pointAtPercent(1) size = 6.0 offset = size / 2 painter.save() painter.setRenderHint(painter.Antialiasing, True) font = painter.font() font.setPointSize(12) painter.setFont(font) text = 'slice' text_x = painter.fontMetrics().width(text) / 2 text_y = painter.fontMetrics().height() / 1.5 text_pos = QtCore.QPointF(p1.x() - text_x, p1.y() - text_y) text_color = QtGui.QColor(*PIPE_SLICER_COLOR) text_color.setAlpha(80) painter.setPen(QtGui.QPen(text_color, 1.5, QtCore.Qt.SolidLine)) painter.drawText(text_pos, text) painter.setPen(QtGui.QPen(color, 1.5, QtCore.Qt.DashLine)) painter.drawPath(self.path()) painter.setPen(QtGui.QPen(color, 1.5, QtCore.Qt.SolidLine)) painter.setBrush(color) rect = QtCore.QRectF(p1.x() - offset, p1.y() - offset, size, size) painter.drawEllipse(rect) rect = QtCore.QRectF(p2.x() - offset, p2.y() - offset, size, size) painter.drawEllipse(rect) painter.restore()
def mouseReleaseEvent(self, event): if event.button() == QtCore.Qt.LeftButton: self.LMB_state = False elif event.button() == QtCore.Qt.RightButton: self.RMB_state = False elif event.button() == QtCore.Qt.MiddleButton: self.MMB_state = False # hide pipe slicer. if self._SLICER_PIPE.isVisible(): self._on_pipes_sliced(self._SLICER_PIPE.path()) p = QtCore.QPointF(0.0, 0.0) self._SLICER_PIPE.draw_path(p, p) self._SLICER_PIPE.setVisible(False) # hide selection marquee if self._rubber_band.isVisible(): rect = self._rubber_band.rect() map_rect = self.mapToScene(rect).boundingRect() self._rubber_band.hide() self.scene().update(map_rect) # find position changed nodes and emit signal. moved_nodes = { n: xy_pos for n, xy_pos in self._node_positions.items() if n.xy_pos != xy_pos } # only emit of node is not colliding with a pipe. if moved_nodes and not self.COLLIDING_state: self.moved_nodes.emit(moved_nodes) # reset recorded positions. self._node_positions = {} # emit signal if selected node collides with pipe. # Note: if collide state is true then only 1 node is selected. if self.COLLIDING_state: nodes, pipes = self.selected_items() if nodes and pipes: self.insert_node.emit(pipes[0], nodes[0].id, moved_nodes) super(NodeViewer, self).mouseReleaseEvent(event)
def reset_path(self): path = QtGui.QPainterPath(QtCore.QPointF(0.0, 0.0)) self.setPath(path)
def set_size(self, size=5.0): triangle = QtGui.QPolygonF() triangle.append(QtCore.QPointF(-size, size)) triangle.append(QtCore.QPointF(0.0, -size * 2)) triangle.append(QtCore.QPointF(size, size)) self.setPolygon(triangle)